2种基于异常机制的反调试方法
来源:互联网 发布:相思相见知何日 编辑:程序博客网 时间:2024/04/30 18:46
如题,一种是利用异常处理例程进行反调试:首先安装好一个异常处理例程,然后人为抛出异常在异常处理例程中通过IsDebuggerPresent来判断程序是否被调试;另一种是利用未处理异常进行反跟踪,其原理是:当异常发生时所有异常处理例程都不能处理异常,系统线程异常处理例程将起作用,它调用 ZwQueryInformationProcess 判断是否被调试,
如果没有调试并且程序中调用SetUnhandledExceptionFilter安装了最后异常处理例程的话,系统转向对它的调用。
第一种方法中IsDebuggerPresent是通过返回FS寄存器上记录的地址的一些偏移量来实现的。在debugger中可以任意操作当前进程内存地址上的值,所以只需要用调试器把[[FS:30]:2的值修改成0,IsDebuggerPresent就会返回false,导致判断失败。相比第二种方法中UnhandledExceptionFilter是否调用取决于系统内核的判断。用户态的调试器要想改变这个行为就得颇费功夫了。下面我将依次展示两种反调试方法。
第一种方法,通过在异常处理例程中判断IsDebuggerPresent的返回值:
#include <windows.h>int AntiDebugInSEH(EXCEPTION_POINTERS* ExceptionInfo){DWORD state = 0x00;__asm{mov eax,dword ptr fs:[30h];movzx eax, byte ptr ds:[eax+2h];mov state,eax;}ExceptionInfo->ContextRecord->Eax = state;ExceptionInfo->ContextRecord->Eip = 0x06+(DWORD)ExceptionInfo->ExceptionRecord->ExceptionAddress;return EXCEPTION_CONTINUE_EXECUTION;}int main(){int i=0;__try{__asm{xor eax,eax;mov dword ptr [eax],0; //触发异常}__asm{ //异常返回后,eax的值为AntiDebugInSEH中ExceptionInfo->ContextRecord->Eax设定的值 mov i,eax}if(i==1){}else{MessageBox(NULL,"","",0);}i++;}__except(AntiDebugInSEH(GetExceptionInformation())){}}上面这段代码,如果正常运行将弹出对话框,如果调试运行对话框是看不到了。文章中也提到了,可以通过修改[[fs:30]:2]处的内存地址使IsDebuggerPresent失效,好的,祭出windbg:
进入异常时,[fs:[30h]:2]处的值为0x0001,即正在调试状态:
0:000> r eaxeax=7ffd50000:000> dd eax7ffd5000 00010000 ffffffff 00400000 76fb88807ffd5010 00291940 00000000 00290000 76fb8380为了使IsDebuggerPresent失效,修改0x7ffd5000处的内存值:
0:000> ed 7ffd5000 0x000000000:000> dd eax7ffd5000 00000000 ffffffff 00400000 76fb88807ffd5010 00291940 00000000 00290000 76fb8380当程序从异常处理例程返回时,又可以见到对话框了:
接下来看下第二种反调试方法:
#include <windows.h>LONG WINAPI UnhandledExcept(EXCEPTION_POINTERS *pExpInfo) {if(pExpInfo->ExceptionRecord->ExceptionCode != EXCEPTION_BREAKPOINT){return EXCEPTION_EXECUTE_HANDLER;}else{pExpInfo->ContextRecord->Eip = (DWORD)(pExpInfo->ContextRecord->Eip+1);pExpInfo->ContextRecord->Eax = 0x0000FEEE;return EXCEPTION_CONTINUE_EXECUTION;}}int main(){HMODULE hMod = LoadLibrary("kernel32.dll");DWORD* funcAddr = (DWORD*)GetProcAddress(hMod,"ExitProcess");SetUnhandledExceptionFilter(UnhandledExcept);_asm int 3;__asm{cmp ax,0xFEEE;jz next;push 0;mov eax,funcAddr;call eax;next:}{MessageBox(NULL,"","",MB_OK);}}这段代码,还是读者自己试下,我暂时没想到如果绕过检测的方法。
参考连接:
http://www.52pojie.cn/forum.php?mod=viewthread&tid=16609
http://bbs.pediy.com/showthread.php?t=9023
0 0
- 2种基于异常机制的反调试方法
- 基于STARTUPINFO的反调试与反反调试
- 常用的反调试方法
- java的方法、重构,调试、异常处理机制总结
- 2种内核级反用户态调试方法
- 转载过来的反调试方法
- 调试中使用反汇编的方法
- 【前无古人后无来者的反调试方法】
- 计算CRC32值反调试的方法
- Windows 下常见的反调试方法
- od反调试的对策(使用除0异常)
- linux反调试方法
- PE文件的TLS-反调试机制
- 一种基于TLS的高级反调试技术
- 一种基于TLS的高级反调试技术
- 反反调试思想方法探索(转)
- String的replaceAll方法替换反斜线报异常
- 反调试主要方法简述
- Codeforces Round #317 [AimFund Thanks-Round] (Div. 2) C(组合数+容斥)
- UVA 1584 Circular Sequence
- Redis详细,config配置,win和linux下怎么玩,和mysql数据同步。
- android color.xml
- Algorithms—268.Missing Number
- 2种基于异常机制的反调试方法
- [LeedCode OJ]#169 Majority Element
- Linux下安装Python3
- extjs4 之单元格编辑 获取列对象
- Android IM(五)连接断开重连
- Linux内核设计与实现--学习笔记--第三章- 1(task_struct等)
- 黑马程序员——线程Thread一(线程创建)
- Android系统自带样式(android:theme)
- 深入理解RunLoop