反调试:
1.函数检测
IsDebuggerPresent
CheckRemoteDebuggerPresen
NtQueryInformationProcess函数是一个未公开的API,它的第二个参数可以用来查询进程的调试端口。如果进程被调试,那么返回的端口值会是-1,否则就是其他的值。
NtQueryInformationProcess(GetCurrentProcess(), (PROCESSINFOCLASS)7, &debugPort, sizeof(debugPort), NULL)
2.数据检测
2.1:查询进程PEB的BeingDebugged标志位
检测PEB第三位 BeingDebugged 是否为1
bool PebIsDebuggedApproach()
{
char result = 0;
__asm
{
// 进程的PEB地址放在fs这个寄存器位置上
mov eax, fs:[30h]
// 查询BeingDebugged标志位
mov al, BYTE PTR [eax + 2]
mov result, al
}
return result != 0;
}
2.2:查询进程PEB的NtGlobal标志位
当进程被调试的时候,操作系统除了修改BeingDebugged这个标志位
以外,还会修改其他几个地方,其中NtDll中一些控制堆(Heap)操作的函数的标志位就会被修改
bool PebNtGlobalFlagsApproach()
{
int result = 0;
__asm
{
// 进程的PEB
mov eax, fs:[30h]
// 控制堆操作函数的工作方式的标志位
mov eax, [eax + 68h]
// 操作系统会加上这些标志位FLG_HEAP_ENABLE_TAIL_CHECK,
// FLG_HEAP_ENABLE_FREE_CHECK and FLG_HEAPVALIDATE
PARAMETERS,
// 它们的并集就是x70
// 下面的代码相当于C/C++的
// eax = eax & 0x70
and eax, 0x70
mov result, eax
}
return result != 0;
}
2.3:查询进程堆的一些标志位
只要进程被调试,进程在堆上分配的内存,在分配的堆的头信息里,ForceFlags这个标志位会被修改
bool HeapFlagsApproach()
{
int result = 0;
__asm
{
// 进程的PEB
mov eax, fs:[30h]
// 进程的堆,我们随便访问了一个堆,下面是默认的堆
mov eax, [eax + 18h]
// 检查ForceFlag标志位,在没有被调试的情况下应该是
mov eax, [eax + 10h]
mov result, eax
}
return result != 0;
}
3.符号检测
一些调试器会使用驱动来实现某些功能,因此可以去检测驱动符号,来判断是否有调试器存在
\.\SomeDrv
CreateFile("\\.\SoftICE", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0)
4.窗口检测
检测调试器的窗口,如IDA, OD等等
FindWindow("OllyDbg", 0)
5.特征码检测
检测某个调试器的进程特征码,收集特征码后可以进行逐一判断
BYTE sign[] = {xxxx特征码};
PROCESSENTRY32 sentry32 = {0};
sentry32.dwSize = sizeof();
Createtoolhelp32Snapshot();
Process32First
do
{
OpenProcess();
DWORD szReaded = 0;
Byte signRemote[sizeof(sign)];
ReadProcessMemory();
if(memcmp(sign, signRemote, sizeof(sign)) == 0)
}
6.行为检测
进程处于调试状态和一般状态的某些指令的行为会有差异,如花费时间等等
rdtsc检测时间
7.断点检测
软断点int 3检测
硬断点dr寄存器检测
8.功能破坏
NtSetInfomationThread(HANDLE, THREADINFOCLASS, PVOID, LONG)
第二个参数设置,ThreadHideFromDebugger,可以对调试器隐藏线程的异常
OpenProcess、OpenThread、CreateProcess、CreateThread、Attach、WriteProcessMemeory、等等HOOk
9.行为占用
一个进程只能同时被一个调试器调试,那么可以启动另外一个进程去以调试模式启动被保护进程,称为双进程模式
PS:反调试简记,代码只是记录参考使用
参考:
小甲鱼《调试技术解密》
章立春《软件保护及分析技术》
[课程]Android-CTF解题方法汇总!