反调试 - NtQueryInformationProcess(ProcessDebugPort,ProcessDebugFlags,ProcessDebugObjectHandle)

NtQueryInformationProcess 是微软 未公开 的一个 API,嗯,这个反调试的方法有一个特点就是 能过吾爱破解版OD! ,其他版本的OD没有尝试,但相信这种反调试手法可以检测大部分的第三方OD。
在这里插入图片描述
首先需要知道的几点:

// NtQueryInformationProcess 函数原型
__kernel_entry NTSTATUS NtQueryInformationProcess(
  IN HANDLE           ProcessHandle,				// 进程句柄
  IN PROCESSINFOCLASS ProcessInformationClass,		// 检索的进程信息类型
  OUT PVOID           ProcessInformation,			// 接收进程信息的缓冲区指针
  IN ULONG            ProcessInformationLength,		// 缓冲区指针大小
  OUT PULONG          ReturnLength					// 实际接收的进程信息大小
);

// PROCESSINFOCLASS 结构体原型(别问我这都啥意思,我也不知道 /手动滑稽)
typedef enum _PROCESSINFOCLASS
{
    ProcessBasicInformation, 					// 0x0
    ProcessQuotaLimits, 
    ProcessIoCounters, 
    ProcessVmCounters, 
    ProcessTimes, 
    ProcessBasePriority, 
    ProcessRaisePriority,
    ProcessDebugPort,							// 0x7
    ProcessExceptionPort, 
    ProcessAccessToken, 
    ProcessLdtInformation, 
    ProcessLdtSize, 
    ProcessDefaultHardErrorMode, 
    ProcessIoPortHandlers, 
    ProcessPooledUsageAndLimits, 
    ProcessWorkingSetWatch,
    ProcessUserModeIOPL,
    ProcessEnableAlignmentFaultFixup, 
    ProcessPriorityClass, 
    ProcessWx86Information,
    ProcessHandleCount, 
    ProcessAffinityMask, 
    ProcessPriorityBoost, 
    ProcessDeviceMap, 
    ProcessSessionInformation, 
    ProcessForegroundInformation,
    ProcessWow64Information, 					// 0x1A
    ProcessImageFileName, 						// 0x1B
    ProcessLUIDDeviceMapsEnabled, 
    ProcessBreakOnTermination, 
    ProcessDebugObjectHandle,					// 0x1E
    ProcessDebugFlags, 							// 0x1F
    ProcessHandleTracing, 
    ProcessIoPriority, 
    ProcessExecuteFlags, 
    ProcessResourceManagement, 
    ProcessCookie, 
    ProcessImageInformation, 
    ProcessCycleTime, 
    ProcessPagePriority, 
    ProcessInstrumentationCallback, 
    ProcessThreadStackAllocation, 
    ProcessWorkingSetWatchEx,
    ProcessImageFileNameWin32, 
    ProcessImageFileMapping, 
    ProcessAffinityUpdateMode, 
    ProcessMemoryAllocationMode, 
    ProcessGroupInformation,
    ProcessTokenVirtualizationEnabled, 
    ProcessConsoleHostProcess, 
    ProcessWindowInformation, 
    ProcessHandleInformation,
    ProcessMitigationPolicy,
    ProcessDynamicFunctionTableInformation,
    ProcessHandleCheckingMode,
    ProcessKeepAliveCount,
    ProcessRevokeFileHandles,
    ProcessWorkingSetControl,
    ProcessHandleTable, 
    ProcessCheckStackExtentsMode,
    ProcessCommandLineInformation,
    ProcessProtectionInformation,
    ProcessMemoryExhaustion,
    ProcessFaultInformation, 
    ProcessTelemetryIdInformation, 
    ProcessCommitReleaseInformation, 
    ProcessDefaultCpuSetsInformation,
    ProcessAllowedCpuSetsInformation,
    ProcessSubsystemProcess,
    ProcessJobMemoryInformation, 
    ProcessInPrivate, 
    ProcessRaiseUMExceptionOnInvalidHandleClose, 
    ProcessIumChallengeResponse,
    ProcessChildProcessInformation, 
    ProcessHighGraphicsPriorityInformation,
    ProcessSubsystemInformation, 
    ProcessEnergyValues, 
    ProcessActivityThrottleState, 
    ProcessActivityThrottlePolicy,
    ProcessWin32kSyscallFilterInformation,
    ProcessDisableSystemAllowedCpuSets, 
    ProcessWakeInformation,
    ProcessEnergyTrackingState,
    ProcessManageWritesToExecutableMemory,REDSTONE3
    ProcessCaptureTrustletLiveDump,
    ProcessTelemetryCoverage,
    ProcessEnclaveInformation,
    ProcessEnableReadWriteVmLogging, 
    ProcessUptimeInformation,
    ProcessImageSection,
    ProcessDebugAuthInformation, 
    ProcessSystemResourceManagement,
    ProcessSequenceNumber,
    ProcessLoaderDetour,
    ProcessSecurityDomainInformation, 
    ProcessCombineSecurityDomainsInformation, 
    ProcessEnableLogging, 
    ProcessLeapSecondInformation,
    ProcessFiberShadowStackAllocation,
    ProcessFreeFiberShadowStackAllocation,
    MaxProcessInfoClass
} PROCESSINFOCLASS;

_PROCESSINFOCLASS → ProcessDebugPort:

进程处于被调试状态时,ProcessDebugPort = 0xffffffff

有调试器时:
在这里插入图片描述没有调试器时:
在这里插入图片描述
参考代码:

#include "stdafx.h"

#include <iostream>
#include <windows.h>
#include <winternl.h>

#pragma region 依赖 

typedef NTSTATUS(NTAPI *pfnNtQueryInformationProcess)(
    _In_      HANDLE           ProcessHandle,
    _In_      UINT             ProcessInformationClass,
    _Out_     PVOID            ProcessInformation,
    _In_      ULONG            ProcessInformationLength,
    _Out_opt_ PULONG           ReturnLength
);

#pragma endregion

int _tmain(int argc, _TCHAR* argv[])
{
	pfnNtQueryInformationProcess NtQueryInformationProcess = NULL;	// 存放 ntdll 中 NtQueryInformationProcess 函数地址
    NTSTATUS status;												// NTSTATUS 错误代码,0:执行成功
    DWORD isDebuggerPresent = -1;									// 如果当前被调试,则 = ffffffff
    HMODULE hNtDll = LoadLibrary(TEXT("ntdll.dll"));				// ntdll 模块句柄

	// ntdll 加载成功
	if(hNtDll){
		// 取 NtQueryInformationProcess 函数地址
		NtQueryInformationProcess = (pfnNtQueryInformationProcess)GetProcAddress(hNtDll, "NtQueryInformationProcess");
		
		// 取地址成功
		if (NtQueryInformationProcess){
			// NtQueryInformationProcess 检测调试器
			status = NtQueryInformationProcess(
                GetCurrentProcess(),			// 进程句柄
                0x7,							// 要检索的进程信息类型,ProcessDebugPort:调试器端口号
                &isDebuggerPresent,				// 接收进程信息的缓冲区指针
                sizeof(DWORD),					// 缓冲区大小
                NULL							// 实际返回进程信息的大小
				);

			// NtQueryInformationProcess 执行成功
			if(status == 0 && isDebuggerPresent != 0){
				// 输出
				std::cout << "status = " << status << std::endl;
				std::cout << "isDebuggerPresent = " << std::hex << isDebuggerPresent << std::endl;
				std::cout << "检测到调试器" << std::endl;
				
				getchar();
				return 0;
			}
		}
	}

	// 输出
	std::cout << "status = " << status << std::endl;
	std::cout << "isDebuggerPresent = " << std::hex << isDebuggerPresent << std::endl;
	std::cout << "没有发现调试器" << std::endl;

	getchar();
	return 0;
}

_PROCESSINFOCLASS → ProcessDebugObjectHandle:

ProcessDebugObjectHandle = 调试对象句柄

有调试器时:
在这里插入图片描述
没有调试器时:
在这里插入图片描述
代码:

// 只需要把 NtQueryInformationProcess() 中的 0x7 改成 0x1E

_PROCESSINFOCLASS → ProcessDebugFlags:

调试状态:ProcessDebugFlags = 0,非调试状态 ProcessDebugFlags = 1

有调试器时:
在这里插入图片描述

没有调试器时:
在这里插入图片描述
代码:

// 1.把 NtQueryInformationProcess() 中的 0x7 改成 0x1F
// 2.把 if(status == 0 && isDebuggerPresent != 0) 判断改为 if(status == 0 && isDebuggerPresent == 0)

就这些了,_PROCESSINFOCLASS 结构体力有很多成员查不到意思,如果哪个老哥知道,希望告知,先谢过啦 !!

在这里插入图片描述

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
## Features ### Anti-debugging attacks - IsDebuggerPresent - CheckRemoteDebuggerPresent - Process Environement Block (BeingDebugged) - Process Environement Block (NtGlobalFlag) - ProcessHeap (Flags) - ProcessHeap (ForceFlags) - NtQueryInformationProcess (ProcessDebugPort) - NtQueryInformationProcess (ProcessDebugFlags) - NtQueryInformationProcess (ProcessDebugObject) - NtSetInformationThread (HideThreadFromDebugger) - NtQueryObject (ObjectTypeInformation) - NtQueryObject (ObjectAllTypesInformation) - CloseHanlde (NtClose) Invalide Handle - SetHandleInformation (Protected Handle) - UnhandledExceptionFilter - OutputDebugString (GetLastError()) - Hardware Breakpoints (SEH / GetThreadContext) - Software Breakpoints (INT3 / 0xCC) - Memory Breakpoints (PAGE_GUARD) - Interrupt 0x2d - Interrupt 1 - Parent Process (Explorer.exe) - SeDebugPrivilege (Csrss.exe) - NtYieldExecution / SwitchToThread - TLS callbacks ### Anti-Dumping - Erase PE header from memory - SizeOfImage ### Timing Attacks [Anti-Sandbox] - RDTSC (with CPUID to force a VM Exit) - RDTSC (Locky version with GetProcessHeap & CloseHandle) - Sleep -> SleepEx -> NtDelayExecution - Sleep (in a loop a small delay) - Sleep and check if time was accelerated (GetTickCount) - SetTimer (Standard Windows Timers) - timeSetEvent (Multimedia Timers) - WaitForSingleObject -> WaitForSingleObjectEx -> NtWaitForSingleObject - WaitForMultipleObjects -> WaitForMultipleObjectsEx -> NtWaitForMultipleObjects (todo) - IcmpSendEcho (CCleaner Malware) - CreateWaitableTimer (todo) - CreateTimerQueueTimer (todo) - Big crypto loops (todo) ### Human Interaction / Generic [Anti-Sandbox] - Mouse movement - Total Physical memory (GlobalMemoryStatusEx) - Disk size using DeviceIoControl (IOCTL_DISK_GET_LENGTH_INFO) - Disk size using GetDiskFreeSpaceEx (TotalNumberOfBytes) - Mouse (Single click / Double click) (todo) - DialogBox (todo) - Scrolling (todo) - Execution after reboot (todo) - Count of processors (Win32/Tinba - Win32/Dyre) - Sandbox k
常见的调试技术包括检测调试器、检测调试器的附加、检测调试器的子进程、检测调试器的内存读写等。下面是一个简单的调试示例: ```c #include <Windows.h> #include <stdio.h> BOOL IsDebuggerPresentCheck() { return IsDebuggerPresent(); } BOOL CheckRemoteDebuggerPresentCheck() { BOOL bDebugged = FALSE; HANDLE hProcess = GetCurrentProcess(); CheckRemoteDebuggerPresent(hProcess, &bDebugged); CloseHandle(hProcess); return bDebugged; } BOOL NtQueryInformationProcessCheck() { BOOL bDebugged = FALSE; NTSTATUS status; PROCESS_BASIC_INFORMATION pbi; ULONG ulSize = 0; status = NtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), &ulSize); if (status == 0 && pbi.Reserved3 != 0) { bDebugged = TRUE; } return bDebugged; } BOOL DebugActiveProcessCheck() { HANDLE hProcess = GetCurrentProcess(); BOOL bDebugged = DebugActiveProcessCheck(hProcess); CloseHandle(hProcess); return bDebugged; } BOOL CheckDebugger() { if (IsDebuggerPresentCheck()) { return TRUE; } if (CheckRemoteDebuggerPresentCheck()) { return TRUE; } if (NtQueryInformationProcessCheck()) { return TRUE; } if (DebugActiveProcessCheck()) { return TRUE; } return FALSE; } void AntiDebug() { while (CheckDebugger()) { Sleep(1000); } } int main() { AntiDebug(); printf("Hello, world!\n"); return 0; } ``` 以上代码中,我们首先定义了一些函数来检测调试器,包括 IsDebuggerPresent()、CheckRemoteDebuggerPresent()、NtQueryInformationProcess() 和 DebugActiveProcess() 等函数。然后,我们实现了一个 AntiDebug() 函数,该函数会不断地检测调试器是否存在,如果存在则等待 1 秒钟后再进行检测。最后,在程序的主函数中调用 AntiDebug() 函数,确保程序在被调试时能够退出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值