反调试破解
最近很多题都碰到了很烦人的反调试,有些反调试并不好调试过去,所以有了学习的要求。
静态反调试技巧
要记住几个重要的点
一、PEB
在反调试中会遇到PEB结构体中的几个点
1、BeingDebugged
在PEB结构体地址offset为0x2处,如果在调试的状态这个值会变成1,否则是0。检测的时候我们最常见到的是IsDebuggerPresent()api函数来判断是否处于调试阶段,其原理是先从TEB中找FS:[18],然后通过TEB.ProcessEnviromentBlock成员获取PEB地址然后找到偏移处就行。
2、Ldr
在偏移处0xc,PEB.Ldr是一个指向_PEB_LDR_DATA结构体的指针,其结构体是在堆内存创建的所以看该区域有无0xfeeefeee区域,有这个说明在调试状态,所以要将其改为NULL
3、Process Heap
PEB.ProcessHeap指向HEAP结构体的指针,偏移为0x18
进程处于调试状态时Flags和ForceFlags会变成特定值,可以从GetProcessHeap()这个api来获取PEB.ProcessHeap,这个api原理也是从TEB开始找到PEB.ProcessHeap。在非调试状态下,Flags的值为0x2,ForceFlags成员的值为0x0.
4、NtGlobalFlag
偏移为0x68,这个值在调试的时候会变成0x70,改为0x00就行
eg:
遇到第一种情况直接F7进入查看下面hex dump中的eax值,改为0就行
对于Ldr,call eax是为了调用ntdll.NtCurrentTeb()api,PEB地址是会存到EBX寄存器的,然后进行EEFEEEFE的初始化,再将Ldr的地址存到ESI寄存器
二、NtQueryInformationProcess()
这是一个api,用来探测调试器的技术
主要看第二个参数PROCESSINFOCLASS ProcessInformationClass指定特定值并调用该函数,相关信息被设置到PVOID ProcessInformation,其中PROCESSINFOCLASS是枚举类型
1、ProcessDebugPort
当进程处于调试状态,系统分配一个调试端口,ProcessDebugPort参数为7时,调用NtQueryInformationProcess()函数就能获取调试端口,若进程不在调试状态,其变量dwDebugPort值为0,若处于调试状态,其值为0xfffffff
CheckRemoteDebuggerPresent()这个api和IsDebuggerPresent()api是差不多的,用来检测进程是否处于调试阶段,该api不仅可以检测当前进程还能检测其他进程是否处于调试状态
3、ProcessDebugFlags(0x1F)
检测DebugFlags的值来判断是否处于调试状态,函数第二个参数设置为ProcessDebugFlags时,第三个值调取调试标志的值,若为0,则进程处于调试阶段,若为1,在非调试阶段
三、NtQuerySystemInoformation()
这是基于调试环境检测的反调试技术
四、NtQueryObject()
五、ZwSetInformationThread()
找到栈前第二个参数值,改为0就行
六、ETC
我们只要找到字符串魔改就行,把findwindows()api的第一个参数全改为null