├── .gitattributes ├── .gitmodules ├── LICENSE.md ├── README.md └── src ├── Defs.h ├── hook_emus.cpp ├── hook_emus.h ├── hooks.cpp ├── hooks.h └── main.cpp /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/ColdHook/src"] 2 | path = src/ColdHook/src 3 | url = git://github.com/Rat431/ColdHook.git 4 | [submodule "src/ColdHook"] 5 | path = src/ColdHook 6 | url = git://github.com/Rat431/ColdHook.git 7 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Rat431 inc 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ColdHide 2 | 3 | ColdHide is a mini and simple open source user mode anti-anti debug library x86/x64 for Windows. 4 | To inject this library try using [ColdMDLoader](https://github.com/Rat431/ColdMDLoader). 5 | 6 | ## Hooks 7 | - ***PEB hooking*** 8 | - ***NtQueryInformationProcess*** 9 | - ***NtClose*** 10 | - ***Drx hooking*** 11 | - ***NtQueryObject*** 12 | - ***NtQuerySystemInformation*** 13 | - ***NtSetInformationThread*** 14 | - ***NtSetInformationProcess*** 15 | - ***NtCreateThreadEx*** 16 | - ***NtYieldExecution*** 17 | - ***NtSetDebugFilterState*** 18 | - ***Process32FirstW*** 19 | - ***Process32NextW*** 20 | - ***GetTickCount*** 21 | - ***GetTickCount64*** 22 | - ***Anti-Anti attach*** 23 | 24 | 25 | ## Build requirements 26 | - MSVC 2019 or higher build tools are required to compile this project. 27 | 28 | ## Credits 29 | - [Zydis (Disassembler engine)](https://github.com/zyantific/zydis) 30 | - [ColdHook (Hooking library)](https://github.com/Rat431/ColdHook) 31 | -------------------------------------------------------------------------------- /src/Defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2020 Rat431 (https://github.com/Rat431). 3 | This software is under the MIT license, for more informations check the LICENSE file. 4 | */ 5 | 6 | #pragma once 7 | #include 8 | #include 9 | 10 | typedef _Return_type_success_( return >= 0 ) LONG NTSTATUS; 11 | 12 | typedef struct _UNICODE_STRING 13 | { 14 | USHORT Length; 15 | USHORT MaximumLength; 16 | PWSTR Buffer; 17 | } UNICODE_STRING, * PUNICODE_STRING; 18 | typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION 19 | { 20 | BOOLEAN DebuggerEnabled; 21 | BOOLEAN DebuggerNotPresent; 22 | } SYSTEM_KERNEL_DEBUGGER_INFORMATION, * PSYSTEM_KERNEL_DEBUGGER_INFORMATION; 23 | 24 | typedef struct _OBJECT_TYPE_INFORMATION 25 | { 26 | UNICODE_STRING TypeName; 27 | ULONG TotalNumberOfObjects; 28 | ULONG TotalNumberOfHandles; 29 | } OBJECT_TYPE_INFORMATION, * POBJECT_TYPE_INFORMATION; 30 | 31 | typedef struct _OBJECT_ALL_TYPES_INFORMATION 32 | { 33 | ULONG NumberOfObjectTypes; 34 | OBJECT_TYPE_INFORMATION ObjectTypeInformation[1]; 35 | } OBJECT_ALL_TYPES_INFORMATION, * POBJECT_ALL_TYPES_INFORMATION; 36 | 37 | typedef struct _PS_ATTRIBUTE 38 | { 39 | ULONG_PTR Attribute; 40 | SIZE_T Size; 41 | union 42 | { 43 | ULONG_PTR Value; 44 | PVOID ValuePtr; 45 | }; 46 | PSIZE_T ReturnLength; 47 | } PS_ATTRIBUTE, * PPS_ATTRIBUTE; 48 | typedef LONG KPRIORITY; 49 | typedef struct _PROCESS_BASIC_INFORMATION 50 | { 51 | NTSTATUS ExitStatus; 52 | void * PebBaseAddress; 53 | ULONG_PTR AffinityMask; 54 | KPRIORITY BasePriority; 55 | ULONG_PTR UniqueProcessId; 56 | ULONG_PTR InheritedFromUniqueProcessId; 57 | } PROCESS_BASIC_INFORMATION, * PPROCESS_BASIC_INFORMATION; 58 | 59 | typedef enum _PROCESSINFOCLASS 60 | { 61 | ProcessBasicInformation = 0, 62 | ProcessQuotaLimits = 1, 63 | ProcessIoCounters = 2, 64 | ProcessVmCounters = 3, 65 | ProcessTimes = 4, 66 | ProcessBasePriority = 5, 67 | ProcessRaisePriority = 6, 68 | ProcessDebugPort = 7, 69 | ProcessExceptionPort = 8, 70 | ProcessAccessToken = 9, 71 | ProcessLdtInformation = 10, 72 | ProcessLdtSize = 11, 73 | ProcessDefaultHardErrorMode = 12, 74 | ProcessIoPortHandlers = 13, // Note: this is kernel mode only 75 | ProcessPooledUsageAndLimits = 14, 76 | ProcessWorkingSetWatch = 15, 77 | ProcessUserModeIOPL = 16, 78 | ProcessEnableAlignmentFaultFixup = 17, 79 | ProcessPriorityClass = 18, 80 | ProcessWx86Information = 19, 81 | ProcessHandleCount = 20, 82 | ProcessAffinityMask = 21, 83 | ProcessPriorityBoost = 22, 84 | ProcessDeviceMap = 23, 85 | ProcessSessionInformation = 24, 86 | ProcessForegroundInformation = 25, 87 | ProcessWow64Information = 26, 88 | ProcessImageFileName = 27, 89 | ProcessLUIDDeviceMapsEnabled = 28, 90 | ProcessBreakOnTermination = 29, 91 | ProcessDebugObjectHandle = 30, 92 | ProcessDebugFlags = 31, 93 | ProcessHandleTracing = 32, 94 | ProcessIoPriority = 33, 95 | ProcessExecuteFlags = 34, 96 | ProcessTlsInformation = 35, 97 | ProcessCookie = 36, 98 | ProcessImageInformation = 37, 99 | ProcessCycleTime = 38, 100 | ProcessPagePriority = 39, 101 | ProcessInstrumentationCallback = 40, 102 | ProcessThreadStackAllocation = 41, 103 | ProcessWorkingSetWatchEx = 42, 104 | ProcessImageFileNameWin32 = 43, 105 | ProcessImageFileMapping = 44, 106 | ProcessAffinityUpdateMode = 45, 107 | ProcessMemoryAllocationMode = 46, 108 | ProcessGroupInformation = 47, 109 | ProcessTokenVirtualizationEnabled = 48, 110 | ProcessOwnerInformation = 49, 111 | ProcessWindowInformation = 50, 112 | ProcessHandleInformation = 51, 113 | ProcessMitigationPolicy = 52, 114 | ProcessDynamicFunctionTableInformation = 53, 115 | ProcessHandleCheckingMode = 54, 116 | ProcessKeepAliveCount = 55, 117 | ProcessRevokeFileHandles = 56, 118 | ProcessWorkingSetControl = 57, 119 | ProcessHandleTable = 58, 120 | ProcessCheckStackExtentsMode = 59, 121 | ProcessCommandLineInformation = 60, 122 | ProcessProtectionInformation = 61, 123 | ProcessMemoryExhaustion = 62, 124 | ProcessFaultInformation = 63, 125 | ProcessTelemetryIdInformation = 64, 126 | ProcessCommitReleaseInformation = 65, 127 | ProcessReserved1Information = 66, 128 | ProcessReserved2Information = 67, 129 | ProcessSubsystemProcess = 68, 130 | ProcessInPrivate = 70, 131 | ProcessRaiseUMExceptionOnInvalidHandleClose = 71, 132 | ProcessSubsystemInformation = 75, 133 | ProcessWin32kSyscallFilterInformation = 79, 134 | ProcessEnergyTrackingState = 82, 135 | MaxProcessInfoClass // MaxProcessInfoClass should always be the last enum 136 | } PROCESSINFOCLASS; 137 | 138 | typedef struct _PS_ATTRIBUTE_LIST 139 | { 140 | SIZE_T TotalLength; 141 | PS_ATTRIBUTE Attributes[1]; 142 | } PS_ATTRIBUTE_LIST, * PPS_ATTRIBUTE_LIST; 143 | 144 | typedef enum _THREADINFOCLASS 145 | { 146 | ThreadBasicInformation = 0, 147 | ThreadTimes = 1, 148 | ThreadPriority = 2, 149 | ThreadBasePriority = 3, 150 | ThreadAffinityMask = 4, 151 | ThreadImpersonationToken = 5, 152 | ThreadDescriptorTableEntry = 6, 153 | ThreadEnableAlignmentFaultFixup = 7, 154 | ThreadEventPair_Reusable = 8, 155 | ThreadQuerySetWin32StartAddress = 9, 156 | ThreadZeroTlsCell = 10, 157 | ThreadPerformanceCount = 11, 158 | ThreadAmILastThread = 12, 159 | ThreadIdealProcessor = 13, 160 | ThreadPriorityBoost = 14, 161 | ThreadSetTlsArrayAddress = 15, // Obsolete 162 | ThreadIsIoPending = 16, 163 | ThreadHideFromDebugger = 17, 164 | ThreadBreakOnTermination = 18, 165 | ThreadSwitchLegacyState = 19, 166 | ThreadIsTerminated = 20, 167 | ThreadLastSystemCall = 21, 168 | ThreadIoPriority = 22, 169 | ThreadCycleTime = 23, 170 | ThreadPagePriority = 24, 171 | ThreadActualBasePriority = 25, 172 | ThreadTebInformation = 26, 173 | ThreadCSwitchMon = 27, // Obsolete 174 | ThreadCSwitchPmu = 28, 175 | ThreadWow64Context = 29, 176 | ThreadGroupInformation = 30, 177 | ThreadUmsInformation = 31, // UMS 178 | ThreadCounterProfiling = 32, 179 | ThreadIdealProcessorEx = 33, 180 | ThreadCpuAccountingInformation = 34, 181 | ThreadSuspendCount = 35, 182 | ThreadActualGroupAffinity = 41, 183 | ThreadDynamicCodePolicyInfo = 42, 184 | ThreadSubsystemInformation = 45, 185 | 186 | MaxThreadInfoClass = 51, 187 | } THREADINFOCLASS; 188 | 189 | typedef enum _SYSTEM_INFORMATION_CLASS 190 | { 191 | SystemBasicInformation, 192 | SystemProcessorInformation, 193 | SystemPerformanceInformation, 194 | SystemTimeOfDayInformation, 195 | SystemPathInformation, 196 | SystemProcessInformation, 197 | SystemCallCountInformation, 198 | SystemDeviceInformation, 199 | SystemProcessorPerformanceInformation, 200 | SystemFlagsInformation, 201 | SystemCallTimeInformation, 202 | SystemModuleInformation, 203 | SystemLocksInformation, 204 | SystemStackTraceInformation, 205 | SystemPagedPoolInformation, 206 | SystemNonPagedPoolInformation, 207 | SystemHandleInformation, 208 | SystemObjectInformation, 209 | SystemPageFileInformation, 210 | SystemVdmInstemulInformation, 211 | SystemVdmBopInformation, 212 | SystemFileCacheInformation, 213 | SystemPoolTagInformation, 214 | SystemInterruptInformation, 215 | SystemDpcBehaviorInformation, 216 | SystemFullMemoryInformation, 217 | SystemLoadGdiDriverInformation, 218 | SystemUnloadGdiDriverInformation, 219 | SystemTimeAdjustmentInformation, 220 | SystemSummaryMemoryInformation, 221 | SystemNextEventIdInformation, 222 | SystemEventIdsInformation, 223 | SystemCrashDumpInformation, 224 | SystemExceptionInformation, 225 | SystemCrashDumpStateInformation, 226 | SystemKernelDebuggerInformation, 227 | SystemContextSwitchInformation, 228 | SystemRegistryQuotaInformation, 229 | SystemExtendServiceTableInformation, 230 | SystemPrioritySeperation, 231 | SystemPlugPlayBusInformation, 232 | SystemDockInformation, 233 | /* SystemPowerInformation,*/ 234 | SystemProcessorSpeedInformation = 43, 235 | SystemCurrentTimeZoneInformation, 236 | SystemLookasideInformation 237 | } SYSTEM_INFORMATION_CLASS, * PSYSTEM_INFORMATION_CLASS; 238 | 239 | typedef enum _OBJECT_INFORMATION_CLASS 240 | { 241 | ObjectBasicInformation = 0, 242 | ObjectNameInformation = 1, 243 | ObjectTypeInformation = 2, 244 | ObjectAllTypesInformation = 3, 245 | ObjectHandleInformation = 4 246 | } OBJECT_INFORMATION_CLASS; 247 | 248 | typedef struct _OBJECT_ATTRIBUTES 249 | { 250 | ULONG Length; 251 | HANDLE RootDirectory; 252 | PUNICODE_STRING ObjectName; 253 | ULONG Attributes; 254 | PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR 255 | PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE 256 | } OBJECT_ATTRIBUTES; 257 | typedef OBJECT_ATTRIBUTES * POBJECT_ATTRIBUTES; 258 | 259 | // Define some offsets 260 | #define PEB_BeingDebuggedOffset 0x2 261 | #ifdef _WIN64 262 | #define NAKED 263 | #define GetPebFunction() __readgsqword(0x60) 264 | #define MAX_ADDRESS_SIZE 0x8 265 | #define PEB_Offset 0x60 266 | #define PEB_NtGlobalFlagOffset 0xBC 267 | #define HeapPEB_Offset 0x30 268 | #define HeapFlagsBaseWinHigher 0x70 269 | #define HeapForceFlagsBaseWinHigher 0x74 270 | #define HeapFlagsBaseWinLower 0x14 271 | #define HeapForceFlagsBaseWinLower 0x18 272 | #else 273 | #define NAKED _declspec(naked) 274 | #define GetPebFunction() __readfsdword(0x30) 275 | #define MAX_ADDRESS_SIZE 0x4 276 | #define PEB_Offset 0x30 277 | #define PEB_NtGlobalFlagOffset 0x68 278 | #define HeapPEB_Offset 0x18 279 | #define HeapFlagsBaseWinHigher 0x40 280 | #define HeapForceFlagsBaseWinHigher 0x44 281 | #define HeapFlagsBaseWinLower 0xC 282 | #define HeapForceFlagsBaseWinLower 0x10 283 | #endif 284 | 285 | // Thread flags 286 | #define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001 287 | #define THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH 0x00000002 288 | #define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004 289 | #define THREAD_CREATE_FLAGS_HAS_SECURITY_DESCRIPTOR 0x00000010 290 | #define THREAD_CREATE_FLAGS_ACCESS_CHECK_IN_TARGET 0x00000020 291 | #define THREAD_CREATE_FLAGS_INITIAL_THREAD 0x00000080 292 | 293 | #define DEBUG_OBJECT L"DebugObject" 294 | 295 | #define STATUS_SUCCESS ((NTSTATUS)0x00000000L) 296 | #define STATUS_NO_YIELD_PERFORMED ((NTSTATUS)0x40000024L) 297 | #define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L) 298 | #define STATUS_PORT_NOT_SET ((NTSTATUS)0xC0000353L) 299 | #define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) 300 | #define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0) -------------------------------------------------------------------------------- /src/hook_emus.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2020 Rat431 (https://github.com/Rat431). 3 | This software is under the MIT license, for more informations check the LICENSE file. 4 | */ 5 | 6 | #include "hook_emus.h" 7 | #include "hooks.h" 8 | 9 | // Vars 10 | static ULONG BreakT = NULL; 11 | static bool IsEnabledTracing = false; 12 | static DWORD_PTR DebugFlags = 1; 13 | 14 | static CONTEXT FakeContext[1000] = { 0 }; 15 | static CONTEXT BeckupHardwareBP[1000] = { 0 }; 16 | static bool KIUEDFlag[1000] = { 0 }; 17 | 18 | // Some common debugger process names. 19 | const wchar_t * Debuggers[15] = 20 | { 21 | L"ollydbg.exe", 22 | L"windbg.exe", 23 | L"devenv.exe", 24 | L"ImmunityDebugger.exe", 25 | L"idaq.exe", 26 | L"idaq64.exe", 27 | L"ida.exe", 28 | L"ida64.exe", 29 | L"x32dbg.exe", 30 | L"x64dbg.exe", 31 | L"ProcessHacker.exe", 32 | L"cheatengine-x86_64.exe", 33 | L"cheatengine-i386.exe", 34 | L"binaryninja.exe", 35 | L"DbgX.Shell.exe" // WinDbg preview (UWP) 36 | }; 37 | const wchar_t * DebuggersPatch[15] = 38 | { 39 | L"proc1.exe", 40 | L"proc2.exe", 41 | L"proc3.exe", 42 | L"proc4.exe", 43 | L"proc5.exe", 44 | L"proc6.exe", 45 | L"proc7.exe", 46 | L"proc8.exe", 47 | L"proc9.exe", 48 | L"proc10.exe", 49 | L"proc11.exe", 50 | L"proc12.exe", 51 | L"proc13.exe", 52 | L"proc14.exe", 53 | L"proc15.exe" 54 | }; 55 | 56 | namespace Hook_emu 57 | { 58 | static bool Cleaned = false; 59 | void InitHookFunctionsVars() 60 | { 61 | if (!Cleaned) 62 | { 63 | for (size_t i = 0; i < 1000; i++) 64 | { 65 | memset( &FakeContext[i], 0, sizeof( CONTEXT ) ); 66 | memset( &BeckupHardwareBP[i], 0, sizeof( CONTEXT ) ); 67 | } 68 | Cleaned = true; 69 | } 70 | } 71 | 72 | // proxied functions 73 | NTSTATUS NTAPI __NtQueryInformationProcess( HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength ) 74 | { 75 | NTSTATUS Return = STATUS_SUCCESS; 76 | 77 | // Call the restored function 78 | __NtQueryInformationProcess__ ___NtQueryInformationProcess__ = (__NtQueryInformationProcess__) Hooks_Informastion::Nt_QueryProcessP; 79 | Return = ___NtQueryInformationProcess__( ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, ReturnLength ); 80 | 81 | if (NT_SUCCESS( Return )) 82 | { 83 | switch (ProcessInformationClass) 84 | { 85 | // Debug port 86 | case PROCESSINFOCLASS::ProcessDebugPort: 87 | { 88 | // Check if is the correct size 89 | if (ProcessInformationLength >= sizeof( DWORD_PTR )) 90 | { 91 | *(DWORD_PTR *) ProcessInformation = 0; 92 | } 93 | else 94 | Return = STATUS_INFO_LENGTH_MISMATCH; 95 | 96 | break; 97 | } 98 | 99 | // Debug object 100 | case PROCESSINFOCLASS::ProcessDebugObjectHandle: 101 | { 102 | // Check if is the correct size 103 | if (ProcessInformationLength >= sizeof( DWORD_PTR )) 104 | { 105 | *(DWORD_PTR *) ProcessInformation = 0; 106 | Return = STATUS_PORT_NOT_SET; 107 | } 108 | else 109 | Return = STATUS_INFO_LENGTH_MISMATCH; 110 | 111 | break; 112 | } 113 | 114 | // Debug flags 115 | case PROCESSINFOCLASS::ProcessDebugFlags: 116 | { 117 | // Check if is the correct size 118 | if (ProcessInformationLength >= sizeof( DWORD_PTR )) 119 | { 120 | *(DWORD_PTR *) ProcessInformation = DebugFlags; 121 | } 122 | else 123 | Return = STATUS_INFO_LENGTH_MISMATCH; 124 | 125 | break; 126 | } 127 | 128 | // Basic information 129 | case PROCESSINFOCLASS::ProcessBasicInformation: 130 | { 131 | // Patch Parent PID 132 | PROCESS_BASIC_INFORMATION * pb = (PROCESS_BASIC_INFORMATION *) ProcessInformation; 133 | pb->InheritedFromUniqueProcessId = Hooks_Informastion::FPPID; 134 | 135 | break; 136 | } 137 | 138 | // ProcessBreakOnTermination 139 | case PROCESSINFOCLASS::ProcessBreakOnTermination: 140 | { 141 | // Check if is the correct size 142 | if (ProcessInformationLength >= sizeof( ULONG )) 143 | { 144 | *(ULONG *) ProcessInformation = BreakT; 145 | } 146 | else 147 | Return = STATUS_INFO_LENGTH_MISMATCH; 148 | 149 | break; 150 | } 151 | 152 | // Crash dump info 153 | case SYSTEM_INFORMATION_CLASS::SystemCrashDumpInformation: 154 | { 155 | if (IsEnabledTracing) 156 | Return = STATUS_SUCCESS; 157 | else 158 | Return = STATUS_INVALID_PARAMETER; 159 | 160 | break; 161 | } 162 | } 163 | } 164 | return Return; 165 | } 166 | NTSTATUS NTAPI __NtSetInformationThread( HANDLE ThreadHandle, THREADINFOCLASS ThreadInformationClass, PVOID ThreadInformation, ULONG ThreadInformationLength ) 167 | { 168 | // Ignore the call with ThreadHideFromDebugger flag 169 | __NtSetInformationThread__ ___NtSetInformationThread__ = (__NtSetInformationThread__) Hooks_Informastion::Nt_SetThreadInformationP; 170 | if (ThreadInformationClass == ThreadHideFromDebugger && ThreadInformation <= NULL && ThreadInformationLength <= NULL) 171 | { 172 | return STATUS_SUCCESS; 173 | } 174 | return ___NtSetInformationThread__( ThreadHandle, ThreadInformationClass, ThreadInformation, ThreadInformationLength ); 175 | } 176 | NTSTATUS NTAPI __NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength ) 177 | { 178 | NTSTATUS Return = STATUS_SUCCESS; 179 | 180 | __NtQuerySystemInformation__ ___NtQuerySystemInformation__ = (__NtQuerySystemInformation__) Hooks_Informastion::Nt_QuerySystemP; 181 | Return = ___NtQuerySystemInformation__( SystemInformationClass, SystemInformation, SystemInformationLength, ReturnLength ); 182 | 183 | if (NT_SUCCESS( Return )) 184 | { 185 | // Check if is requesting SystemKernelDebuggerInformation(0x23) flag 186 | if (SystemInformationClass == SystemKernelDebuggerInformation) 187 | { 188 | if (SystemInformationLength >= sizeof( _SYSTEM_KERNEL_DEBUGGER_INFORMATION )) 189 | { 190 | _SYSTEM_KERNEL_DEBUGGER_INFORMATION * skdi = (_SYSTEM_KERNEL_DEBUGGER_INFORMATION *) SystemInformation; 191 | skdi->DebuggerEnabled = false; 192 | skdi->DebuggerNotPresent = true; 193 | } 194 | else 195 | Return = STATUS_INVALID_PARAMETER; 196 | } 197 | } 198 | return Return; 199 | } 200 | NTSTATUS NTAPI __NtClose( HANDLE Handle ) 201 | { 202 | BYTE BUFF[2] = { 0 }; 203 | NTSTATUS Return = STATUS_SUCCESS; 204 | 205 | __NtClose__ ___NtClose__ = (__NtClose__) Hooks_Informastion::Nt_CloseP; 206 | __NtQueryObject__ ___NtQueryObject__ = (__NtQueryObject__) Hooks_Informastion::Nt_QueryObjectP; 207 | 208 | // Check if the handle is valid 209 | if ((Return = ___NtQueryObject__( Handle, ObjectHandleInformation, BUFF, 0x2, NULL )) != STATUS_INVALID_HANDLE) 210 | { 211 | Return = ___NtClose__( Handle ); 212 | } 213 | return Return; 214 | } 215 | NTSTATUS NTAPI __NtQueryObject( HANDLE Handle, OBJECT_INFORMATION_CLASS ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength ) 216 | { 217 | NTSTATUS Return = STATUS_SUCCESS; 218 | 219 | __NtQueryObject__ ___NtQueryObject__ = (__NtQueryObject__) Hooks_Informastion::Nt_QueryObjectP; 220 | Return = ___NtQueryObject__( Handle, ObjectInformationClass, ObjectInformation, ObjectInformationLength, ReturnLength ); 221 | 222 | if (NT_SUCCESS( Return )) 223 | { 224 | if (ObjectInformationClass == ObjectTypeInformation) 225 | { 226 | // Check if is the correct size 227 | if (ObjectInformationLength >= sizeof( OBJECT_TYPE_INFORMATION )) 228 | { 229 | POBJECT_TYPE_INFORMATION object = (POBJECT_TYPE_INFORMATION) ObjectInformation; 230 | if (object->TypeName.Buffer) 231 | { 232 | if (lstrcmp( object->TypeName.Buffer, DEBUG_OBJECT ) == 0) 233 | { 234 | // Debug object fake call 235 | if (object->TotalNumberOfObjects > 1) 236 | { 237 | object->TotalNumberOfObjects = 1; 238 | object->TotalNumberOfHandles = 1; 239 | } 240 | else 241 | { 242 | object->TotalNumberOfObjects = 0; 243 | object->TotalNumberOfHandles = 0; 244 | } 245 | } 246 | } 247 | } 248 | else 249 | Return = STATUS_INFO_LENGTH_MISMATCH; 250 | } 251 | else if (ObjectInformationClass == ObjectAllTypesInformation) 252 | { 253 | // Check if is the correct size 254 | if (ObjectInformationLength >= sizeof( OBJECT_ALL_TYPES_INFORMATION )) 255 | { 256 | POBJECT_ALL_TYPES_INFORMATION object = (POBJECT_ALL_TYPES_INFORMATION) ObjectInformation; 257 | unsigned char * pType = (unsigned char *) object->ObjectTypeInformation; 258 | 259 | // Loop untill we find DebugObject name and set to 0. 260 | for (unsigned int i = 0; i < object->NumberOfObjectTypes; i++) 261 | { 262 | POBJECT_TYPE_INFORMATION pCurType = (POBJECT_TYPE_INFORMATION) pType; 263 | if (pCurType->TypeName.Buffer) 264 | { 265 | if (lstrcmp( pCurType->TypeName.Buffer, DEBUG_OBJECT ) == 0) 266 | { 267 | // Debug object fake call. A target process can call NtCreateDebugObject to create a fake object 268 | // and detect an anti anti debug tool as it expect to return 1 object. 269 | if (pCurType->TotalNumberOfObjects > 1) 270 | { 271 | pCurType->TotalNumberOfObjects = 1; 272 | pCurType->TotalNumberOfHandles = 1; 273 | } 274 | else 275 | { 276 | pCurType->TotalNumberOfObjects = 0; 277 | pCurType->TotalNumberOfHandles = 0; 278 | } 279 | break; 280 | } 281 | } 282 | 283 | // Next structure... 284 | pType = (unsigned char *) ((ULONG_PTR) pCurType->TypeName.Buffer + pCurType->TypeName.MaximumLength); 285 | ULONG_PTR pTempAddr = ((ULONG_PTR) pType & (LONG_PTR) -sizeof( void * )); 286 | if (pTempAddr < (ULONG_PTR) pType) 287 | pTempAddr += sizeof( ULONG_PTR ); 288 | pType = (unsigned char *) pTempAddr; 289 | } 290 | } 291 | else 292 | Return = STATUS_INFO_LENGTH_MISMATCH; 293 | } 294 | } 295 | return Return; 296 | } 297 | 298 | // DRx functions 299 | NTSTATUS NTAPI __NtGetContextThread( HANDLE ThreadHandle, PCONTEXT pContext ) 300 | { 301 | NTSTATUS Return = STATUS_SUCCESS; 302 | DWORD Flags = 0; 303 | size_t CurrOffset = 0; 304 | 305 | __NtGetContextThread__ ___NtGetContextThread__ = (__NtGetContextThread__) Hooks_Informastion::Nt_NtGetContextThreadP; 306 | 307 | if (pContext) 308 | { 309 | if (pContext->ContextFlags & CONTEXT_DEBUG_REGISTERS) 310 | { 311 | CurrOffset = Hooks_Manager::GetOffsetByThreadID( GetThreadId( ThreadHandle ) ); 312 | 313 | // Clean the flag 314 | Flags = pContext->ContextFlags; 315 | pContext->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS; 316 | 317 | if (pContext->ContextFlags) 318 | { 319 | Return = ___NtGetContextThread__( ThreadHandle, pContext ); 320 | } 321 | 322 | // Now each Thread handle should have its own CONTEXT. 323 | pContext->Dr0 = FakeContext[CurrOffset].Dr0; 324 | pContext->Dr1 = FakeContext[CurrOffset].Dr1; 325 | pContext->Dr2 = FakeContext[CurrOffset].Dr2; 326 | pContext->Dr3 = FakeContext[CurrOffset].Dr3; 327 | pContext->Dr6 = FakeContext[CurrOffset].Dr6; 328 | pContext->Dr7 = FakeContext[CurrOffset].Dr7; 329 | 330 | // Once we got context infos without the CONTEXT_DEBUG_REGISTERS, we can restore the original flags to be safe. 331 | pContext->ContextFlags = Flags; 332 | } 333 | else 334 | Return = ___NtGetContextThread__( ThreadHandle, pContext ); 335 | } 336 | else 337 | Return = ___NtGetContextThread__( ThreadHandle, pContext ); 338 | return Return; 339 | } 340 | NTSTATUS NTAPI __NtSetContextThread( HANDLE ThreadHandle, PCONTEXT pContext ) 341 | { 342 | NTSTATUS Return = STATUS_SUCCESS; 343 | DWORD Flags = 0; 344 | __NtSetContextThread__ ___NtSetContextThread__ = (__NtSetContextThread__) Hooks_Informastion::Nt_NtSetContextThreadP; 345 | 346 | if (pContext) 347 | { 348 | if (pContext->ContextFlags & CONTEXT_DEBUG_REGISTERS) 349 | { 350 | if (Hooks_Config::FakeContextEmulation) 351 | { 352 | size_t CurrOffset = Hooks_Manager::GetOffsetByThreadID( GetThreadId( ThreadHandle ) ); 353 | 354 | // Now each Thread handle should have its own CONTEXT. 355 | FakeContext[CurrOffset].Dr0 = pContext->Dr0; 356 | FakeContext[CurrOffset].Dr1 = pContext->Dr1; 357 | FakeContext[CurrOffset].Dr2 = pContext->Dr2; 358 | FakeContext[CurrOffset].Dr3 = pContext->Dr3; 359 | FakeContext[CurrOffset].Dr6 = pContext->Dr6; 360 | FakeContext[CurrOffset].Dr7 = pContext->Dr7; 361 | } 362 | 363 | // Clean the flag 364 | Flags = pContext->ContextFlags; 365 | pContext->ContextFlags &= ~CONTEXT_DEBUG_REGISTERS; 366 | 367 | if (pContext->ContextFlags) 368 | { 369 | Return = ___NtSetContextThread__( ThreadHandle, pContext ); 370 | } 371 | 372 | // Once we got context infos without the CONTEXT_DEBUG_REGISTERS, we can restore the original flags to be safe. 373 | pContext->ContextFlags = Flags; 374 | } 375 | else 376 | Return = ___NtSetContextThread__( ThreadHandle, pContext ); 377 | } 378 | else 379 | Return = ___NtSetContextThread__( ThreadHandle, pContext ); 380 | return Return; 381 | } 382 | 383 | NTSTATUS NTAPI __NtContinue( PCONTEXT ThreadContext, BOOLEAN RaiseAlert ) 384 | { 385 | __NtContinue__ ___NtContinue__ = (__NtContinue__) Hooks_Informastion::Nt_ContinueP; 386 | 387 | if (ThreadContext) 388 | { 389 | size_t CurrOffset = Hooks_Manager::GetOffsetByThreadID( GetCurrentThreadId() ); 390 | 391 | // Now each Thread handle should have its own CONTEXT. 392 | if (KIUEDFlag[CurrOffset]) 393 | { 394 | ThreadContext->Dr0 = BeckupHardwareBP[CurrOffset].Dr0; 395 | ThreadContext->Dr1 = BeckupHardwareBP[CurrOffset].Dr1; 396 | ThreadContext->Dr2 = BeckupHardwareBP[CurrOffset].Dr2; 397 | ThreadContext->Dr3 = BeckupHardwareBP[CurrOffset].Dr3; 398 | ThreadContext->Dr6 = BeckupHardwareBP[CurrOffset].Dr6; 399 | ThreadContext->Dr7 = BeckupHardwareBP[CurrOffset].Dr7; 400 | 401 | KIUEDFlag[CurrOffset] = false; 402 | } 403 | } 404 | return ___NtContinue__( ThreadContext, RaiseAlert ); 405 | } 406 | NTSTATUS NTAPI __NtCreateThreadEx( PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, HANDLE ProcessHandle, PVOID StartRoutine, PVOID Argument, ULONG CreateFlags, ULONG_PTR ZeroBits, SIZE_T StackSize, SIZE_T MaximumStackSize, PPS_ATTRIBUTE_LIST AttributeList ) 407 | { 408 | __NtCreateThreadEx__ ___NtCreateThreadEx__ = (__NtCreateThreadEx__) Hooks_Informastion::Nt_CreateThreadExP; 409 | ULONG Flags = CreateFlags; 410 | if (Flags & THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER) 411 | { 412 | Flags &= ~THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER; 413 | } 414 | return ___NtCreateThreadEx__( ThreadHandle, DesiredAccess, ObjectAttributes, ProcessHandle, StartRoutine, Argument, Flags, ZeroBits, StackSize, MaximumStackSize, AttributeList ); 415 | } 416 | NTSTATUS NTAPI __NtSetInformationProcess( HANDLE ProcessHandle, PROCESS_INFORMATION_CLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength ) 417 | { 418 | __NtSetInformationProcess__ ___NtSetInformationProcess__ = (__NtSetInformationProcess__) Hooks_Informastion::Nt_SetInformationProcessP; 419 | if (ProcessInformationClass == SystemCrashDumpInformation) 420 | { 421 | IsEnabledTracing = true; 422 | return STATUS_SUCCESS; 423 | } 424 | else if (ProcessInformationClass == ProcessDebugFlags) 425 | { 426 | // Check if is the correct size 427 | if (ProcessInformationLength >= sizeof( DWORD_PTR )) 428 | { 429 | DebugFlags = *(DWORD_PTR *) ProcessInformation; 430 | } 431 | else 432 | return STATUS_INVALID_PARAMETER; 433 | } 434 | return ___NtSetInformationProcess__( ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength ); 435 | } 436 | NTSTATUS NTAPI __NtYieldExecution() 437 | { 438 | return STATUS_NO_YIELD_PERFORMED; 439 | } 440 | NTSTATUS NTAPI __NtSetDebugFilterState( ULONG ComponentId, ULONG Level, BOOLEAN State ) 441 | { 442 | return STATUS_ACCESS_DENIED; 443 | } 444 | 445 | VOID NTAPI __KiUserExceptionDispatcher( PEXCEPTION_RECORD ExceptionRecord, PCONTEXT Context ) 446 | { 447 | if (Context) 448 | { 449 | if (Context->ContextFlags & CONTEXT_DEBUG_REGISTERS) 450 | { 451 | size_t CurrOffset = Hooks_Manager::GetOffsetByThreadID( GetCurrentThreadId() ); 452 | 453 | // Now each Thread handle should have its own CONTEXT. 454 | BeckupHardwareBP[CurrOffset].Dr0 = Context->Dr0; 455 | BeckupHardwareBP[CurrOffset].Dr1 = Context->Dr1; 456 | BeckupHardwareBP[CurrOffset].Dr2 = Context->Dr2; 457 | BeckupHardwareBP[CurrOffset].Dr3 = Context->Dr3; 458 | BeckupHardwareBP[CurrOffset].Dr6 = Context->Dr6; 459 | BeckupHardwareBP[CurrOffset].Dr7 = Context->Dr7; 460 | 461 | Context->Dr0 = FakeContext[CurrOffset].Dr0; 462 | Context->Dr1 = FakeContext[CurrOffset].Dr1; 463 | Context->Dr2 = FakeContext[CurrOffset].Dr2; 464 | Context->Dr3 = FakeContext[CurrOffset].Dr3; 465 | Context->Dr6 = FakeContext[CurrOffset].Dr6; 466 | Context->Dr7 = FakeContext[CurrOffset].Dr7; 467 | 468 | KIUEDFlag[CurrOffset] = true; 469 | } 470 | } 471 | } 472 | NAKED VOID NTAPI __RKiUserExceptionDispatcher( PEXCEPTION_RECORD ExceptionRecord, PCONTEXT Context ) 473 | { 474 | // We'll write bytes manually for x64. 475 | #ifndef _WIN64 476 | _asm 477 | { 478 | push dword ptr[esp + 4] 479 | push dword ptr[esp + 4] 480 | call __KiUserExceptionDispatcher 481 | jmp Hooks_Informastion::Nt_ExceptionDispatcherP 482 | } 483 | #endif 484 | } 485 | 486 | 487 | BOOL WINAPI __Process32FirstW( HANDLE hSnapshot, LPPROCESSENTRY32 lppe ) 488 | { 489 | BOOL Return; 490 | __Process32First__ ___Process32First__ = (__Process32First__) Hooks_Informastion::Kernel32_Process32FirstWP; 491 | Return = ___Process32First__( hSnapshot, lppe ); 492 | 493 | // Here we patch again the parent PID 494 | if (Return) 495 | { 496 | // Target process can check processes names 497 | for (int i = 0; i < 13; i++) 498 | { 499 | if (lstrcmpW( lppe->szExeFile, Debuggers[i] ) == 0) 500 | { 501 | UINT Length = lstrlenW( lppe->szExeFile ); 502 | ZeroMemory( lppe->szExeFile, (Length * sizeof( wchar_t )) ); 503 | lstrcpyW( lppe->szExeFile, DebuggersPatch[i] ); 504 | break; 505 | } 506 | } 507 | 508 | if (lppe->th32ProcessID == Hooks_Informastion::CurrentProcessID) 509 | { 510 | lppe->th32ParentProcessID = (DWORD) Hooks_Informastion::FPPID; 511 | } 512 | } 513 | return Return; 514 | } 515 | BOOL WINAPI __Process32NextW( HANDLE hSnapshot, LPPROCESSENTRY32 lppe ) 516 | { 517 | BOOL Return; 518 | __Process32Next__ ___Process32Next__ = (__Process32Next__) Hooks_Informastion::Kernel32_Process32NextWP; 519 | Return = ___Process32Next__( hSnapshot, lppe ); 520 | 521 | // Here we patch again the parent PID 522 | if (Return) 523 | { 524 | // Target process can check the process name 525 | for (int i = 0; i < 13; i++) 526 | { 527 | if (lstrcmpW( lppe->szExeFile, Debuggers[i] ) == 0) 528 | { 529 | UINT Length = lstrlenW( lppe->szExeFile ); 530 | ZeroMemory( lppe->szExeFile, (Length * sizeof( wchar_t )) ); 531 | lstrcpyW( lppe->szExeFile, DebuggersPatch[i] ); 532 | break; 533 | } 534 | } 535 | 536 | if (lppe->th32ProcessID == Hooks_Informastion::CurrentProcessID) 537 | { 538 | lppe->th32ParentProcessID = (DWORD) Hooks_Informastion::FPPID; 539 | } 540 | } 541 | return Return; 542 | } 543 | DWORD WINAPI __GetTickCount() 544 | { 545 | return 1; // Return static value 546 | } 547 | ULONGLONG WINAPI __GetTickCount64() 548 | { 549 | return 1; // Return static value 550 | } 551 | } -------------------------------------------------------------------------------- /src/hook_emus.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2020 Rat431 (https://github.com/Rat431). 3 | This software is under the MIT license, for more informations check the LICENSE file. 4 | */ 5 | 6 | #pragma once 7 | #include "Defs.h" 8 | #include 9 | 10 | // Define original functions 11 | typedef NTSTATUS( NTAPI * __NtQueryInformationProcess__ )(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG); 12 | typedef NTSTATUS( NTAPI * __NtSetInformationThread__ )(HANDLE, THREADINFOCLASS, PVOID, ULONG); 13 | typedef NTSTATUS( NTAPI * __NtQuerySystemInformation__ )(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG); 14 | typedef NTSTATUS( NTAPI * __NtClose__ )(HANDLE); 15 | typedef NTSTATUS( NTAPI * __NtQueryObject__ )(HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, PULONG); 16 | typedef NTSTATUS( NTAPI * __NtGetContextThread__ )(HANDLE, PCONTEXT); 17 | typedef NTSTATUS( NTAPI * __NtSetContextThread__ )(HANDLE, PCONTEXT); 18 | typedef NTSTATUS( NTAPI * __NtContinue__ )(PCONTEXT, BOOLEAN); 19 | typedef NTSTATUS( NTAPI * __NtCreateThreadEx__ )(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, HANDLE, PVOID, PVOID, ULONG, ULONG_PTR, SIZE_T, SIZE_T, PPS_ATTRIBUTE_LIST); 20 | typedef NTSTATUS( NTAPI * __NtSetInformationProcess__ )(HANDLE, PROCESS_INFORMATION_CLASS, PVOID, ULONG); 21 | typedef NTSTATUS( NTAPI * __NtYieldExecution__ )(); 22 | typedef NTSTATUS( NTAPI * __NtSetDebugFilterState__ )(ULONG, ULONG, BOOLEAN); 23 | 24 | typedef VOID( NTAPI * __KiUserExceptionDispatcher__ )(PEXCEPTION_RECORD, PCONTEXT); 25 | typedef BOOL( WINAPI * __Process32First__ )(HANDLE, LPPROCESSENTRY32); 26 | typedef BOOL( WINAPI * __Process32Next__ )(HANDLE, LPPROCESSENTRY32); 27 | 28 | namespace Hook_emu 29 | { 30 | void InitHookFunctionsVars(); 31 | 32 | // proxied functions 33 | NTSTATUS NTAPI __NtQueryInformationProcess( HANDLE ProcessHandle, PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength ); 34 | NTSTATUS NTAPI __NtSetInformationThread( HANDLE ThreadHandle, THREADINFOCLASS ThreadInformationClass, PVOID ThreadInformation, ULONG ThreadInformationLength ); 35 | NTSTATUS NTAPI __NtQuerySystemInformation( SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength ); 36 | NTSTATUS NTAPI __NtClose( HANDLE Handle ); 37 | NTSTATUS NTAPI __NtQueryObject( HANDLE Handle, OBJECT_INFORMATION_CLASS ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength ); 38 | 39 | // DRx functions 40 | NTSTATUS NTAPI __NtGetContextThread( HANDLE ThreadHandle, PCONTEXT pContext ); 41 | NTSTATUS NTAPI __NtSetContextThread( HANDLE ThreadHandle, PCONTEXT pContext ); 42 | 43 | NTSTATUS NTAPI __NtContinue( PCONTEXT ThreadContext, BOOLEAN RaiseAlert ); 44 | NTSTATUS NTAPI __NtCreateThreadEx( PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, HANDLE ProcessHandle, PVOID StartRoutine, PVOID Argument, ULONG CreateFlags, ULONG_PTR ZeroBits, SIZE_T StackSize, SIZE_T MaximumStackSize, PPS_ATTRIBUTE_LIST AttributeList ); 45 | NTSTATUS NTAPI __NtSetInformationProcess( HANDLE ProcessHandle, PROCESS_INFORMATION_CLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength ); 46 | NTSTATUS NTAPI __NtYieldExecution(); 47 | NTSTATUS NTAPI __NtSetDebugFilterState( ULONG ComponentId, ULONG Level, BOOLEAN State ); 48 | 49 | VOID NTAPI __KiUserExceptionDispatcher( PEXCEPTION_RECORD ExceptionRecord, PCONTEXT Context ); 50 | VOID NTAPI __RKiUserExceptionDispatcher( PEXCEPTION_RECORD ExceptionRecord, PCONTEXT Context ); 51 | 52 | 53 | BOOL WINAPI __Process32FirstW( HANDLE hSnapshot, LPPROCESSENTRY32 lppe ); 54 | BOOL WINAPI __Process32NextW( HANDLE hSnapshot, LPPROCESSENTRY32 lppe ); 55 | DWORD WINAPI __GetTickCount(); 56 | ULONGLONG WINAPI __GetTickCount64(); 57 | } -------------------------------------------------------------------------------- /src/hooks.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2020 Rat431 (https://github.com/Rat431). 3 | This software is under the MIT license, for more informations check the LICENSE file. 4 | */ 5 | 6 | #include "hooks.h" 7 | #include "Defs.h" 8 | #include 9 | #include 10 | #include 11 | 12 | #ifdef _WIN64 13 | #define VALID_MACHINE IMAGE_FILE_MACHINE_AMD64 14 | #else 15 | #define VALID_MACHINE IMAGE_FILE_MACHINE_I386 16 | #endif 17 | 18 | // var 19 | static char ColdHidepath[MAX_PATH] = { 0 }; 20 | 21 | namespace Hooks_Informastion 22 | { 23 | HMODULE hNtDll = NULL; 24 | HMODULE hKernel = NULL; 25 | HMODULE hKernel32 = NULL; 26 | void * KIUEDRPage = NULL; 27 | DWORD CurrentProcessID = NULL; 28 | ULONG_PTR FPPID = NULL; 29 | 30 | // PEB. 31 | void * PEB_BeingDebuggedP = NULL; 32 | int32_t PEB_BeingDebuggedID = NULL; 33 | 34 | void * PEB_NtGlobalFlagP = NULL; 35 | int32_t PEB_NtGlobalFlagID = NULL; 36 | 37 | // HeapFlags 38 | void * FlagsHeapFlagsP = NULL; 39 | int32_t FlagsHeapFlagsID = NULL; 40 | 41 | // Some ntdll apis 42 | void * Nt_QueryProcessP = NULL; 43 | int32_t Nt_QueryProcessID = NULL; 44 | 45 | void * Nt_QuerySystemP = NULL; 46 | int32_t Nt_QuerySystemID = NULL; 47 | 48 | void * Nt_SetThreadInformationP = NULL; 49 | int32_t Nt_SetThreadInformationID = NULL; 50 | 51 | void * Nt_CloseP = NULL; 52 | int32_t Nt_CloseID = NULL; 53 | 54 | void * Nt_QueryObjectP = NULL; 55 | int32_t Nt_QueryObjectID = NULL; 56 | 57 | void * Nt_NtGetContextThreadP = NULL; 58 | int32_t Nt_NtGetContextThreadID = NULL; 59 | 60 | void * Nt_NtSetContextThreadP = NULL; 61 | int32_t Nt_NtSetContextThreadID = NULL; 62 | 63 | void * Nt_ContinueP = NULL; 64 | int32_t Nt_ContinueID = NULL; 65 | 66 | void * Nt_CreateThreadExP = NULL; 67 | int32_t Nt_CreateThreadExID = NULL; 68 | 69 | void * Nt_ExceptionDispatcherP = NULL; 70 | int32_t Nt_ExceptionDispatcherID = NULL; 71 | 72 | void * Nt_SetInformationProcessP = NULL; 73 | int32_t Nt_SetInformationProcessID = NULL; 74 | 75 | void * Nt_YieldExecutionP = NULL; 76 | int32_t Nt_YieldExecutionID = NULL; 77 | 78 | void * Nt_SetDebugFilterStateP = NULL; 79 | int32_t Nt_SetDebugFilterStateID = NULL; 80 | 81 | void * Kernel32_Process32FirstWP = NULL; 82 | int32_t Kernel32_Process32FirstWID = NULL; 83 | 84 | void * Kernel32_Process32NextWP = NULL; 85 | int32_t Kernel32_Process32NextWID = NULL; 86 | 87 | void * Kernel32_GetTickCountP = NULL; 88 | int32_t Kernel32_GetTickCountID = NULL; 89 | 90 | void * Kernel32_GetTickCount64P = NULL; 91 | int32_t Kernel32_GetTickCount64ID = NULL; 92 | } 93 | 94 | namespace Hooks_Config 95 | { 96 | // Hide PEB. 97 | bool HideWholePEB = true; 98 | bool PEB_BeingDebugged = false; 99 | bool PEB_NtGlobalFlag = false; 100 | 101 | // HeapFlags 102 | bool HeapFlags = false; 103 | 104 | // DRx 105 | bool HideWholeDRx = true; 106 | bool FakeContextEmulation = false; 107 | 108 | bool DRx_ThreadContextRead = false; 109 | bool DRx_ThreadContextWrite = false; 110 | bool Nt_Continue = false; 111 | bool Nt_KiUserExceptionDispatcher = false; 112 | 113 | // Anti attach 114 | bool Anti_Anti_Attach = false; 115 | 116 | // Some ntdll apis 117 | bool Nt_QueryProcess = true; 118 | bool Nt_QuerySystem = true; 119 | bool Nt_SetThreadInformation = true; 120 | bool Nt_Close = true; 121 | bool Nt_QueryObject = true; 122 | bool Nt_CreateThreadEx = true; 123 | bool Nt_SetInformationProcess = true; 124 | bool Nt_YieldExecution = true; 125 | bool Nt_SetDebugFilterState = true; 126 | 127 | bool Kernel32_Process32First = true; 128 | bool Kernel32_Process32Next = true; 129 | bool Kernel32_GetTickCount = true; 130 | bool Kernel32_GetTickCount64 = true; 131 | } 132 | 133 | namespace Hooks 134 | { 135 | static void HidePEB() 136 | { 137 | void * PEB_BaseAddress = nullptr; 138 | void * _HeapAddress = nullptr; 139 | 140 | // Get PEB Address by the offset, or you can even call NtQueryInformationProcess. 141 | PEB_BaseAddress = (void *) GetPebFunction(); 142 | 143 | if (PEB_BaseAddress) 144 | { 145 | // Check if we should patch the flags first. 146 | if (Hooks_Config::PEB_BeingDebugged) 147 | { 148 | Hooks_Informastion::PEB_BeingDebuggedP = (void *) ((ULONG_PTR) PEB_BaseAddress + PEB_BeingDebuggedOffset); 149 | *(BYTE *) Hooks_Informastion::PEB_BeingDebuggedP = 0; 150 | } 151 | if (Hooks_Config::PEB_NtGlobalFlag) 152 | { 153 | Hooks_Informastion::PEB_NtGlobalFlagP = (void *) ((ULONG_PTR) PEB_BaseAddress + PEB_NtGlobalFlagOffset); 154 | *(BYTE *) Hooks_Informastion::PEB_NtGlobalFlagP = 0; 155 | } 156 | if (Hooks_Config::HeapFlags) 157 | { 158 | // Get Process heap base address 159 | memcpy( &_HeapAddress, (void *) ((ULONG_PTR) PEB_BaseAddress + HeapPEB_Offset), MAX_ADDRESS_SIZE ); 160 | 161 | if (_HeapAddress) 162 | { 163 | // Check if the current Windows OS is Windows Vista or greater as different force flags and heap flags offsets in older versions. 164 | if (IsWindowsVistaOrGreater()) 165 | { 166 | // Check if HEAP_GROWABLE flag is not setted, if not, we set it 167 | if (!(*(DWORD *) ((ULONG_PTR) _HeapAddress + HeapFlagsBaseWinHigher) & HEAP_GROWABLE)) 168 | { 169 | *(DWORD *) ((ULONG_PTR) _HeapAddress + HeapFlagsBaseWinHigher) |= HEAP_GROWABLE; 170 | } 171 | *(DWORD *) ((ULONG_PTR) _HeapAddress + HeapForceFlagsBaseWinHigher) = 0; 172 | } 173 | else 174 | { 175 | // Check if HEAP_GROWABLE flag is not setted, if not, we set it 176 | if (!(*(DWORD *) ((ULONG_PTR) _HeapAddress + HeapFlagsBaseWinLower) & HEAP_GROWABLE)) 177 | { 178 | *(DWORD *) ((ULONG_PTR) _HeapAddress + HeapFlagsBaseWinLower) |= HEAP_GROWABLE; 179 | } 180 | *(DWORD *) ((ULONG_PTR) _HeapAddress + HeapForceFlagsBaseWinLower) = 0; 181 | } 182 | } 183 | } 184 | } 185 | } 186 | 187 | static void HideDRx() 188 | { 189 | Hooks_Informastion::Nt_NtGetContextThreadP = GetProcAddress( Hooks_Informastion::hNtDll, "NtGetContextThread" ); 190 | Hooks_Informastion::Nt_NtSetContextThreadP = GetProcAddress( Hooks_Informastion::hNtDll, "NtSetContextThread" ); 191 | 192 | if (Hooks_Informastion::Nt_NtGetContextThreadP) 193 | { 194 | if (Hooks_Config::DRx_ThreadContextRead) 195 | { 196 | // Hook 197 | Hook_Info * HookDataS; 198 | int32_t ErrorCode = 0; 199 | 200 | Hooks_Informastion::Nt_NtGetContextThreadID = ColdHook_Service::InitFunctionHookByAddress( &HookDataS, true, 201 | Hooks_Informastion::Nt_NtGetContextThreadP, Hook_emu::__NtGetContextThread, &ErrorCode ); 202 | 203 | if (Hooks_Informastion::Nt_NtGetContextThreadID > 0 && ErrorCode == 0) 204 | { 205 | ColdHook_Service::ServiceRegisterHookInformation( HookDataS, Hooks_Informastion::Nt_NtGetContextThreadID, &ErrorCode ); 206 | Hooks_Informastion::Nt_NtGetContextThreadP = HookDataS->OriginalF; 207 | } 208 | } 209 | } 210 | if (Hooks_Informastion::Nt_NtSetContextThreadP) 211 | { 212 | if (Hooks_Config::DRx_ThreadContextWrite) 213 | { 214 | // Hook 215 | Hook_Info * HookDataS; 216 | int32_t ErrorCode = 0; 217 | 218 | Hooks_Informastion::Nt_NtSetContextThreadID = ColdHook_Service::InitFunctionHookByAddress( &HookDataS, true, 219 | Hooks_Informastion::Nt_NtSetContextThreadP, Hook_emu::__NtSetContextThread, &ErrorCode ); 220 | 221 | if (Hooks_Informastion::Nt_NtSetContextThreadID > 0 && ErrorCode == 0) 222 | { 223 | ColdHook_Service::ServiceRegisterHookInformation( HookDataS, Hooks_Informastion::Nt_NtSetContextThreadID, &ErrorCode ); 224 | Hooks_Informastion::Nt_NtSetContextThreadP = HookDataS->OriginalF; 225 | } 226 | } 227 | } 228 | } 229 | static void HideProcessInformations() 230 | { 231 | Hooks_Informastion::Nt_QueryProcessP = GetProcAddress( Hooks_Informastion::hNtDll, "NtQueryInformationProcess" ); 232 | 233 | if (Hooks_Informastion::Nt_QueryProcessP) 234 | { 235 | if (Hooks_Config::Nt_QueryProcess) 236 | { 237 | // Hook 238 | Hook_Info * HookDataS; 239 | int32_t ErrorCode = 0; 240 | 241 | Hooks_Informastion::Nt_QueryProcessID = ColdHook_Service::InitFunctionHookByAddress( &HookDataS, true, 242 | Hooks_Informastion::Nt_QueryProcessP, Hook_emu::__NtQueryInformationProcess, &ErrorCode ); 243 | 244 | if (Hooks_Informastion::Nt_QueryProcessID > 0 && ErrorCode == 0) 245 | { 246 | if (ColdHook_Service::ServiceRegisterHookInformation( HookDataS, Hooks_Informastion::Nt_QueryProcessID, &ErrorCode )) 247 | { 248 | Hooks_Informastion::Nt_QueryProcessP = HookDataS->OriginalF; 249 | } 250 | } 251 | } 252 | } 253 | } 254 | static void HideSetInformationThread() 255 | { 256 | Hooks_Informastion::Nt_SetThreadInformationP = GetProcAddress( Hooks_Informastion::hNtDll, "NtSetInformationThread" ); 257 | 258 | if (Hooks_Informastion::Nt_SetThreadInformationP) 259 | { 260 | if (Hooks_Config::Nt_SetThreadInformation) 261 | { 262 | // Hook 263 | Hook_Info * HookDataS; 264 | int32_t ErrorCode = 0; 265 | 266 | Hooks_Informastion::Nt_SetThreadInformationID = ColdHook_Service::InitFunctionHookByAddress( &HookDataS, true, 267 | Hooks_Informastion::Nt_SetThreadInformationP, Hook_emu::__NtSetInformationThread, &ErrorCode ); 268 | 269 | if (Hooks_Informastion::Nt_SetThreadInformationID > 0 && ErrorCode == 0) 270 | { 271 | ColdHook_Service::ServiceRegisterHookInformation( HookDataS, Hooks_Informastion::Nt_SetThreadInformationID, &ErrorCode ); 272 | Hooks_Informastion::Nt_SetThreadInformationP = HookDataS->OriginalF; 273 | } 274 | } 275 | } 276 | } 277 | static void HideQuerySystemInformation() 278 | { 279 | Hooks_Informastion::Nt_QuerySystemP = GetProcAddress( Hooks_Informastion::hNtDll, "NtQuerySystemInformation" ); 280 | 281 | if (Hooks_Informastion::Nt_QuerySystemP) 282 | { 283 | if (Hooks_Config::Nt_QuerySystem) 284 | { 285 | // Hook 286 | Hook_Info * HookDataS; 287 | int32_t ErrorCode = 0; 288 | 289 | Hooks_Informastion::Nt_QuerySystemID = ColdHook_Service::InitFunctionHookByAddress( &HookDataS, true, 290 | Hooks_Informastion::Nt_QuerySystemP, Hook_emu::__NtQuerySystemInformation, &ErrorCode ); 291 | 292 | if (Hooks_Informastion::Nt_QuerySystemID > 0 && ErrorCode == 0) 293 | { 294 | ColdHook_Service::ServiceRegisterHookInformation( HookDataS, Hooks_Informastion::Nt_QuerySystemID, &ErrorCode ); 295 | Hooks_Informastion::Nt_QuerySystemP = HookDataS->OriginalF; 296 | } 297 | } 298 | } 299 | } 300 | static void HideCloseHandle() 301 | { 302 | Hooks_Informastion::Nt_CloseP = GetProcAddress( Hooks_Informastion::hNtDll, "NtClose" ); 303 | 304 | if (Hooks_Informastion::Nt_CloseP) 305 | { 306 | if (Hooks_Config::Nt_Close) 307 | { 308 | // Hook 309 | Hook_Info * HookDataS; 310 | int32_t ErrorCode = 0; 311 | 312 | Hooks_Informastion::Nt_CloseID = ColdHook_Service::InitFunctionHookByAddress( &HookDataS, true, 313 | Hooks_Informastion::Nt_CloseP, Hook_emu::__NtClose, &ErrorCode ); 314 | 315 | if (Hooks_Informastion::Nt_CloseID > 0 && ErrorCode == 0) 316 | { 317 | ColdHook_Service::ServiceRegisterHookInformation( HookDataS, Hooks_Informastion::Nt_CloseID, &ErrorCode ); 318 | Hooks_Informastion::Nt_CloseP = HookDataS->OriginalF; 319 | } 320 | } 321 | } 322 | } 323 | static void HideQueryObject() 324 | { 325 | Hooks_Informastion::Nt_QueryObjectP = GetProcAddress( Hooks_Informastion::hNtDll, "NtQueryObject" ); 326 | 327 | if (Hooks_Informastion::Nt_QueryObjectP) 328 | { 329 | if (Hooks_Config::Nt_QueryObject) 330 | { 331 | // Hook 332 | Hook_Info * HookDataS; 333 | int32_t ErrorCode = 0; 334 | 335 | Hooks_Informastion::Nt_QueryObjectID = ColdHook_Service::InitFunctionHookByAddress( &HookDataS, true, 336 | Hooks_Informastion::Nt_QueryObjectP, Hook_emu::__NtQueryObject, &ErrorCode ); 337 | 338 | if (Hooks_Informastion::Nt_QueryObjectID > 0 && ErrorCode == 0) 339 | { 340 | ColdHook_Service::ServiceRegisterHookInformation( HookDataS, Hooks_Informastion::Nt_QueryObjectID, &ErrorCode ); 341 | Hooks_Informastion::Nt_QueryObjectP = HookDataS->OriginalF; 342 | } 343 | } 344 | } 345 | } 346 | static void HideSetInformationProcess() 347 | { 348 | Hooks_Informastion::Nt_SetInformationProcessP = GetProcAddress( Hooks_Informastion::hNtDll, "NtSetInformationProcess" ); 349 | 350 | if (Hooks_Informastion::Nt_SetInformationProcessP) 351 | { 352 | if (Hooks_Config::Nt_SetInformationProcess) 353 | { 354 | // Hook 355 | Hook_Info * HookDataS; 356 | int32_t ErrorCode = 0; 357 | 358 | Hooks_Informastion::Nt_SetInformationProcessID = ColdHook_Service::InitFunctionHookByAddress( &HookDataS, true, 359 | Hooks_Informastion::Nt_SetInformationProcessP, Hook_emu::__NtSetInformationProcess, &ErrorCode ); 360 | 361 | if (Hooks_Informastion::Nt_SetInformationProcessID > 0 && ErrorCode == 0) 362 | { 363 | ColdHook_Service::ServiceRegisterHookInformation( HookDataS, Hooks_Informastion::Nt_SetInformationProcessID, &ErrorCode ); 364 | Hooks_Informastion::Nt_SetInformationProcessP = HookDataS->OriginalF; 365 | } 366 | } 367 | } 368 | } 369 | static void HideNtContinue() 370 | { 371 | Hooks_Informastion::Nt_ContinueP = GetProcAddress( Hooks_Informastion::hNtDll, "NtContinue" ); 372 | 373 | if (Hooks_Informastion::Nt_ContinueP) 374 | { 375 | if (Hooks_Config::Nt_Continue) 376 | { 377 | // Hook 378 | Hook_Info * HookDataS; 379 | int32_t ErrorCode = 0; 380 | 381 | Hooks_Informastion::Nt_ContinueID = ColdHook_Service::InitFunctionHookByAddress( &HookDataS, true, 382 | Hooks_Informastion::Nt_ContinueP, Hook_emu::__NtContinue, &ErrorCode ); 383 | 384 | if (Hooks_Informastion::Nt_ContinueID > 0 && ErrorCode == 0) 385 | { 386 | ColdHook_Service::ServiceRegisterHookInformation( HookDataS, Hooks_Informastion::Nt_ContinueID, &ErrorCode ); 387 | Hooks_Informastion::Nt_ContinueP = HookDataS->OriginalF; 388 | } 389 | } 390 | } 391 | } 392 | static void HideCreateThreadEx() 393 | { 394 | Hooks_Informastion::Nt_CreateThreadExP = GetProcAddress( Hooks_Informastion::hNtDll, "NtCreateThreadEx" ); 395 | 396 | if (Hooks_Informastion::Nt_CreateThreadExP) 397 | { 398 | if (Hooks_Config::Nt_CreateThreadEx) 399 | { 400 | // Hook 401 | Hook_Info * HookDataS; 402 | int32_t ErrorCode = 0; 403 | 404 | Hooks_Informastion::Nt_CreateThreadExID = ColdHook_Service::InitFunctionHookByAddress( &HookDataS, true, 405 | Hooks_Informastion::Nt_CreateThreadExP, Hook_emu::__NtCreateThreadEx, &ErrorCode ); 406 | 407 | if (Hooks_Informastion::Nt_CreateThreadExID > 0 && ErrorCode == 0) 408 | { 409 | ColdHook_Service::ServiceRegisterHookInformation( HookDataS, Hooks_Informastion::Nt_CreateThreadExID, &ErrorCode ); 410 | Hooks_Informastion::Nt_CreateThreadExP = HookDataS->OriginalF; 411 | } 412 | } 413 | } 414 | } 415 | static BYTE x64KIUEDHook[25] = { 0x48, 0x89, 0xE1, 0x48, 0x81, 0xC1, 0xF0, 0x04, 0x00, 0x00, 0x48, 0x89, 416 | 0xE2, 0xFF, 0x15, 0x0E, 0x00, 0x00, 0x00, 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00 }; 417 | static void HideExceptionDispatcher() 418 | { 419 | Hooks_Informastion::Nt_ExceptionDispatcherP = GetProcAddress( Hooks_Informastion::hNtDll, "KiUserExceptionDispatcher" ); 420 | 421 | if (Hooks_Informastion::Nt_ExceptionDispatcherP) 422 | { 423 | if (Hooks_Config::Nt_KiUserExceptionDispatcher) 424 | { 425 | // Hook 426 | Hook_Info * HookDataS; 427 | int32_t ErrorCode = 0; 428 | void * TempPointer = nullptr; 429 | bool IsRunning64Bit = ColdHook_Service::Is64BitProcess(); 430 | 431 | if (IsRunning64Bit) 432 | { 433 | // Allocate a page 434 | Hooks_Informastion::KIUEDRPage = VirtualAlloc( nullptr, 0x1000, MEM_COMMIT, PAGE_EXECUTE_READWRITE ); 435 | TempPointer = Hooks_Informastion::KIUEDRPage; 436 | } 437 | else 438 | { 439 | TempPointer = Hook_emu::__RKiUserExceptionDispatcher; 440 | } 441 | if (TempPointer) 442 | { 443 | Hooks_Informastion::Nt_ExceptionDispatcherID = ColdHook_Service::InitFunctionHookByAddress( &HookDataS, true, 444 | Hooks_Informastion::Nt_ExceptionDispatcherP, TempPointer, &ErrorCode ); 445 | 446 | if (Hooks_Informastion::Nt_ExceptionDispatcherID > 0 && ErrorCode == 0) 447 | { 448 | ColdHook_Service::ServiceRegisterHookInformation( HookDataS, Hooks_Informastion::Nt_ExceptionDispatcherID, &ErrorCode ); 449 | Hooks_Informastion::Nt_ExceptionDispatcherP = HookDataS->OriginalF; 450 | 451 | if (IsRunning64Bit) 452 | { 453 | memcpy( TempPointer, x64KIUEDHook, sizeof( x64KIUEDHook ) ); 454 | *(void **) ((ULONG_PTR) TempPointer + sizeof( x64KIUEDHook )) = Hooks_Informastion::Nt_ExceptionDispatcherP; 455 | *(void **) ((ULONG_PTR) TempPointer + sizeof( x64KIUEDHook ) + sizeof( void * )) = Hook_emu::__KiUserExceptionDispatcher; 456 | } 457 | } 458 | } 459 | } 460 | } 461 | } 462 | static void HideYieldExecution() 463 | { 464 | Hooks_Informastion::Nt_YieldExecutionP = GetProcAddress( Hooks_Informastion::hNtDll, "NtYieldExecution" ); 465 | 466 | if (Hooks_Informastion::Nt_YieldExecutionP) 467 | { 468 | if (Hooks_Config::Nt_YieldExecution) 469 | { 470 | // Hook 471 | Hook_Info * HookDataS; 472 | int32_t ErrorCode = 0; 473 | 474 | Hooks_Informastion::Nt_YieldExecutionID = ColdHook_Service::InitFunctionHookByAddress( &HookDataS, true, 475 | Hooks_Informastion::Nt_YieldExecutionP, Hook_emu::__NtYieldExecution, &ErrorCode ); 476 | 477 | if (Hooks_Informastion::Nt_YieldExecutionID > 0 && ErrorCode == 0) 478 | { 479 | ColdHook_Service::ServiceRegisterHookInformation( HookDataS, Hooks_Informastion::Nt_YieldExecutionID, &ErrorCode ); 480 | Hooks_Informastion::Nt_YieldExecutionP = HookDataS->OriginalF; 481 | } 482 | } 483 | } 484 | } 485 | static void HideSetDebugFilterState() 486 | { 487 | Hooks_Informastion::Nt_SetDebugFilterStateP = GetProcAddress( Hooks_Informastion::hNtDll, "NtSetDebugFilterState" ); 488 | 489 | if (Hooks_Informastion::Nt_SetDebugFilterStateP) 490 | { 491 | if (Hooks_Config::Nt_SetDebugFilterState) 492 | { 493 | // Hook 494 | Hook_Info * HookDataS; 495 | int32_t ErrorCode = 0; 496 | 497 | Hooks_Informastion::Nt_SetDebugFilterStateID = ColdHook_Service::InitFunctionHookByAddress( &HookDataS, true, 498 | Hooks_Informastion::Nt_SetDebugFilterStateP, Hook_emu::__NtSetDebugFilterState, &ErrorCode ); 499 | 500 | if (Hooks_Informastion::Nt_SetDebugFilterStateID > 0 && ErrorCode == 0) 501 | { 502 | ColdHook_Service::ServiceRegisterHookInformation( HookDataS, Hooks_Informastion::Nt_SetDebugFilterStateID, &ErrorCode ); 503 | Hooks_Informastion::Nt_SetDebugFilterStateP = HookDataS->OriginalF; 504 | } 505 | } 506 | } 507 | } 508 | static bool RetrieveSystemDirectory( char * OutPut ) 509 | { 510 | #ifdef _WIN64 511 | GetSystemDirectoryA( OutPut, MAX_PATH ); 512 | #else 513 | GetSystemWow64DirectoryA( OutPut, MAX_PATH ); 514 | if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 515 | { 516 | GetSystemDirectoryA( OutPut, MAX_PATH ); 517 | } 518 | #endif 519 | return true; 520 | } 521 | static bool IsAddressSection( ULONG_PTR address, ULONG_PTR Baseaddress, IMAGE_SECTION_HEADER * pSHeader, IMAGE_NT_HEADERS * ntheader, void ** OutSBaseAddress, 522 | SIZE_T * OutSSize ) 523 | { 524 | for (int i = 0; i < ntheader->FileHeader.NumberOfSections; i++) 525 | { 526 | if ((pSHeader->VirtualAddress <= (address - Baseaddress)) && ((address - Baseaddress) < (pSHeader->VirtualAddress + pSHeader->Misc.VirtualSize))) 527 | { 528 | *OutSBaseAddress = (void *) ((ULONG_PTR) Baseaddress + pSHeader->VirtualAddress); 529 | *OutSSize = pSHeader->Misc.VirtualSize; 530 | return true; 531 | } 532 | pSHeader++; 533 | } 534 | return false; 535 | } 536 | static size_t ConvertRvaToOffset( ULONG_PTR address, ULONG_PTR Baseaddress, IMAGE_SECTION_HEADER * pSHeader, IMAGE_NT_HEADERS * ntheader ) 537 | { 538 | for (int i = 0; i < ntheader->FileHeader.NumberOfSections; i++) 539 | { 540 | if ((pSHeader->VirtualAddress <= (address - Baseaddress)) && ((address - Baseaddress) < (pSHeader->VirtualAddress + pSHeader->Misc.VirtualSize))) 541 | { 542 | return (address - Baseaddress - pSHeader->VirtualAddress) + (pSHeader->PointerToRawData); 543 | } 544 | pSHeader++; 545 | } 546 | return NULL; 547 | } 548 | static bool IsAddressPresent( void ** Buffer, void * Address, size_t size ) 549 | { 550 | void ** Start = Buffer; 551 | for (size_t i = 0; i < size; i++, Start++) 552 | { 553 | if (*Start == Address) 554 | { 555 | return true; 556 | } 557 | } 558 | return false; 559 | } 560 | static CHAR SystemDirectory[MAX_PATH] = { 0 }; 561 | static void HideAntiAntiAttach() 562 | { 563 | if (Hooks_Config::Anti_Anti_Attach) 564 | { 565 | // Vars 566 | void * Page = nullptr; 567 | void ** ExportsPage = nullptr; 568 | void ** ExportsPageDbg = nullptr; 569 | void * OriginalMappedNtdll = nullptr; 570 | 571 | size_t ExportsFunctions = 0; 572 | size_t fileSize = 0; 573 | 574 | HANDLE FileP = 0; 575 | 576 | // Check if the variable is empty 577 | if (SystemDirectory[0] == 0) 578 | { 579 | RetrieveSystemDirectory( SystemDirectory ); 580 | lstrcatA( SystemDirectory, "\\ntdll.dll" ); 581 | } 582 | 583 | // Read the file 584 | FileP = CreateFileA( SystemDirectory, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); 585 | if (FileP != INVALID_HANDLE_VALUE) 586 | { 587 | // Get file size 588 | fileSize = GetFileSize( FileP, NULL ); 589 | 590 | Page = VirtualAlloc( nullptr, fileSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE ); 591 | if (Page) 592 | { 593 | // Read the file and parse headers later 594 | DWORD READ; 595 | if (!ReadFile( FileP, Page, fileSize, &READ, NULL )) 596 | { 597 | VirtualFree( Page, 0, MEM_RELEASE ); 598 | CloseHandle( FileP ); 599 | return; 600 | } 601 | 602 | // Headers 603 | auto pDosHeader = (IMAGE_DOS_HEADER *) Hooks_Informastion::hNtDll; 604 | if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) 605 | { 606 | VirtualFree( Page, 0, MEM_RELEASE ); 607 | CloseHandle( FileP ); 608 | return; 609 | } 610 | auto pNtHeader = (IMAGE_NT_HEADERS *) ((ULONG_PTR) Hooks_Informastion::hNtDll + pDosHeader->e_lfanew); 611 | if (pNtHeader->Signature != IMAGE_NT_SIGNATURE) 612 | { 613 | VirtualFree( Page, 0, MEM_RELEASE ); 614 | CloseHandle( FileP ); 615 | return; 616 | } 617 | if (pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size <= 0) 618 | { 619 | VirtualFree( Page, 0, MEM_RELEASE ); 620 | CloseHandle( FileP ); 621 | return; 622 | } 623 | if (pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress <= 0) 624 | { 625 | VirtualFree( Page, 0, MEM_RELEASE ); 626 | CloseHandle( FileP ); 627 | return; 628 | } 629 | 630 | auto pDosHeaderFile = (IMAGE_DOS_HEADER *) Page; 631 | if (pDosHeaderFile->e_magic != IMAGE_DOS_SIGNATURE) 632 | { 633 | VirtualFree( Page, 0, MEM_RELEASE ); 634 | CloseHandle( FileP ); 635 | return; 636 | } 637 | auto pNtHeaderFile = (IMAGE_NT_HEADERS *) ((ULONG_PTR) Page + pDosHeaderFile->e_lfanew); 638 | if (pNtHeaderFile->Signature != IMAGE_NT_SIGNATURE) 639 | { 640 | VirtualFree( Page, 0, MEM_RELEASE ); 641 | CloseHandle( FileP ); 642 | return; 643 | } 644 | if (pNtHeaderFile->FileHeader.Machine != VALID_MACHINE) 645 | { 646 | VirtualFree( Page, 0, MEM_RELEASE ); 647 | CloseHandle( FileP ); 648 | return; 649 | } 650 | 651 | // Map 652 | OriginalMappedNtdll = VirtualAlloc( nullptr, pNtHeaderFile->OptionalHeader.SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE ); 653 | if (!OriginalMappedNtdll) 654 | { 655 | VirtualFree( Page, 0, MEM_RELEASE ); 656 | CloseHandle( FileP ); 657 | return; 658 | } 659 | 660 | memcpy( OriginalMappedNtdll, Page, pNtHeaderFile->OptionalHeader.SizeOfHeaders ); 661 | auto pSecHeader = IMAGE_FIRST_SECTION( pNtHeaderFile ); 662 | for (int i = 0; i < pNtHeaderFile->FileHeader.NumberOfSections; i++, pSecHeader++) 663 | { 664 | if (pSecHeader->SizeOfRawData) 665 | { 666 | memcpy( (void *) ((ULONG_PTR) OriginalMappedNtdll + pSecHeader->VirtualAddress), (void *) ((ULONG_PTR) Page + pSecHeader->PointerToRawData), 667 | pSecHeader->SizeOfRawData ); 668 | } 669 | } 670 | 671 | auto pExports = (IMAGE_EXPORT_DIRECTORY *) ((ULONG_PTR) Hooks_Informastion::hNtDll + pNtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); 672 | 673 | ExportsFunctions = (sizeof( void * ) * pExports->NumberOfFunctions) + 0x100; 674 | ExportsPage = (void **) VirtualAlloc( 0, ExportsFunctions, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE ); 675 | if (!ExportsPage) 676 | { 677 | VirtualFree( OriginalMappedNtdll, 0, MEM_RELEASE ); 678 | VirtualFree( Page, 0, MEM_RELEASE ); 679 | CloseHandle( FileP ); 680 | return; 681 | } 682 | 683 | memset( ExportsPage, ExportsFunctions, 0 ); 684 | 685 | // Store exports pointers 686 | size_t DbgFunctionsCount = 0; 687 | DWORD * pExpNames = (DWORD *) ((ULONG_PTR) Hooks_Informastion::hNtDll + pExports->AddressOfNames); 688 | WORD * pOrdinalName = (WORD *) ((ULONG_PTR) Hooks_Informastion::hNtDll + pExports->AddressOfNameOrdinals); 689 | DWORD * pFunction = (DWORD *) ((ULONG_PTR) Hooks_Informastion::hNtDll + pExports->AddressOfFunctions); 690 | 691 | for (unsigned int i = 0; i < pExports->NumberOfFunctions; i++) 692 | { 693 | for (unsigned int b = 0; b < pExports->NumberOfNames; b++) 694 | { 695 | if (pOrdinalName[b] == i) 696 | { 697 | auto pFunctionName = (PCHAR) ((ULONG_PTR) Hooks_Informastion::hNtDll + pExpNames[b]); 698 | if (pFunctionName) 699 | { 700 | if (strncmp( pFunctionName, "Dbg", 3 ) == 0) 701 | { 702 | DbgFunctionsCount++; 703 | } 704 | } 705 | } 706 | } 707 | ExportsPage[i] = (void *) ((ULONG_PTR) Hooks_Informastion::hNtDll + pFunction[i]); 708 | } 709 | 710 | ExportsPageDbg = (void **) VirtualAlloc( nullptr, (sizeof( void * ) * DbgFunctionsCount) + 0x100, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE ); 711 | if (!ExportsPageDbg) 712 | { 713 | VirtualFree( OriginalMappedNtdll, 0, MEM_RELEASE ); 714 | VirtualFree( Page, 0, MEM_RELEASE ); 715 | VirtualFree( ExportsPage, 0, MEM_RELEASE ); 716 | CloseHandle( FileP ); 717 | return; 718 | } 719 | 720 | memset( ExportsPageDbg, (sizeof( void * ) * DbgFunctionsCount) + 0x100, 0 ); 721 | 722 | // Now store target functions that we must restore 723 | void ** ExportsPageDbgFLoop = ExportsPageDbg; 724 | for (unsigned int i = 0; i < pExports->NumberOfNames; i++) 725 | { 726 | auto pFunctionName = (PCHAR) ((ULONG_PTR) Hooks_Informastion::hNtDll + pExpNames[i]); 727 | if (pFunctionName) 728 | { 729 | if (strncmp( pFunctionName, "Dbg", 3 ) == 0) 730 | { 731 | *ExportsPageDbgFLoop = GetProcAddress( Hooks_Informastion::hNtDll, pFunctionName ); 732 | ExportsPageDbgFLoop++; 733 | } 734 | } 735 | } 736 | 737 | // Restore 738 | for (size_t i = 0; i < DbgFunctionsCount; i++) 739 | { 740 | for (size_t m = 0; m < 0x100; m++) 741 | { 742 | PBYTE TargetRestoreAddr = (PBYTE) ((ULONG_PTR) ExportsPageDbg[i] + m); 743 | DWORD CurrRVa; 744 | PBYTE pOrgByte; 745 | DWORD OLD; 746 | bool Break = false; 747 | if (m != 0) 748 | { 749 | // If we reach another export function then break. 750 | for (unsigned int x = 0; x < pExports->NumberOfFunctions; x++) 751 | { 752 | if (ExportsPage[x] == (void *) TargetRestoreAddr) 753 | { 754 | Break = true; 755 | break; 756 | } 757 | } 758 | } 759 | if (Break) 760 | { 761 | break; 762 | } 763 | CurrRVa = (DWORD) ((ULONG_PTR) TargetRestoreAddr - (ULONG_PTR) Hooks_Informastion::hNtDll); 764 | pOrgByte = (PBYTE) ((ULONG_PTR) OriginalMappedNtdll + CurrRVa); 765 | if (VirtualProtect( TargetRestoreAddr, sizeof( BYTE ), PAGE_EXECUTE_READWRITE, &OLD )) 766 | { 767 | *TargetRestoreAddr = *pOrgByte; 768 | VirtualProtect( TargetRestoreAddr, sizeof( BYTE ), OLD, &OLD ); 769 | } 770 | } 771 | } 772 | 773 | // Free 774 | VirtualFree( OriginalMappedNtdll, 0, MEM_RELEASE ); 775 | VirtualFree( Page, 0, MEM_RELEASE ); 776 | VirtualFree( ExportsPage, 0, MEM_RELEASE ); 777 | VirtualFree( ExportsPageDbg, 0, MEM_RELEASE ); 778 | } 779 | CloseHandle( FileP ); 780 | } 781 | } 782 | } 783 | 784 | static void HideProcess32First() 785 | { 786 | Hooks_Informastion::Kernel32_Process32FirstWP = GetProcAddress( Hooks_Informastion::hKernel32, "Process32FirstW" ); 787 | 788 | if (Hooks_Config::Kernel32_Process32First) 789 | { 790 | if (Hooks_Informastion::Kernel32_Process32FirstWP) 791 | { 792 | // Hook 793 | Hook_Info * HookDataS; 794 | int32_t ErrorCode = 0; 795 | 796 | Hooks_Informastion::Kernel32_Process32FirstWID = ColdHook_Service::InitFunctionHookByAddress( &HookDataS, true, 797 | Hooks_Informastion::Kernel32_Process32FirstWP, Hook_emu::__Process32FirstW, &ErrorCode ); 798 | 799 | if (Hooks_Informastion::Kernel32_Process32FirstWID > 0 && ErrorCode == 0) 800 | { 801 | ColdHook_Service::ServiceRegisterHookInformation( HookDataS, Hooks_Informastion::Kernel32_Process32FirstWID, &ErrorCode ); 802 | Hooks_Informastion::Kernel32_Process32FirstWP = HookDataS->OriginalF; 803 | } 804 | } 805 | } 806 | } 807 | static void HideProcess32Next() 808 | { 809 | Hooks_Informastion::Kernel32_Process32NextWP = GetProcAddress( Hooks_Informastion::hKernel32, "Process32NextW" ); 810 | 811 | if (Hooks_Config::Kernel32_Process32Next) 812 | { 813 | if (Hooks_Informastion::Kernel32_Process32NextWP) 814 | { 815 | // Hook 816 | Hook_Info * HookDataS; 817 | int32_t ErrorCode = 0; 818 | 819 | Hooks_Informastion::Kernel32_Process32NextWID = ColdHook_Service::InitFunctionHookByAddress( &HookDataS, true, 820 | Hooks_Informastion::Kernel32_Process32NextWP, Hook_emu::__Process32NextW, &ErrorCode ); 821 | 822 | if (Hooks_Informastion::Kernel32_Process32NextWID > 0 && ErrorCode == 0) 823 | { 824 | ColdHook_Service::ServiceRegisterHookInformation( HookDataS, Hooks_Informastion::Kernel32_Process32NextWID, &ErrorCode ); 825 | Hooks_Informastion::Kernel32_Process32NextWP = HookDataS->OriginalF; 826 | } 827 | } 828 | } 829 | } 830 | static void HideGetTickCount() 831 | { 832 | Hooks_Informastion::Kernel32_GetTickCountP = GetProcAddress( Hooks_Informastion::hKernel32, "GetTickCount" ); 833 | 834 | if (Hooks_Config::Kernel32_GetTickCount) 835 | { 836 | if (Hooks_Informastion::Kernel32_GetTickCountP) 837 | { 838 | // Hook 839 | Hook_Info * HookDataS; 840 | int32_t ErrorCode = 0; 841 | 842 | Hooks_Informastion::Kernel32_GetTickCountID = ColdHook_Service::InitFunctionHookByAddress( &HookDataS, false, 843 | Hooks_Informastion::Kernel32_GetTickCountP, Hook_emu::__GetTickCount, &ErrorCode ); 844 | 845 | if (Hooks_Informastion::Kernel32_GetTickCountID > 0 && ErrorCode == 0) 846 | { 847 | ColdHook_Service::ServiceRegisterHookInformation( HookDataS, Hooks_Informastion::Kernel32_GetTickCountID, &ErrorCode ); 848 | Hooks_Informastion::Kernel32_GetTickCountP = HookDataS->OriginalF; 849 | } 850 | } 851 | } 852 | } 853 | static void HideGetTickCount64() 854 | { 855 | Hooks_Informastion::Kernel32_GetTickCount64P = GetProcAddress( Hooks_Informastion::hKernel32, "GetTickCount64" ); 856 | 857 | if (Hooks_Config::Kernel32_GetTickCount64) 858 | { 859 | if (Hooks_Informastion::Kernel32_GetTickCount64P) 860 | { 861 | // Hook 862 | Hook_Info * HookDataS; 863 | int32_t ErrorCode = 0; 864 | 865 | Hooks_Informastion::Kernel32_GetTickCount64ID = ColdHook_Service::InitFunctionHookByAddress( &HookDataS, false, 866 | Hooks_Informastion::Kernel32_GetTickCount64P, Hook_emu::__GetTickCount64, &ErrorCode ); 867 | 868 | if (Hooks_Informastion::Kernel32_GetTickCount64ID > 0 && ErrorCode == 0) 869 | { 870 | ColdHook_Service::ServiceRegisterHookInformation( HookDataS, Hooks_Informastion::Kernel32_GetTickCount64ID, &ErrorCode ); 871 | Hooks_Informastion::Kernel32_GetTickCount64P = HookDataS->OriginalF; 872 | } 873 | } 874 | } 875 | } 876 | } 877 | namespace Hooks_Manager 878 | { 879 | // Init and ShutDown 880 | static bool IsInited = false; 881 | void Init( HMODULE hMain ) 882 | { 883 | if (!IsInited) 884 | { 885 | // ReadIniConfiguration first 886 | Hooks_Manager::InitInternalPath( hMain ); 887 | Hooks_Manager::ReadIni(); 888 | 889 | // Initialiizzation 890 | if (ColdHook_Service::ServiceGlobalInit( nullptr )) 891 | { 892 | Hooks_Informastion::hNtDll = GetModuleHandleA( "ntdll.dll" ); 893 | Hooks_Informastion::hKernel = GetModuleHandleA( "kernelbase.dll" ); 894 | 895 | if (Hooks_Informastion::hKernel == nullptr) 896 | { 897 | Hooks_Informastion::hKernel = GetModuleHandleA( "kernel32.dll" ); 898 | } 899 | 900 | Hooks_Informastion::hKernel32 = GetModuleHandleA( "kernel32.dll" ); 901 | 902 | // Store the current PID 903 | Hooks_Informastion::CurrentProcessID = GetCurrentProcessId(); 904 | Hooks_Manager::GetExplorerPID(); 905 | 906 | // Call hooking functions 907 | Hooks::HideAntiAntiAttach(); 908 | 909 | Hooks::HideProcessInformations(); 910 | Hooks::HideCloseHandle(); 911 | Hooks::HideDRx(); 912 | Hooks::HidePEB(); 913 | Hooks::HideQueryObject(); 914 | Hooks::HideQuerySystemInformation(); 915 | Hooks::HideSetInformationThread(); 916 | Hooks::HideSetInformationProcess(); 917 | Hooks::HideNtContinue(); 918 | Hooks::HideCreateThreadEx(); 919 | Hooks::HideExceptionDispatcher(); 920 | Hooks::HideYieldExecution(); 921 | Hooks::HideSetDebugFilterState(); 922 | Hooks::HideProcess32First(); 923 | Hooks::HideProcess32Next(); 924 | Hooks::HideGetTickCount64(); 925 | Hooks::HideGetTickCount(); 926 | 927 | Hook_emu::InitHookFunctionsVars(); 928 | IsInited = true; 929 | } 930 | } 931 | } 932 | void ShutDown() 933 | { 934 | return; 935 | } 936 | 937 | // Configuration 938 | static void ReadIni() 939 | { 940 | char INI[MAX_PATH] = { 0 }; 941 | strcpy( INI, ColdHidepath ); 942 | strcat( INI, "ColdHide.ini" ); 943 | 944 | Hooks_Config::HideWholePEB = GetPrivateProfileIntA( "PEB_Hook", "HideWholePEB", true, INI ) != FALSE; 945 | 946 | if (!Hooks_Config::HideWholePEB) 947 | { 948 | Hooks_Config::PEB_BeingDebugged = GetPrivateProfileIntA( "PEB_Hook", "BeingDebugged", true, INI ) != FALSE; 949 | Hooks_Config::PEB_NtGlobalFlag = GetPrivateProfileIntA( "PEB_Hook", "NtGlobalFlag", true, INI ) != FALSE; 950 | Hooks_Config::HeapFlags = GetPrivateProfileIntA( "PEB_Hook", "HeapFlags", true, INI ) != FALSE; 951 | } 952 | else 953 | { 954 | Hooks_Config::HideWholePEB = false; 955 | Hooks_Config::PEB_BeingDebugged = true; 956 | Hooks_Config::PEB_NtGlobalFlag = true; 957 | Hooks_Config::HeapFlags = true; 958 | } 959 | Hooks_Config::HideWholeDRx = GetPrivateProfileIntA( "Nt_DRx", "HideWholeDRx", true, INI ) != FALSE; 960 | Hooks_Config::FakeContextEmulation = GetPrivateProfileIntA( "Nt_DRx", "FakeContextEmulation", true, INI ) != FALSE; 961 | if (!Hooks_Config::HideWholeDRx) 962 | { 963 | Hooks_Config::DRx_ThreadContextRead = GetPrivateProfileIntA( "Nt_DRx", "NtGetContextThread", true, INI ) != FALSE; 964 | Hooks_Config::DRx_ThreadContextWrite = GetPrivateProfileIntA( "Nt_DRx", "NtSetContextThread", true, INI ) != FALSE; 965 | Hooks_Config::Nt_Continue = GetPrivateProfileIntA( "Nt_DRx", "NtContinue", true, INI ) != FALSE; 966 | Hooks_Config::Nt_KiUserExceptionDispatcher = GetPrivateProfileIntA( "Nt_DRx", "KiUserExceptionDispatcher", true, INI ) != FALSE; 967 | } 968 | else 969 | { 970 | Hooks_Config::HideWholeDRx = false; 971 | Hooks_Config::DRx_ThreadContextRead = true; 972 | Hooks_Config::DRx_ThreadContextWrite = true; 973 | Hooks_Config::Nt_Continue = true; 974 | Hooks_Config::Nt_KiUserExceptionDispatcher = true; 975 | } 976 | Hooks_Config::Anti_Anti_Attach = GetPrivateProfileIntA( "Additional", "Anti_Anti_Attach", false, INI ) != FALSE; 977 | 978 | Hooks_Config::Nt_QueryProcess = GetPrivateProfileIntA( "NTAPIs", "NtQueryInformationProcess", true, INI ) != FALSE; 979 | Hooks_Config::Nt_QuerySystem = GetPrivateProfileIntA( "NTAPIs", "NtQuerySystemInformation", true, INI ) != FALSE; 980 | Hooks_Config::Nt_SetThreadInformation = GetPrivateProfileIntA( "NTAPIs", "NtSetInformationThread", true, INI ) != FALSE; 981 | Hooks_Config::Nt_Close = GetPrivateProfileIntA( "NTAPIs", "NtClose", true, INI ) != FALSE; 982 | Hooks_Config::Nt_QueryObject = GetPrivateProfileIntA( "NTAPIs", "NtQueryObject", true, INI ) != FALSE; 983 | Hooks_Config::Nt_CreateThreadEx = GetPrivateProfileIntA( "NTAPIs", "NtCreateThreadEx", true, INI ) != FALSE; 984 | Hooks_Config::Nt_SetInformationProcess = GetPrivateProfileIntA( "NTAPIs", "NtSetInformationProcess", true, INI ) != FALSE; 985 | Hooks_Config::Nt_YieldExecution = GetPrivateProfileIntA( "NTAPIs", "NtYieldExecution", true, INI ) != FALSE; 986 | Hooks_Config::Nt_SetDebugFilterState = GetPrivateProfileIntA( "NTAPIs", "NtSetDebugFilterState", true, INI ) != FALSE; 987 | 988 | Hooks_Config::Kernel32_Process32First = GetPrivateProfileIntA( "WinAPIs", "Process32First", true, INI ) != FALSE; 989 | Hooks_Config::Kernel32_Process32Next = GetPrivateProfileIntA( "WinAPIs", "Process32Next", true, INI ) != FALSE; 990 | Hooks_Config::Kernel32_GetTickCount = GetPrivateProfileIntA( "WinAPIs", "GetTickCount", true, INI ) != FALSE; 991 | Hooks_Config::Kernel32_GetTickCount64 = GetPrivateProfileIntA( "WinAPIs", "GetTickCount64", true, INI ) != FALSE; 992 | } 993 | static void InitInternalPath( HMODULE hMain ) 994 | { 995 | size_t Length = GetModuleFileNameA( hMain, ColdHidepath, sizeof( ColdHidepath ) ); 996 | if (Length) 997 | { 998 | for (size_t i = Length; i > 0; i--) 999 | { 1000 | if (ColdHidepath[i] == '\\' || ColdHidepath[i] == '/') 1001 | { 1002 | memset( &ColdHidepath[i + 1], 0, Length - (i + 1) ); 1003 | break; 1004 | } 1005 | } 1006 | } 1007 | } 1008 | void GetExplorerPID() 1009 | { 1010 | // Get fake PID. 1011 | HANDLE hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ); 1012 | 1013 | if (hProcessSnap != INVALID_HANDLE_VALUE) 1014 | { 1015 | PROCESSENTRY32 pe32; 1016 | pe32.dwSize = sizeof( PROCESSENTRY32 ); 1017 | 1018 | if (Process32First( hProcessSnap, &pe32 )) 1019 | { 1020 | do 1021 | { 1022 | if (lstrcmp( pe32.szExeFile, L"explorer.exe" ) == 0) 1023 | { 1024 | Hooks_Informastion::FPPID = pe32.th32ProcessID; 1025 | break; 1026 | } 1027 | } while (Process32Next( hProcessSnap, &pe32 ) == TRUE); 1028 | CloseHandle( hProcessSnap ); 1029 | } 1030 | } 1031 | } 1032 | static std::vector ThreadDataID; 1033 | size_t GetOffsetByThreadID( DWORD ID ) 1034 | { 1035 | size_t offset = 0; 1036 | bool Save = true; 1037 | 1038 | for (auto iter = ThreadDataID.begin(); iter != ThreadDataID.end(); iter++, offset++) 1039 | { 1040 | DWORD CurId = *iter; 1041 | if (CurId == ID) 1042 | { 1043 | Save = false; 1044 | break; 1045 | } 1046 | } 1047 | 1048 | if (Save) 1049 | { 1050 | ThreadDataID.push_back( ID ); 1051 | } 1052 | return offset; 1053 | } 1054 | } -------------------------------------------------------------------------------- /src/hooks.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2020 Rat431 (https://github.com/Rat431). 3 | This software is under the MIT license, for more informations check the LICENSE file. 4 | */ 5 | 6 | #pragma once 7 | #include "hook_emus.h" 8 | #include "ColdHook/ColdHook.h" 9 | 10 | namespace Hooks_Informastion 11 | { 12 | extern DWORD CurrentProcessID; 13 | extern ULONG_PTR FPPID; 14 | 15 | // PEB. 16 | extern void * PEB_BeingDebuggedP; 17 | extern int32_t PEB_BeingDebuggedID; 18 | 19 | extern void * PEB_NtGlobalFlagP; 20 | extern int32_t PEB_NtGlobalFlagID; 21 | 22 | // HeapFlags 23 | extern void * FlagsHeapFlagsP; 24 | extern int32_t FlagsHeapFlagsID; 25 | 26 | // Some ntdll apis 27 | extern void * Nt_QueryProcessP; 28 | extern int32_t Nt_QueryProcessID; 29 | 30 | extern void * Nt_QuerySystemP; 31 | extern int32_t Nt_QuerySystemID; 32 | 33 | extern void * Nt_SetThreadInformationP; 34 | extern int32_t Nt_SetThreadInformationID; 35 | 36 | extern void * Nt_CloseP; 37 | extern int32_t Nt_CloseID; 38 | 39 | extern void * Nt_QueryObjectP; 40 | extern int32_t Nt_QueryObjectID; 41 | 42 | extern void * Nt_NtGetContextThreadP; 43 | extern int32_t Nt_NtGetContextThreadID; 44 | 45 | extern void * Nt_NtSetContextThreadP; 46 | extern int32_t Nt_NtSetContextThreadID; 47 | 48 | extern void * Nt_ContinueP; 49 | extern int32_t Nt_ContinueID; 50 | 51 | extern void * Nt_CreateThreadExP; 52 | extern int32_t Nt_CreateThreadExID; 53 | 54 | extern void * Nt_ExceptionDispatcherP; 55 | extern int32_t Nt_ExceptionDispatcherID; 56 | 57 | extern void * Nt_SetInformationProcessP; 58 | extern int32_t Nt_SetInformationProcessID; 59 | 60 | extern void * Nt_YieldExecutionP; 61 | extern int32_t Nt_YieldExecutionID; 62 | 63 | extern void * Nt_SetDebugFilterStateP; 64 | extern int32_t Nt_SetDebugFilterStateID; 65 | 66 | extern void * Kernel32_Process32FirstWP; 67 | extern int32_t Kernel32_Process32FirstWID; 68 | 69 | extern void * Kernel32_Process32NextWP; 70 | extern int32_t Kernel32_Process32NextWID; 71 | 72 | extern void * Kernel32_GetTickCountP; 73 | extern int32_t Kernel32_GetTickCountID; 74 | 75 | extern void * Kernel32_GetTickCount64P; 76 | extern int32_t Kernel32_GetTickCount64ID; 77 | } 78 | namespace Hooks_Config 79 | { 80 | // Hide PEB. 81 | extern bool HideWholePEB; 82 | extern bool PEB_BeingDebugged; 83 | extern bool PEB_NtGlobalFlag; 84 | 85 | // HeapFlags 86 | extern bool HeapFlags; 87 | 88 | // DRx 89 | extern bool HideWholeDRx; 90 | extern bool FakeContextEmulation; 91 | 92 | extern bool DRx_ThreadContextRead; 93 | extern bool DRx_ThreadContextWrite; 94 | extern bool Nt_Continue; 95 | extern bool Nt_KiUserExceptionDispatcher; 96 | 97 | // Anti attach 98 | extern bool Anti_Anti_Attach; 99 | 100 | // Some ntdll apis 101 | extern bool Nt_QueryProcess; 102 | extern bool Nt_QuerySystem; 103 | extern bool Nt_SetThreadInformation; 104 | extern bool Nt_Close; 105 | extern bool Nt_QueryObject; 106 | extern bool Nt_CreateThreadEx; 107 | extern bool Nt_SetInformationProcess; 108 | extern bool Nt_YieldExecution; 109 | extern bool Nt_SetDebugFilterState; 110 | 111 | extern bool Kernel32_Process32First; 112 | extern bool Kernel32_Process32Next; 113 | extern bool Kernel32_GetTickCount; 114 | extern bool Kernel32_GetTickCount64; 115 | } 116 | namespace Hooks 117 | { 118 | static void HidePEB(); 119 | static void HideDRx(); 120 | static void HideProcessInformations(); 121 | static void HideSetInformationThread(); 122 | static void HideQuerySystemInformation(); 123 | static void HideCloseHandle(); 124 | static void HideQueryObject(); 125 | static void HideSetInformationProcess(); 126 | static void HideNtContinue(); 127 | static void HideCreateThreadEx(); 128 | static void HideExceptionDispatcher(); 129 | static void HideYieldExecution(); 130 | static void HideSetDebugFilterState(); 131 | static void HideAntiAntiAttach(); 132 | 133 | static void HideProcess32First(); 134 | static void HideProcess32Next(); 135 | static void HideGetTickCount(); 136 | static void HideGetTickCount64(); 137 | } 138 | namespace Hooks_Manager 139 | { 140 | // Init and ShutDown 141 | void Init( HMODULE hMain ); 142 | void ShutDown(); 143 | 144 | // Configuration 145 | static void ReadIni(); 146 | static void InitInternalPath( HMODULE hMain ); 147 | 148 | void GetExplorerPID(); 149 | size_t GetOffsetByThreadID( DWORD ID ); 150 | } -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2020 Rat431 (https://github.com/Rat431). 3 | This software is under the MIT license, for more informations check the LICENSE file. 4 | */ 5 | 6 | #include "hooks.h" 7 | 8 | // small export 9 | extern "C" _declspec(dllexport) void CHide_Bridge() 10 | { 11 | return; 12 | } 13 | 14 | BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) 15 | { 16 | if (ul_reason_for_call == DLL_PROCESS_ATTACH) 17 | { 18 | Hooks_Manager::Init( hModule ); 19 | } 20 | else if (ul_reason_for_call == DLL_PROCESS_DETACH) 21 | { 22 | Hooks_Manager::ShutDown(); 23 | } 24 | return TRUE; 25 | } 26 | 27 | --------------------------------------------------------------------------------