mirror of
https://github.com/mrexodia/TitanHide
synced 2026-08-13 04:23:04 -04:00
539 lines
20 KiB
C++
539 lines
20 KiB
C++
#include <windows.h>
|
|
#include <stdio.h>
|
|
#include <Subauth.h>
|
|
#include "..\TitanHide\TitanHide.h"
|
|
|
|
//Thanks to:
|
|
//http://www.codeproject.com/Articles/30815/An-Anti-Reverse-Engineering-Guide
|
|
//http://pferrie.host22.com/papers/antidebug.pdf
|
|
//http://resources.infosecinstitute.com/anti-debugging-detecting-system-debugger/
|
|
|
|
bool CheckProcessDebugFlags()
|
|
{
|
|
// Much easier in ASM but C/C++ looks so much better
|
|
typedef int (WINAPI * pNtQueryInformationProcess)
|
|
(HANDLE, UINT, PVOID, ULONG, PULONG);
|
|
|
|
DWORD NoDebugInherit = 0;
|
|
int Status;
|
|
|
|
// Get NtQueryInformationProcess
|
|
pNtQueryInformationProcess NtQIP = (pNtQueryInformationProcess)
|
|
GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")),
|
|
"NtQueryInformationProcess");
|
|
|
|
|
|
Status = NtQIP(GetCurrentProcess(),
|
|
0x1f, // ProcessDebugFlags
|
|
&NoDebugInherit, sizeof(NoDebugInherit), NULL);
|
|
|
|
if(Status != 0x00000000)
|
|
{
|
|
printf("NtQueryInformationProcess failed with %X\n", Status);
|
|
return false;
|
|
}
|
|
|
|
if(NoDebugInherit == FALSE)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
bool CheckProcessDebugPort()
|
|
{
|
|
// Much easier in ASM but C/C++ looks so much better
|
|
typedef int (WINAPI * pNtQueryInformationProcess)
|
|
(HANDLE, UINT, PVOID, ULONG, PULONG);
|
|
|
|
DWORD_PTR DebugPort = 0;
|
|
ULONG ReturnSize = 0;
|
|
int Status;
|
|
|
|
// Get NtQueryInformationProcess
|
|
pNtQueryInformationProcess NtQIP = (pNtQueryInformationProcess)
|
|
GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")),
|
|
"NtQueryInformationProcess");
|
|
|
|
Status = NtQIP(GetCurrentProcess(),
|
|
0x7, // ProcessDebugPort
|
|
&DebugPort, sizeof(DebugPort), &ReturnSize);
|
|
|
|
if(Status != 0x00000000)
|
|
{
|
|
printf("NtQueryInformationProcess failed with %X, %u\n", Status, ReturnSize);
|
|
return false;
|
|
}
|
|
|
|
if(DebugPort)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|
|
|
|
bool CheckProcessDebugObjectHandle()
|
|
{
|
|
// Much easier in ASM but C/C++ looks so much better
|
|
typedef int (WINAPI * pNtQueryInformationProcess)
|
|
(HANDLE, UINT, PVOID, ULONG, PULONG);
|
|
|
|
DWORD_PTR DebugHandle = 0;
|
|
int Status;
|
|
ULONG ReturnSize = 0;
|
|
|
|
// Get NtQueryInformationProcess
|
|
pNtQueryInformationProcess NtQIP = (pNtQueryInformationProcess)
|
|
GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")),
|
|
"NtQueryInformationProcess");
|
|
|
|
Status = NtQIP(GetCurrentProcess(),
|
|
30, // ProcessDebugHandle
|
|
&DebugHandle, sizeof(DebugHandle), &ReturnSize);
|
|
|
|
if(Status != 0x00000000)
|
|
{
|
|
if(Status != 0xC0000353) //STATUS_PORT_NOT_SET
|
|
printf("NtQueryInformationProcess failed with %X, %u\n", Status, ReturnSize);
|
|
return false;
|
|
}
|
|
|
|
|
|
if(DebugHandle)
|
|
{
|
|
CloseHandle((HANDLE)DebugHandle);
|
|
return true;
|
|
}
|
|
|
|
else
|
|
return false;
|
|
}
|
|
|
|
bool HideFromDebugger()
|
|
{
|
|
typedef NTSTATUS(NTAPI * NT_SET_INFORMATION_THREAD)(
|
|
IN HANDLE ThreadHandle,
|
|
IN ULONG ThreadInformationClass,
|
|
IN PVOID ThreadInformation,
|
|
IN ULONG ThreadInformationLength
|
|
);
|
|
NT_SET_INFORMATION_THREAD NtSIT = (NT_SET_INFORMATION_THREAD)
|
|
GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")),
|
|
"NtSetInformationThread");
|
|
return NT_SUCCESS(NtSIT(GetCurrentThread(),
|
|
0x11, //ThreadHideFromDebugger
|
|
0,
|
|
0));
|
|
}
|
|
|
|
typedef struct _OBJECT_TYPE_INFORMATION
|
|
{
|
|
UNICODE_STRING TypeName;
|
|
ULONG TotalNumberOfObjects;
|
|
ULONG TotalNumberOfHandles;
|
|
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
|
|
|
|
typedef struct _OBJECT_ALL_INFORMATION
|
|
{
|
|
ULONG NumberOfObjects;
|
|
OBJECT_TYPE_INFORMATION ObjectTypeInformation[1];
|
|
} OBJECT_ALL_INFORMATION, *POBJECT_ALL_INFORMATION;
|
|
|
|
typedef enum _OBJECT_INFORMATION_CLASS
|
|
{
|
|
ObjectBasicInformation,
|
|
ObjectNameInformation,
|
|
ObjectTypeInformation,
|
|
ObjectTypesInformation,
|
|
ObjectDataInformation
|
|
} OBJECT_INFORMATION_CLASS, *POBJECT_INFORMATION_CLASS;
|
|
|
|
typedef struct _TEST_OBJECT_ATTRIBUTES
|
|
{
|
|
ULONG Length;
|
|
HANDLE RootDirectory;
|
|
PUNICODE_STRING ObjectName;
|
|
ULONG Attributes;
|
|
PVOID SecurityDescriptor;
|
|
PVOID SecurityQualityOfService;
|
|
} TEST_OBJECT_ATTRIBUTES, *PTEST_OBJECT_ATTRIBUTES;
|
|
|
|
bool CheckObjectTypeInformation()
|
|
{
|
|
typedef NTSTATUS(NTAPI * pNtCreateDebugObject)(PHANDLE, ULONG, PTEST_OBJECT_ATTRIBUTES, ULONG);
|
|
typedef NTSTATUS(NTAPI * pNtQueryObject)(HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, PULONG);
|
|
|
|
pNtCreateDebugObject NtCDO = (pNtCreateDebugObject)GetProcAddress(
|
|
GetModuleHandle(TEXT("ntdll.dll")),
|
|
"NtCreateDebugObject");
|
|
pNtQueryObject NtQO = (pNtQueryObject)GetProcAddress(
|
|
GetModuleHandle(TEXT("ntdll.dll")),
|
|
"NtQueryObject");
|
|
if(NtCDO == NULL || NtQO == NULL)
|
|
return false;
|
|
|
|
TEST_OBJECT_ATTRIBUTES ObjectAttributes = { sizeof(TEST_OBJECT_ATTRIBUTES) };
|
|
HANDLE DebugObjectHandle = NULL;
|
|
NTSTATUS Status = NtCDO(&DebugObjectHandle, 0x0008, &ObjectAttributes, 0);
|
|
if(!NT_SUCCESS(Status))
|
|
return false;
|
|
|
|
// Preserve every handle owned by the protected process, not merely one.
|
|
// The active debugger may independently hold multiple handles to its own
|
|
// debug object, all of which should be removed from the reported total.
|
|
HANDLE DuplicateHandles[2] = {};
|
|
ULONG OwnedHandleCount = 1;
|
|
for(HANDLE& DuplicatedHandle : DuplicateHandles)
|
|
{
|
|
if(DuplicateHandle(
|
|
GetCurrentProcess(),
|
|
DebugObjectHandle,
|
|
GetCurrentProcess(),
|
|
&DuplicatedHandle,
|
|
0,
|
|
FALSE,
|
|
DUPLICATE_SAME_ACCESS))
|
|
{
|
|
OwnedHandleCount++;
|
|
}
|
|
}
|
|
|
|
bool Detected = false;
|
|
ULONG RequiredLength = 0;
|
|
Status = NtQO(DebugObjectHandle, ObjectTypeInformation, NULL, 0, &RequiredLength);
|
|
if(Status != (NTSTATUS)0xC0000004L || RequiredLength < sizeof(OBJECT_TYPE_INFORMATION)) // STATUS_INFO_LENGTH_MISMATCH
|
|
{
|
|
Detected = true;
|
|
}
|
|
else
|
|
{
|
|
OBJECT_TYPE_INFORMATION* TypeInformation = (OBJECT_TYPE_INFORMATION*)HeapAlloc(
|
|
GetProcessHeap(), HEAP_ZERO_MEMORY, RequiredLength);
|
|
if(TypeInformation == NULL)
|
|
{
|
|
Detected = true;
|
|
}
|
|
else
|
|
{
|
|
Status = NtQO(DebugObjectHandle, ObjectTypeInformation, TypeInformation, RequiredLength, NULL);
|
|
if(!NT_SUCCESS(Status) ||
|
|
TypeInformation->TotalNumberOfObjects == 0 ||
|
|
TypeInformation->TotalNumberOfHandles < OwnedHandleCount)
|
|
{
|
|
Detected = true;
|
|
}
|
|
|
|
// VMProtect 3.9.5+ overlaps ReturnLength with TypeName.Buffer.
|
|
Status = NtQO(DebugObjectHandle,
|
|
ObjectTypeInformation,
|
|
TypeInformation,
|
|
RequiredLength,
|
|
(PULONG)&TypeInformation->TypeName.Buffer);
|
|
if(!NT_SUCCESS(Status) ||
|
|
*(PULONG)&TypeInformation->TypeName.Buffer != RequiredLength ||
|
|
TypeInformation->TotalNumberOfObjects == 0 ||
|
|
TypeInformation->TotalNumberOfHandles < OwnedHandleCount)
|
|
{
|
|
Detected = true;
|
|
}
|
|
|
|
HeapFree(GetProcessHeap(), 0, TypeInformation);
|
|
}
|
|
}
|
|
|
|
for(HANDLE DuplicatedHandle : DuplicateHandles)
|
|
{
|
|
if(DuplicatedHandle != NULL)
|
|
CloseHandle(DuplicatedHandle);
|
|
}
|
|
CloseHandle(DebugObjectHandle);
|
|
return Detected;
|
|
}
|
|
|
|
// ObjectListCheck uses NtQueryObject to check the environments
|
|
// list of objects and more specifically for the number of
|
|
// debug objects. This function can cause an exception (although rarely)
|
|
// so either surround it in a try catch or __try __except block
|
|
// but that shouldn't happen unless one tinkers with the function
|
|
bool CheckObjectList()
|
|
{
|
|
__try
|
|
{
|
|
typedef NTSTATUS(NTAPI * pNtQueryObject)(HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, PULONG);
|
|
|
|
POBJECT_ALL_INFORMATION pObjectAllInfo = NULL;
|
|
void* pMemory = NULL;
|
|
NTSTATUS Status;
|
|
ULONG Size = 0;
|
|
|
|
// Get NtQueryObject
|
|
pNtQueryObject NtQO = (pNtQueryObject)GetProcAddress(
|
|
GetModuleHandle(TEXT("ntdll.dll")),
|
|
"NtQueryObject");
|
|
|
|
// Get the size of the list
|
|
Status = NtQO(NULL, ObjectTypesInformation, //ObjectAllTypesInformation
|
|
&Size, sizeof(ULONG), &Size);
|
|
|
|
// Allocate room for the list
|
|
pMemory = VirtualAlloc(NULL, SIZE_T(Size), MEM_RESERVE | MEM_COMMIT,
|
|
PAGE_READWRITE);
|
|
|
|
if(pMemory == NULL)
|
|
return false;
|
|
|
|
// Now we can actually retrieve the list
|
|
Status = NtQO(GetCurrentProcess(), ObjectTypesInformation, pMemory, Size, NULL);
|
|
|
|
// Status != STATUS_SUCCESS
|
|
if(Status != STATUS_SUCCESS)
|
|
{
|
|
VirtualFree(pMemory, 0, MEM_RELEASE);
|
|
return false;
|
|
}
|
|
|
|
// We have the information we need
|
|
pObjectAllInfo = (POBJECT_ALL_INFORMATION)pMemory;
|
|
|
|
unsigned char* pObjInfoLocation = (unsigned char*)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
|
|
wchar_t DebugObject[] = L"DebugObject";
|
|
auto DebugObjectLength = wcslen(DebugObject) * sizeof(wchar_t);
|
|
if(pObjectTypeInfo->TypeName.Length == DebugObjectLength && !memcmp(pObjectTypeInfo->TypeName.Buffer, DebugObject, DebugObjectLength)) //UNICODE_STRING is not NULL-terminated (pointed to by deepzero!)
|
|
{
|
|
// Are there any objects?
|
|
if(pObjectTypeInfo->TotalNumberOfObjects || pObjectTypeInfo->TotalNumberOfHandles)
|
|
{
|
|
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;
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
puts("exception!");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
enum PROCESSINFOCLASS
|
|
{
|
|
ProcessBasicInformation = 0, // 0, q: PROCESS_BASIC_INFORMATION, PROCESS_EXTENDED_BASIC_INFORMATION
|
|
ProcessQuotaLimits, // qs: QUOTA_LIMITS, QUOTA_LIMITS_EX
|
|
ProcessIoCounters, // q: IO_COUNTERS
|
|
ProcessVmCounters, // q: VM_COUNTERS, VM_COUNTERS_EX
|
|
ProcessTimes, // q: KERNEL_USER_TIMES
|
|
ProcessBasePriority, // s: KPRIORITY
|
|
ProcessRaisePriority, // s: ULONG
|
|
ProcessDebugPort, // q: HANDLE
|
|
ProcessExceptionPort, // s: HANDLE
|
|
ProcessAccessToken, // s: PROCESS_ACCESS_TOKEN
|
|
ProcessLdtInformation, // 10
|
|
ProcessLdtSize,
|
|
ProcessDefaultHardErrorMode, // qs: ULONG
|
|
ProcessIoPortHandlers, // (kernel-mode only)
|
|
ProcessPooledUsageAndLimits, // q: POOLED_USAGE_AND_LIMITS
|
|
ProcessWorkingSetWatch, // q: PROCESS_WS_WATCH_INFORMATION[]; s: void
|
|
ProcessUserModeIOPL,
|
|
ProcessEnableAlignmentFaultFixup, // s: BOOLEAN
|
|
ProcessPriorityClass, // qs: PROCESS_PRIORITY_CLASS
|
|
ProcessWx86Information,
|
|
ProcessHandleCount, // 20, q: ULONG, PROCESS_HANDLE_INFORMATION
|
|
ProcessAffinityMask, // s: KAFFINITY
|
|
ProcessPriorityBoost, // qs: ULONG
|
|
ProcessDeviceMap, // qs: PROCESS_DEVICEMAP_INFORMATION, PROCESS_DEVICEMAP_INFORMATION_EX
|
|
ProcessSessionInformation, // q: PROCESS_SESSION_INFORMATION
|
|
ProcessForegroundInformation, // s: PROCESS_FOREGROUND_BACKGROUND
|
|
ProcessWow64Information, // q: ULONG_PTR
|
|
ProcessImageFileName, // q: UNICODE_STRING
|
|
ProcessLUIDDeviceMapsEnabled, // q: ULONG
|
|
ProcessBreakOnTermination, // qs: ULONG
|
|
ProcessDebugObjectHandle, // 30, q: HANDLE
|
|
ProcessDebugFlags, // qs: ULONG
|
|
ProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: size 0 disables, otherwise enables
|
|
ProcessIoPriority, // qs: ULONG
|
|
ProcessExecuteFlags, // qs: ULONG
|
|
ProcessResourceManagement,
|
|
ProcessCookie, // q: ULONG
|
|
ProcessImageInformation, // q: SECTION_IMAGE_INFORMATION
|
|
ProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION
|
|
ProcessPagePriority, // q: ULONG
|
|
ProcessInstrumentationCallback, // 40
|
|
ProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX
|
|
ProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[]
|
|
ProcessImageFileNameWin32, // q: UNICODE_STRING
|
|
ProcessImageFileMapping, // q: HANDLE (input)
|
|
ProcessAffinityUpdateMode, // qs: PROCESS_AFFINITY_UPDATE_MODE
|
|
ProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODE
|
|
ProcessGroupInformation, // q: USHORT[]
|
|
ProcessTokenVirtualizationEnabled, // s: ULONG
|
|
ProcessConsoleHostProcess, // q: ULONG_PTR
|
|
ProcessWindowInformation, // 50, q: PROCESS_WINDOW_INFORMATION
|
|
ProcessHandleInformation, // q: PROCESS_HANDLE_SNAPSHOT_INFORMATION // since WIN8
|
|
ProcessMitigationPolicy, // s: PROCESS_MITIGATION_POLICY_INFORMATION
|
|
ProcessDynamicFunctionTableInformation,
|
|
ProcessHandleCheckingMode,
|
|
ProcessKeepAliveCount, // q: PROCESS_KEEPALIVE_COUNT_INFORMATION
|
|
ProcessRevokeFileHandles, // s: PROCESS_REVOKE_FILE_HANDLES_INFORMATION
|
|
MaxProcessInfoClass
|
|
};
|
|
|
|
bool NTAPI NtSetInformationProcess(
|
|
IN HANDLE ProcessHandle,
|
|
IN PROCESSINFOCLASS ProcessInformationClass,
|
|
IN PVOID ProcessInformation,
|
|
IN ULONG ProcessInformationLength
|
|
)
|
|
{
|
|
typedef NTSTATUS(NTAPI * NTSETINFORMATIONPROCESS)
|
|
(
|
|
IN HANDLE ProcessHandle,
|
|
IN PROCESSINFOCLASS ProcessInformationClass,
|
|
IN PVOID ProcessInformation,
|
|
IN ULONG ProcessInformationLength
|
|
);
|
|
static NTSETINFORMATIONPROCESS NtSIP = 0;
|
|
if(!NtSIP)
|
|
{
|
|
NtSIP = (NTSETINFORMATIONPROCESS)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtSetInformationProcess");
|
|
if(!NtSIP)
|
|
return false;
|
|
}
|
|
return NT_SUCCESS(NtSIP(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength));
|
|
}
|
|
|
|
bool CheckSystemDebugger()
|
|
{
|
|
typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION
|
|
{
|
|
BOOLEAN DebuggerEnabled;
|
|
BOOLEAN DebuggerNotPresent;
|
|
} SYSTEM_KERNEL_DEBUGGER_INFORMATION, *PSYSTEM_KERNEL_DEBUGGER_INFORMATION;
|
|
enum SYSTEM_INFORMATION_CLASS { SystemKernelDebuggerInformation = 35 };
|
|
typedef NTSTATUS(__stdcall * ZW_QUERY_SYSTEM_INFORMATION)(IN SYSTEM_INFORMATION_CLASS SystemInformationClass, IN OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength);
|
|
ZW_QUERY_SYSTEM_INFORMATION ZwQuerySystemInformation;
|
|
SYSTEM_KERNEL_DEBUGGER_INFORMATION Info;
|
|
ZwQuerySystemInformation = (ZW_QUERY_SYSTEM_INFORMATION)GetProcAddress(GetModuleHandleA("ntdll.dll"), "ZwQuerySystemInformation");
|
|
if(ZwQuerySystemInformation && NT_SUCCESS(ZwQuerySystemInformation(SystemKernelDebuggerInformation, &Info, sizeof(Info), NULL)))
|
|
{
|
|
if(Info.DebuggerEnabled || !Info.DebuggerNotPresent)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool CheckSystemDebugControl()
|
|
{
|
|
enum SYSDBG_COMMAND { SysDbgQueryModuleInformation = 0 };
|
|
typedef NTSTATUS(__stdcall * ZW_SYSTEM_DEBUG_CONTROL)(IN SYSDBG_COMMAND Command, IN PVOID InputBuffer OPTIONAL, IN ULONG InputBufferLength, OUT PVOID OutputBuffer OPTIONAL, IN ULONG OutputBufferLength, OUT PULONG ReturnLength OPTIONAL);
|
|
static const NTSTATUS STATUS_DEBUGGER_INACTIVE = (NTSTATUS)0xC0000354L;
|
|
ZW_SYSTEM_DEBUG_CONTROL ZwSystemDebugControl = (ZW_SYSTEM_DEBUG_CONTROL)GetProcAddress(GetModuleHandleA("ntdll.dll"), "ZwSystemDebugControl");
|
|
if(ZwSystemDebugControl == NULL)
|
|
{
|
|
return false;
|
|
}
|
|
return ZwSystemDebugControl(SysDbgQueryModuleInformation, NULL, 0, NULL, 0, NULL) != STATUS_DEBUGGER_INACTIVE;
|
|
}
|
|
|
|
bool CheckNtClose()
|
|
{
|
|
__try
|
|
{
|
|
CloseHandle((HANDLE)0x1234);
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
char title[256] = "";
|
|
sprintf_s(title, "pid: %d", (int)GetCurrentProcessId());
|
|
SetConsoleTitleA(title);
|
|
|
|
BOOL IsWow64 = FALSE;
|
|
#ifndef _WIN64
|
|
IsWow64Process(GetCurrentProcess(), &IsWow64);
|
|
#endif
|
|
|
|
while(1)
|
|
{
|
|
printf("ProcessDebugFlags: %d\n", CheckProcessDebugFlags());
|
|
printf("ProcessDebugPort: %d\n", CheckProcessDebugPort());
|
|
printf("ProcessDebugObjectHandle: %d\n", CheckProcessDebugObjectHandle());
|
|
printf("NtQueryObject: %d\n", CheckObjectList());
|
|
printf("NtQueryObjectType: %d\n", CheckObjectTypeInformation());
|
|
printf("CheckSystemDebugger: %d\n", CheckSystemDebugger());
|
|
if(!IsWow64) // This syscall is not implemented in wow64.dll
|
|
printf("SystemDebugControl: %d\n", CheckSystemDebugControl());
|
|
printf("CheckNtClose: %d\n", CheckNtClose());
|
|
//printf("ThreadHideFromDebugger: %d\n", HideFromDebugger());
|
|
puts("");
|
|
if(argc > 1)
|
|
break;
|
|
Sleep(1000);
|
|
}
|
|
/*int pid=0;
|
|
printf("pid: ");
|
|
scanf("%d", &pid);
|
|
if(OpenProcess(PROCESS_ALL_ACCESS, false, pid))
|
|
puts("OpenProcess OK!");
|
|
else
|
|
puts("OpenProcess FAILED...");
|
|
printf("%u\n", GetCurrentProcessId());*/
|
|
/*HANDLE hDevice=CreateFileA("\\\\.\\TitanHide", GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
|
|
if(hDevice==INVALID_HANDLE_VALUE)
|
|
puts("invalid handle...");
|
|
else
|
|
{
|
|
puts("handle ok!");
|
|
printf("pid: ");
|
|
ULONG pid=0;
|
|
scanf("%d", &pid);
|
|
DWORD written=0;
|
|
HIDE_INFO HideInfo;
|
|
HideInfo.Pid=pid;
|
|
HideInfo.Arg=0;
|
|
HideInfo.Command=HidePid;
|
|
HideInfo.Type=HideProcessDebugFlags|HideProcessDebugPort|HideProcessDebugObjectHandle|HideDebugObject;
|
|
WriteFile(hDevice, &HideInfo, sizeof(HIDE_INFO), &written, 0);
|
|
CloseHandle(hDevice);
|
|
}
|
|
system("pause");*/
|
|
return 0;
|
|
}
|