常用反跟踪技术

常用反跟踪技术

作者:smokingroom
日期:2005-04-12
站点:www.programmerlife.com
邮箱:smokingroom@sina.com


一、防单步调试

 1、利用标志寄存器(Win9x/WinNt都适用)

  CPU标志寄存器(FR)中第八位为陷阱标志(Trap),如果该位置位,则CPU运行于单步模式,因此我们可以根据该位来判断是否处于单步模式,从而实现“反”单步运行。
  代码如下:
procedure Check_Trap;
asm
PUSHFD      //标志寄存器内容进栈
POP  EAX    //获得标志寄存器内容
TEST  AH,$01    //测试陷阱标志
JE  @exit   
PUSH  0
CALL  ExitProcess  //判断出CPU处于单步模式,终止进程,当然,你可以狠点,比如关机什么的,看你的了:)
@exit:   
end;

 2、修改中断入口地址(Win9x适用)
  对中断的处理,系统提供了一个中断入口地址表,单步调试正是通过修改这个中断入口地址表中中断1的入口地址,使用指向自己的处理过程,如果我们在程序运行过程中,将中断1的入口地址破坏一下,会怎么样呢?_-_b
  代码如下:
  
procedure Crash_INT1;
var
IDT:array[0..5] of Byte;
asm
CALL  GetVersion      //GetVersion結果最高位為0則為NT/2000/XP,否則為9x
TEST  EAX,$80000000
JE  @exit        //这里若为NT则退出过程
SIDT  IDT        //取得中断描述表寄存器内容(Interrupt descriptor table)
MOV  EAX,DWORD PTR [IDT+2]    //取得中断入口地址表
ADD  EAX,8        //INT 1的入口地址
CLI
MOV  WORD PTR [EAX],CX    //低16位,随便给它一个值吧
ROR  ECX,16
MOV  WORD PTR [EAX+6],CX    //高16位,随便给它一个值吧
ROL  ECX,16
STI
@exit:
end;


二、防API断点跟踪

  使用SoftIce或TRW的Cracker们,下API断点可谓是基本功课了,比如bpx hmemcpy/bpx MessageBoxA等,实际上,调试器是在API入口处放置了中断指令$CC(即int 3),因此我们可以判断该API入口处第一字节的代码是否为$CC来判断是否设了断点。

  代码如下,我们检查MessageBoxA这个API是否被设了断点。

procedure Check_Bpx
var
DllName,ApiName:PChar;
begin
DllName:='user32.dll';
ApiName:='MessageBoxA';
asm
PUSH  DllName
CALL  GetModuleHandle    //获取user32模块的基地址
PUSH  ApiName
PUSH  EAX
CALL  GetProcAddress    //获取MessageBoxA函数的入口地址
CMP  BYTE PTR [EAX], $CC  //比较入口处首字节是否为$CC(int 3)
JNE  @exit
PUSH  0
CALL  ExitProcess    //判断出MessageBoxA函数已经被设断点,终止进程。
@exit:
end;
end;

三、检测非系统级调试器(WinNT适用)

  1、利用调试API--IsDebuggerPresent

  WinNT系统中,提供了一个IsDebuggerPresent函数,该函数可以判断本进程是否被别的进程调试。不过只对进程级调试器有用,对系统级调试器是无效的,比如SoftIce及TRW等。

  代码如下,首先判断kernel32中是否已经支持该函数,若支持则调用。

procedure Check_Debugger
var
DllName:PChar;
ApiName:PChar;
begin
DllName:='kernel32.dll';
ApiName:='IsDebuggerPresent';
asm
PUSH  DllName
CALL  GetModuleHandle
PUSH  ApiName
PUSH  EAX
CALL  GetProcAddress
CMP  EAX,0
JZ  @exit
CALL  EAX
CMP  EAX,1
JNE  @exit
CALL  ExitProcess
@exit:
end;
end;

四、检测系统级调试器

  1、利用SoftIce后门,检测SoftIce(Win9x/WinNT适用)

procedure Check_SoftIce1;
asm
PUSH  EBP
PUSH  Offset @seh_handler  //因为SoftIce不存时,将引发异常,故需要使用seh来处理
PUSH  FS:[0]
MOV  FS:[0],ESP    //安装seh
MOV  EBP,$4243484B    //EBP=$4243484B,AX=4 为SoftIce接口参数
MOV  AX,$04
INT  3
POP  FS:[0]      //缷载seh
ADD  ESP,4
POP  EBP
CMP  AL,4      //若AL<>4则SOFTICE已经加载!!!
JE  @exit
CALL  ExitProcess    //若加载,则退出
@seh_handler:
MOV  EAX,[ESP+12]
INC  [EAX][TCONTEXT].Eip
MOV  EAX,0
RET  16
@exit:
end;

  2、向SoftIce发命令,检测SoftIce(Win9x/WinNT适用)

procedure Check_SoftIce2;
asm          //通过int 3向SoftIce发命令
MOV  SI,'FG'     
MOV  DI,'JM'      //SI和DI寄存器中放的分别是固定值0x4647("FG")和0x4A4D("JM")
MOV  EDX,Offset @after_int
CALL  @set_seh
MOV  EDX,Offset ExitProcess
INT  3
JMP  EDX      //若SoftIce未加载,则由@seh_handler处理int3,EDX将被设置为@after_int的偏移
@set_seh:
POP  ECX
PUSH  EDX
PUSH  Offset @seh_handler
SUB  EDX,EDX
PUSH  FS:[EDX]
MOV  FS:[EDX],ESP
PUSH  ECX
RET
@seh_handler:
PUSH  EBP
MOV  EBP, ESP
SUB  EDX, EDX
MOV  EAX, FS:[EDX]
MOV  ESP, [EAX]
POP  FS:[EDX]
ADD  ESP, 4
MOV  EAX, [EBP+16]
INC  DWORD PTR [EAX+184]    //CONTEXT.regEip加1,跳过int 3
POP  DWORD PTR [EAX+168]    //CONTEXT.regEdx恢复成offset @after_int
MOV  DWORD PTR [EAX+196],ESP  //CONTEXT.regEsp改成安装seh frame之前的值
MOV  EAX, 0
MOV  ESP, EBP
POP  EBP
RET  16
@after_int:
end;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值