各种反调试技术原理与实例VC版 - 图文 下载本文

http://ucooper.com 7. PEB.NtGlobalFlag , Heap.HeapFlags, Heap.ForceFlags

(1)通常程序没有被调试时,PEB另一个成员NtGlobalFlag(偏移0x68)值为0,如果进程被调试通常值为0x70(代表下述标志被设置): FLG_HEAP_ENABLE_TAIL_CHECK(0X10) FLG_HEAP_ENABLE_FREE_CHECK(0X20) FLG_HEAP_VALIDATE_PARAMETERS(0X40)

这些标志是在ntdll!LdrpInitializeExecutionOptions()里设置的。请注意PEB.NtGlobalFlag的默认值可以通过gflags.exe工具或者在注册表以下位置创建条目来修改:

HKLM\\Software\\Microsoft\\Windows Nt\\CurrentVersion\\Image File Execution Options

assume fs:nothing

mov eax,fs:[30h] mov eax,[eax+68h] and eax,70h

(2)由于NtGlobalFlag标志的设置,堆也会打开几个标志,这个变化可以在ntdll!RtlCreateHeap()里观测到。正常情况下系统为进程创建第一个堆时会将Flags和ForceFlags分别设为2(HEAP_GROWABLE)和0 。当进程被调试时,这两个标志通常被设为50000062(取决于NtGlobalFlag)和0x40000060(等于Flags AND 0x6001007D)。

assume fs:nothing

mov ebx,fs:[30h] ;ebx指向PEB mov eax,[ebx+18h] ;PEB.ProcessHeap

cmp dword ptr [eax+0ch],2 ;PEB.ProcessHeap.Flags jne debugger_found cmp dword ptr [eax+10h],0 ;PEB.ProcessHeap.ForceFlags jne debugger_found

这些标志位都是因为BeingDebugged引起的。系统创建进程的时候设置BeingDebugged=TRUE,后来NtGlobalFlag根据这个标记设置FLG_VALIDATE_PARAMETERS等标记。在为进程创建堆时,又由于NtGlobalFlag的作用,堆的Flags被设置了一些标记,这个Flags随即被填充到ProcessHeap的Flags和ForceFlags中,同时堆中被填充了很多BAADF00D之类的东西(HeapMagic,也可用来检测调试)。 一次性解决这些状态见加密解密P413

//********************************************** typedef ULONG NTSTATUS; typedef ULONG PPEB; typedef ULONG KAFFINITY; typedef ULONG KPRIORITY;

typedef struct _PROCESS_BASIC_INFORMATION { // Information Class 0 NTSTATUS ExitStatus; PPEB PebBaseAddress; KAFFINITY AffinityMask; KPRIORITY BasePriority; ULONG UniqueProcessId;

ULONG InheritedFromUniqueProcessId;

写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP网站建设、Wordpress应用等

http://ucooper.com } PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;

typedef enum _PROCESSINFOCLASS { ProcessBasicInformation, // 0 Y N ProcessQuotaLimits, // 1 Y Y ProcessIoCounters, // 2 Y N ProcessVmCounters, // 3 Y N ProcessTimes, // 4 Y N ProcessBasePriority, // 5 N Y ProcessRaisePriority, // 6 N Y ProcessDebugPort, // 7 Y Y ProcessExceptionPort, // 8 N Y ProcessAccessToken, // 9 N Y ProcessLdtInformation, // 10 Y Y ProcessLdtSize, // 11 N Y

ProcessDefaultHardErrorMode, // 12 Y Y ProcessIoPortHandlers, // 13 N Y ProcessPooledUsageAndLimits, // 14 Y N ProcessWorkingSetWatch, // 15 Y Y ProcessUserModeIOPL, // 16 N Y

ProcessEnableAlignmentFaultFixup, // 17 N Y ProcessPriorityClass, // 18 N Y ProcessWx86Information, // 19 Y N ProcessHandleCount, // 20 Y N ProcessAffinityMask, // 21 N Y ProcessPriorityBoost, // 22 Y Y ProcessDeviceMap,// 23 Y Y ProcessSessionInformation, // 24 Y Y ProcessForegroundInformation, // 25 N Y ProcessWow64Information // 26 Y N } PROCESSINFOCLASS;

typedef NTSTATUS (_stdcall *ZwQueryInformationProcess)( HANDLE ProcessHandle,

PROCESSINFOCLASS ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength ); //定义函数指针

void CDetectODDlg::OnPebflags() {

// TODO: Add your control notification handler code here

//定义函数指针变量

写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP网站建设、Wordpress应用等

http://ucooper.com

ZwQueryInformationProcess MyZwQueryInformationProcess;

HANDLE hProcess = NULL;

PROCESS_BASIC_INFORMATION pbi = {0};

ULONG peb = 0; ULONG cnt = 0;

ULONG PebBase = 0; ULONG AddrBase; BOOL bFoundOD=FALSE; WORD flag; DWORD dwFlag; DWORD bytesrw;

DWORD ProcessId=GetCurrentProcessId();

hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, ProcessId);

if (hProcess != NULL) {

MyZwQueryInformationProcess=(ZwQueryInformationProcess)GetProcAddress(LoadLibrary(\wQueryInformationProcess\ //函数指针变量调用

if (MyZwQueryInformationProcess( {

AddrBase=PebBase; if

(ReadProcessMemory(hProcess,(LPCVOID)(PebBase+0x68),&flag,2,&bytesrw)

&&

ProcessBasicInformation, &pbi,

sizeof(PROCESS_BASIC_INFORMATION), &cnt) == 0)

hProcess,

//函数指针变量赋值

PebBase = (ULONG)pbi.PebBaseAddress; //获取PEB地址

bytesrw==2) //读内存地址

{ //PEB.NtGlobalFlag } if { } if

(ReadProcessMemory(hProcess,(LPCVOID)(AddrBase+0x0c),&flag,2,&bytesrw)

&&

AddrBase=dwFlag;

(ReadProcessMemory(hProcess,(LPCVOID)(PebBase+0x18),&dwFlag,4,&bytesrw)

&&

if(0x70==flag){ }

bFoundOD=TRUE;

bytesrw==4)

bytesrw==2)

写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP网站建设、Wordpress应用等

http://ucooper.com

{//PEB.ProcessHeap.Flags } if

(ReadProcessMemory(hProcess,(LPCVOID)(AddrBase+0x10),&flag,2,&bytesrw)

&&

if(2!=flag){ }

bFoundOD=TRUE;

bytesrw==2)

{//PEB.ProcessHeap.ForceFlags }

if(bFoundOD==FALSE) { } else { }

AfxMessageBox(\发现OD\AfxMessageBox(\没有OD\if(0!=flag){ }

bFoundOD=TRUE;

}

CloseHandle(hProcess); } }

8. DebugPort: CheckRemoteDebuggerPresent()/NtQueryInformationProcess()

Kernel32!CheckRemoteDebuggerPresent()是用于确定是否有调试器被附加到进程。 BOOL CheckRemoteDebuggerPresent( HANDLE hProcess,

PBOOL pbDebuggerPresent )

Kernel32!CheckRemoteDebuggerPresent()接受2个参数,第1个参数是进程句柄,第2个参数是一个指向boolean变量的指针,如果进程被调试,该变量将包含TRUE返回值。 这个API内部调用了ntdll!NtQueryInformationProcess(),由它完成检测工作。

typedef BOOL (WINAPI *CHECK_REMOTE_DEBUGGER_PRESENT)(HANDLE, PBOOL); //定义函数指针

void CDetectODDlg::OnCheckremotedebuggerpresent() {

// TODO: Add your control notification handler code here HANDLE hProcess;

HINSTANCE hModule;

BOOL bDebuggerPresent = FALSE;

CHECK_REMOTE_DEBUGGER_PRESENT CheckRemoteDebuggerPresent; //建立函数指针变量 写意互联网,关注搜索引擎技术,涉猎搜索引擎优化、软件破解、PHP网站建设、Wordpress应用等