首页
社区
课程
招聘
[求助]请问下这是什么反调试
发表于: 2013-8-2 15:36 9435

[求助]请问下这是什么反调试

2013-8-2 15:36
9435
在跟踪低版本armadillo的时候,硬件写入断点无效。有的位置内存断点会被检测。
有一处的SEH是这样的
004B0258 8B4C24 0C mov ecx, dword ptr [esp+C]
004B025C 8B99 B4000000 mov ebx, dword ptr [ecx+B4] ; Armadill.<ModuleEntryPoint>
004B0262 B8 DC5B0000 mov eax, 5BDC
004B0267 03C3 add eax, ebx
004B0269 8981 B8000000 mov dword ptr [ecx+B8], eax
004B026F C683 0F960000 B>mov byte ptr [ebx+960F], 0BF
004B0276 33C0 xor eax, eax
004B0278 8941 04 mov dword ptr [ecx+4], eax
004B027B 8941 08 mov dword ptr [ecx+8], eax
004B027E 8941 0C mov dword ptr [ecx+C], eax
004B0281 8941 10 mov dword ptr [ecx+10], eax
004B0284 C741 18 5501000>mov dword ptr [ecx+18], 155
004B028B 8B81 B0000000 mov eax, dword ptr [ecx+B0]
004B0291 83F8 04 cmp eax, 4
004B0294 74 19 je short 004B02AF
004B0296 50 push eax
004B0297 0FA2 cpuid
004B0299 0F31 rdtsc
004B029B 2B0424 sub eax, dword ptr [esp]
004B029E 83C4 04 add esp, 4
004B02A1 3D FFFFFF05 cmp eax, 5FFFFFF
004B02A6 72 07 jb short 004B02AF
004B02A8 8381 B8000000 6>add dword ptr [ecx+B8], 67
004B02AF 33C0 xor eax, eax
004B02B1 C3 retn


在虚拟机中(xp),004B029B    2B0424          sub     eax, dword ptr [esp]不执行,不知道什么bug
在win7,执行了cpuid之后,ecx就变成了0,后面的004B02A8    8381 B8000000 6>add     dword ptr [ecx+B8], 67引发异常。
如果忽略异常执行,是不会被检测到的,但是进到这个处理程序,就走不出去了。请问是什么原因啊。
还有一点就是,在这个异常处理程序的时候,可以观察到CONTEXT结构里面的硬件断点是正常的,没有清理,这个异常过了之后,就会对我下的写入断点的那个位置进行写入,而硬件断点检测不到。内存断点可以检测到。

[注意]看雪招聘,专注安全领域的专业人才平台!

收藏
免费
支持
分享
最新回复 (6)
雪    币: 135
活跃值: (63)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
2
还有一个我一直想不通的问题。就是,为什么这个壳可以双变单,不是异常之后就调试解密吗。双变单是在解密页面之前就变了。patch几个点就能解密是什么原理啊。那他原本的调试运行不就没有意义了吗。最开始的研究都是强制解密之后再脱离。
2013-8-2 17:44
0
雪    币: 116
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
应该是与rdtsc有关吧
2013-8-2 21:38
0
雪    币: 81
活跃值: (115)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4
异常以后可以获取线程的context,然后把dr寄存器都清零了,硬件断点也就没了。虚拟机处理rdtsc是有个bug的,有时候会利用这个来反虚拟机。清零dr寄存器不是直接读写的,而是改写异常的context,异常结束后系统会自动把异常的context写入到真实的异常。建议你找2篇SEH的文章看看
2013-8-3 11:29
0
雪    币: 135
活跃值: (63)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
5
仔细想了下,可能不是反调试的问题,对SetThreadContext这类函数用到的堆栈内存下断点,是不会断下来的。内存断点会挂掉,硬件断点没反应。drx7=0x155,可以百度到原理,说的是有的调试器无法处理程序本身设置的硬件断点,但是前提是前面4个drx都是写的代码的地址,触发单步异常然后捕获,这里对前面4个drx的处理只是清零,这一点不明白。另外不是虚拟机的问题,不进入这个处理,完全正常运行。对于双变单,刚才看了下剩下的教程贴,有的版本是子进程自己解压然后自己加密,然后被父进程调试解压,调试加密,可能单变双patch的是这个。
2013-8-3 12:11
0
雪    币: 81
活跃值: (115)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
6
清零了硬件断点不就没了么,所以断不下了
你自己用c++写个demo试试嘛
2013-8-3 14:46
0
雪    币: 135
活跃值: (63)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
7
这个是反硬件断点保护,不是简单的清零,dr7=0x155,4个drx都用上了,但是写的值是0,我觉得无意义,按理简单清零应该drx7直接写0。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
  __asm
  {
    xor    eax,eax;
    cdq;
    push  e_handler;
    push  dword ptr fs:[eax];
    mov    fs:[eax],esp;
    int 3;
hwbp1:  nop
hwbp2:  nop
hwbp3:  nop
hwbp4:  nop
    div    edx
    nop
    pop    dword ptr fs:[0]
    add    esp,4
    cmp    al,4;
    jne    rt_label;
    jmp    rf_label;
 
e_handler:
    xor    eax,eax;
    ;ExceptionRecord
    mov    ecx,dword ptr[esp+0x04]
    ;Contextrecord
    mov    edx,dword ptr[esp+0x0c]
    ;ContextEIP
    inc    byte ptr[edx+0xb8];
     
    ;ExceptionCode
    mov    ecx,dword ptr[ecx];
 
    ;1.EXCEPTION_INT_DIVIDE_BY_ZERO
    cmp    ecx,0xc0000094;
    jne    Ex_next2;
    ;Context_eip
    inc    byte ptr[edx+0xb8];
    mov    dword ptr[edx+0x04],eax;dr0
    mov    dword ptr[edx+0x08],eax;dr1
    mov    dword ptr[edx+0x0c],eax;dr2
    mov    dword ptr[edx+0x10],eax;dr3
    mov    dword ptr[edx+0x14],eax;dr6
    mov    dword ptr[edx+0x18],eax;dr7
    ret
 
    ;2.EXCEPTION_BREAKPOINT
Ex_next2:
    cmp    ecx,0x80000003;
    jne    Ex_next3;
 
    mov    dword ptr[edx+0x04],offset hwbp1;dr0
    mov    dword ptr[edx+0x08],offset hwbp2;dr1
    mov    dword ptr[edx+0x0c],offset hwbp3;dr2
    mov    dword ptr[edx+0x10],offset hwbp4;dr3
    mov    dword ptr[edx+0x18],0x155;dr7
    ret
 
    ;3.EXCEPTION_SINGLE_STEP
Ex_next3:
    cmp  ecx,0x80000004
    jne    rt_label
    ;CONTEXT_Eax
    inc    byte ptr[edx+0xb0]
    ret
 
  }by shellwolf

这个才是用到了0x155,相当于改变了程序流程,记录程序自己踩到自己设的硬件断点次数。
单独清零drx0~drx3,然后把drx7莫名其妙的写成0x155,感觉无意义,但是armadillo是这么做的。

好像对硬件断点的检测是我自己弄错了,我自己写了个玩具插件恢复drx的值的时候掉了一句话,所以出问题了,我还以为是反调试。但是内存断点还是不明白什么原理。有一个异常处理很复杂,看不懂。还用到了Unwind。

c++写SEH程序用到了try except关键字(我也不明白),但是实际上这是很复杂的宏来转换的,SEH只有汇编形式的demo才容易看请。c++没试过。
2013-8-3 21:46
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册