<逆向工程核心原理> 动态反调试技术总结
来源:互联网 发布:java获取tomcat版本号 编辑:程序博客网 时间:2024/05/16 10:25
1.异常-SEH
#include "stdio.h"#include "windows.h"#include "tchar.h"void AD_BreakPoint(){ printf("SEH : BreakPoint\n"); __asm { // install SEH push handler push DWORD ptr fs:[0] mov DWORD ptr fs:[0], esp //INT 3 指令是CPU中断命令,在用户模式的调试器啥都不做(经过调试发现不会触发ntdll.dll中的KiUserExceptionDispatcher)。 // generating exception int 3 // 1) debugging // go to terminating code mov eax, 0xFFFFFFFF jmp eax // process terminating!!! // 2) not debugging // go to normal codehandler: mov eax, dword ptr ss:[esp+0xc] mov ebx, normal_code mov dword ptr ds:[eax+0xb8], ebx xor eax, eax retnnormal_code: // remove SEH pop dword ptr fs:[0] add esp, 4 } printf(" => Not debugging...\n\n");}int _tmain(int argc, TCHAR* argv[]){ AD_BreakPoint(); return 0;}
注意:OD的异常选项 忽略int 3 中断必须不选,strongOD插件选项最好不用,才能进入指令
mov eax, 0xFFFFFFFF
jmp eax
OD不能在int 3下断(F2),否则会循环进入异常地址 int 3.
2.异常-SetUnhandledExceptionFilter
#include "stdio.h"#include "windows.h"#include "tchar.h"LPVOID g_pOrgFilter = 0;LONG WINAPI ExceptionFilter(PEXCEPTION_POINTERS pExcept){ SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)g_pOrgFilter); // 8900 MOV DWORD PTR DS:[EAX], EAX // FFE0 JMP EAX pExcept->ContextRecord->Eip += 4; return EXCEPTION_CONTINUE_EXECUTION;}void AD_SetUnhandledExceptionFilter(){ printf("SEH : SetUnhandledExceptionFilter()\n");//SetUnhandledExceptionFilter()来注册新的Top Level Exception Filter回调函数。//触发异常时,系统在前面没有处理异常的情况下,会调用Kernel32.dll中的//UnhandledExceptionFilter()函数。UnhandledExceptionFilter()会利用//ntdll.dll中的NtQueryInformationProcess()来判断是否被调试,//若判断在被调试,异常给调试器(调试器无法处理异常,进程终止)。//若判断未被调试,则调用Top Level Exception Filter回调函数。g_pOrgFilter = (LPVOID)SetUnhandledExceptionFilter( (LPTOP_LEVEL_EXCEPTION_FILTER)ExceptionFilter); __asm { xor eax, eax; mov dword ptr [eax], eax jmp eax } printf(" => Not debugging...\n\n");}int _tmain(int argc, TCHAR* argv[]){ AD_SetUnhandledExceptionFilter(); return 0;}
3.Timing Check
#include "stdio.h"#include "windows.h"#include "tchar.h"void DynAD_RDTSC(){//Timing Check 技术通过计算运行时间的差异来反调试,反模拟。//1.Counter based method//RDTSC 汇编指令(RD==READ TSC == Time Stamp Counter)//x86 CPU中存在一个名为TSC(Time Stamp Counter,时间戳计数器)的64位寄存器。//CPU对每个Clock Cycle(时钟周期)计数,然后保存到TSC.RDTSC是一条汇编指令,//用来将TSC值读入EDX:EAX寄存器)。 //OD中的插件Olly Advanced->options 反调试2 Anti-RDSTC(基于驱动模式可以绕过),此功能有可能造成死机。 //kernel32!QueryPerformanceCounter()/ntdll!NtQueryPerformanceCounter() //kernel32!GetTickCount() //2.Time based method //timeGetTime() //_ftime() DWORD dwDelta = 0; printf("Timing Check (RDTSC method)"); __asm {pushad//0F31 rdtscrdtscpush edxpush eax//用于消耗时间的循环(实际代码相当复杂)xor eax, eaxmov ecx, 0x3e8_LOOP_START:inc eaxloop _LOOP_STARTrdtscpop esi// eaxpop edi// edx// check high order bitscmp edx, edija _DEBUGGER_FOUND// check low order bitssub eax, esi mov dwDelta, eaxcmp eax, 0xffffffjb _DEBUGGER_NOT_FOUND // debugger found -> crash!!!_DEBUGGER_FOUND:xor eax, eaxmov [eax], eax // debugger not found_DEBUGGER_NOT_FOUND:popad} printf(" : delta = %X (ticks)\n", dwDelta); printf(" => Not debugging...\n\n");}int _tmain(int argc, TCHAR* argv[]){ DynAD_RDTSC(); return 0;}
4.陷阱标志
#include "stdio.h"#include "windows.h"#include "tchar.h"void DynAD_SingleStep(){ //陷阱标志指EFLAGS寄存器的第9个(Index8)比特位。 //TF值设置为1时,CPU将进入单步执行(Single Step)模式。单步直行模式中,CPU执行1条指令后即 //触发一个EXCEPTION_SINGLE_STEP(0x80000004)异常,异常地址为下一条指令。然后陷阱标志会 //自动清零。 printf("Trap Flag (Single Step)\n"); __asm { // install SEH push handler push DWORD ptr fs:[0] mov DWORD ptr fs:[0], esp //因无法修改EFLAGS,故通过栈修改 pushfd or dword ptr ss:[esp], 0x100 popfd //执行完nop指令后,才触发EXCEPTION_SINGLE_STEP异常,OD在nop指令使用F7,F8,F9都可以。 //即KiUserExceptionDispatcher的异常地址指向 mov eax,0xFFFFFFFF //1)若为正常运行,则运行前面注册过的SEH //2)若为调试运行,则继续执行以下指令,不管使用F7,F8,F9都断在mov eax,0xFFFFFFFF nop // 1) debugging // go to terminating code mov eax, 0xFFFFFFFF jmp eax // process terminating!!! // 2) not debugging // go to normal codehandler: mov eax, dword ptr ss:[esp+0xc] mov ebx, normal_code mov dword ptr ds:[eax+0xb8], ebx xor eax, eax retnnormal_code: // remove SEH pop dword ptr fs:[0] add esp, 4 } printf(" => Not debugging...\n\n");}int _tmain(int argc, TCHAR* argv[]){ DynAD_SingleStep(); return 0;}
#include "stdio.h"#include "windows.h"#include "tchar.h"void DynAD_INT2D(){//INT 2D 原为内核模式中用来触发异常的指令,也可以在用户模式下触发异常。但程序//调试运行时不会触发异常,只是忽略。//INT 2D指令会造成两个有趣的现象//1.在调试模式中执行INT2D指令后(F7,F8),下条指令的第一个字节将被忽略,后一个字节会被识别为新的指令继续执行。此特性,可用于代码混淆。//2.在调试模式中执行INT2D指令后(F7,F8),程序不会停在其下条指令开始的地方,而是一直运行,直到遇到断点(原有的代码字节顺序被打乱,OD的BUG)。 BOOL bDebugging = FALSE; __asm { // install SEH push handler push DWORD ptr fs:[0] mov DWORD ptr fs:[0], esp //可以在执行到此条指令时,修改EFlags寄存器TF=1,然后就能进入SEH处理函数 int 0x2d nop mov bDebugging, 1 jmp normal_codehandler: mov eax, dword ptr ss:[esp+0xc] mov dword ptr ds:[eax+0xb8], offset normal_code mov bDebugging, 0 xor eax, eax retnnormal_code: // remove SEH pop dword ptr fs:[0] add esp, 4 } printf("Trap Flag (INT 2D)\n"); if( bDebugging ) printf(" => Debugging!!!\n\n"); else printf(" => Not debugging...\n\n");}int _tmain(int argc, TCHAR* argv[]){ DynAD_INT2D(); return 0;}
5.0xCC探测
#include "stdio.h"#include "windows.h"#include "tchar.h"DWORD g_dwOrgChecksum = 0xF5934986;int _tmain(int argc, TCHAR* argv[]);void DynAD_Checksum(){ BOOL bDebugging = FALSE; DWORD dwSize = 0; printf("Checksum\n"); __asm { mov ecx, offset _tmain mov esi, offset DynAD_Checksum sub ecx, esi // ecx : loop count (buf size) xor eax, eax // eax : checksum xor ebx, ebx_CALC_CHECKSUM: movzx ebx, byte ptr ds:[esi] add eax, ebx rol eax, 1 inc esi loop _CALC_CHECKSUM cmp eax, g_dwOrgChecksum je _NOT_DEBUGGING mov bDebugging, 1_NOT_DEBUGGING: } if( bDebugging ) printf(" => Debugging!!!\n\n"); else printf(" => Not debugging...\n\n");}int _tmain(int argc, TCHAR* argv[]){ DynAD_Checksum(); return 0;}
总结:
1. CC int3 指令(注意两者之间没有空格)。
2.CD 2D int 2d 指令
3.
pushfd
or [esp],100
popfd
使EFlags寄存器TF==1.
此3种方法,都是利用了调试器特有的性质(1.忽略 2.一直运行,直到断点。 3.断在执行指令后的一条指令,都没有触发ntdll!KiUserExceptionDispatcher())。
0 0
- <逆向工程核心原理> 动态反调试技术总结
- <逆向工程核心原理> 静态反调试技术总结
- 《逆向工程核心原理》》<07> 反调试技术
- 《逆向工程核心原理》》<06> 高级逆向分析技术
- 《逆向工程核心原理》
- 《逆向工程核心原理》
- 逆向工程核心原理
- 逆向工程核心原理学习笔记(七):总结
- 逆向工程核心原理学习笔记(七):总结
- 《逆向工程核心原理》学习总结(一)
- 《逆向工程核心原理》学习总结(二)
- 《逆向工程核心原理》学习总结(三)
- 《逆向工程核心原理》学习总结(四)
- 反调试技术总结.
- 反调试技术总结
- 171211 逆向-高级反调试技术
- 美团逆向-干掉反动态调试
- 《逆向工程核心原理》相关说明
- 产品经理入门
- 正则表达
- 点语法
- 用debugfs查看EXT4分区相关信息
- ******************* fscanf--fprintf *******************
- <逆向工程核心原理> 动态反调试技术总结
- **light oj 1145 - Dice (I) (计数dp(难哭了))
- log4j.properties配置详解
- Java程序员从笨鸟到菜鸟全部博客目录
- Latch争用
- 图像匹配
- JAVA静态和非静态内部类
- 蜂鸣器电路中有大内容
- 事务的控制(配置文件&&注解)