首页
社区
课程
招聘
[原创]Safengine Shielden 2.3.8.0 脱壳 ∷之∷ 为了能下断
发表于: 2017-4-11 09:40 42673

[原创]Safengine Shielden 2.3.8.0 脱壳 ∷之∷ 为了能下断

2017-4-11 09:40
42673

                    

最近又在论坛上看到不少人求Safengine Shielden(以下称SE)的脱壳方法,其实之前论坛里的几位大牛都已经放出过不少牛文,虽然这些牛文是对应老版本的SE的,文中附带的代码可能已经失效,但是里面的方法确实在新版本中依然有效的,可能大神们对自己思路的阐述过于跳跃了,所以难免让新人们有些跟不上。在这里,我把我对大牛们的思路理解放上来,以供参考吧。

SE 2.3.8.0目前已知的最大反调试手段就是anti断点,主要是anti了硬件断点和int3软断点,加壳后无法对被加壳的程序下断,客观上提高了脱壳的难度,所以第一步是要想办法把anti断点去掉。

int3软断点的anti必然是基于内存效验的方法(int3软断点需要修改内存代码),对壳代码进行hash效验保护,如若发现内存有被修改,则结束进程。如果要patch掉内存hash效验,必须知道hash代码的位置,由于SE的垃圾混淆代码很多,更本不可能通过搜索的方式获取,最好的办法就是用硬件断点下一个读取断,所以问题就是要先修复硬件断点。

对于硬件断点,SE采用的是先通过SetThreadContext设置四个DRx寄存器为1byte读取特定地址的断点,然后通过在虚拟机中构造读取特定地址以产生异常,再用SEH handler处理异常,并检测DRx寄存器的值。如果该产生异常的时候没有产生异常,又或者DRx的值不为先前SetThreadContext设定的值,那么就退出进程。

        对于内存断点反anti,暂时没有思路,还需要继续研究。

1、先在KiUserExceptionDispatcher下断

2、断下两次后记录

[esp+0x14] = 0012F7FC  00E8A7CA乔巴.00E8A7CA//异常产生的位置,就是后面的vm:ds[imm]位置

3CPU窗口中显示调试寄存器

         DR0 = 00E57016

         DR1 = 00E57000

         DR2 = 00E57004

DR3 = 00E57008

DR7 = 33330555

由于SE会产生数个线程来进行反调试检测,内存完整性检测等,为了减少干扰项,把SE创建的检测线程先patch掉,不让他启动,可能会对后面的程序运行有副作用,但是便于我一开始的脱壳调试。

        PS: SE会把NTDLL.dllkrenel32.dll中的一些代码Shadow到一段自己分配的空间中,所以需要利用内存搜索的方法,搜索特定代码找到这些被ShadowAPI

先在KiUserExceptionDispatcher下断

第一次断下后,搜索特征代码

#8BFF558BECFF751CFF7518FF7514FF7510FF750CFF75086AFFE8????????5DC21800#

搜索到的代码:

       修改函数开头位置为ret 18

00D1FB55  8BFF        mov  edi, edi     ;改成ret 18

        SE会调用Shadow_GetThreadContext来检测是否存在调试软件下的硬件断点,如果有就会退出进程。

在刚才搜索到Shadow_CreateThread的内存段内搜索特征代码:

#8BFF558BECFF750CFF7508FF15????????85C00F8C??????0033C0405DC208009090909090#

搜索到的代码:

如果直接修改以上代码会被SE检测到,我的方法是inline hook函数调用KiFastSystemCall之前的地址(壳另外加载了一块内存)

01888ACA   FF15 9E088501  call   dword ptr [185089E] //获取这里地址

//获取到的地址标准的ntdll.ZwGetContextThread调用

//我构造的代码

壳总是会判断这TlsValue是否等于Dr0+Dr1+Dr2+Dr3Total

我们在壳欲取得Drx的值时,将之清为0,并设TlsValue0

至于SetTlsValueIndex应为多少才对,很多方法可以得知.

例如断ShadowSetTlsValue ,XP SP2用的Index4 , XP SP3则是6

        这里是重头戏,反anti硬件断点必须从这里开始,由于壳会检测异常信息中的DRx寄存器,所以我们必须在SESEH handler被调用前,给_CONTEXT结构中的DRx赋予之前获得的特定值。

_CONTEXT结构如下:

typedef struct _CONTEXT

{

    DWORD ContextFlags;

    DWORD  Dr0;

    DWORD  Dr1;

    DWORD  Dr2;

    DWORD  Dr3;

    DWORD  Dr6;

    DWORD  Dr7;

    FLOATING_SAVE_AREA FloatSave;

    DWORD  SegGs;

    DWORD  SegFs;

    DWORD  SegEs;

    DWORD  SegDs;

    DWORD  Edi;

    DWORD  Esi;

    DWORD  Ebx;

    DWORD  Edx;

    DWORD  Ecx;

    DWORD  Eax;

    DWORD  Ebp;

    DWORD  Eip;

    DWORD  SegCs;

    DWORD  EFlags;

    DWORD  Esp;

    DWORD  SegSs;

} CONTEXT;


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 4
支持
分享
打赏 + 2.00雪花
打赏次数 2 雪花 + 2.00
 
赞赏  demoscene   +1.00 2018/08/17
赞赏  CCkicker   +1.00 2017/05/08
最新回复 (42)
雪    币: 9024
活跃值: (6245)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
感谢分享,点个赞
2017-4-11 10:42
0
雪    币: 12502
活跃值: (3053)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
厉害、。我当时。老想着硬干这个壳,然而各种被反艹
2017-4-11 10:59
0
雪    币: 6566
活跃值: (4526)
能力值: ( LV7,RANK:110 )
在线值:
发帖
回帖
粉丝
4
好东西,感谢分享
2017-4-11 13:53
0
雪    币: 346
活跃值: (25)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5
厉害!
2017-4-11 15:28
0
雪    币: 47147
活跃值: (20445)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
6
文章不错,感谢分享!
2017-4-11 21:27
0
雪    币: 14706
活跃值: (3165)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
感谢分享  。
2017-4-11 21:44
0
雪    币: 4938
活跃值: (977)
能力值: ( LV9,RANK:175 )
在线值:
发帖
回帖
粉丝
8
学习
2017-4-11 23:09
0
雪    币: 346
活跃值: (45)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
思路清析    感谢分享!
2017-4-12 09:09
0
雪    币: 3181
活跃值: (1796)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10

构造inline hook代码
// hook executehandler2
7C99AFC9    81EB 00060000   sub    ebx, 600   //减出myexceptionhandle的地址 
7C99AFCF    3B8B FC0F0000   cmp    ecx, dword ptr [ebx+FFC] //比较是否是SE的SEHhandler

执行第一句代码后 ebx =?

ebx+FFC =?


2017-4-12 14:33
0
雪    币: 279
活跃值: (14)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
好久没看到脱壳相关的文章了,赞一个
2017-4-12 14:44
0
雪    币: 2166
活跃值: (3226)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
12




MsScotch

构造inline hook代码
// hook executehandler2
7C99AFC9 &a ...

请看完整的代码:

7C99AFC0        E8  00000000                call      7C99AFC5
7C99AFC5        5B                                                  pop          ebx
7C99AFC6        83EB  05                                sub        ebx,  5    
7C99AFC9        81EB  00060000        sub        ebx,  600      //减出myexceptionhandle的地址
7C99AFCF        3B8B  FC0F0000      cmp        ecx,  dword  ptr  [ebx+FFC]  //比较是否是SE的SEHhandler



首先这段代码的空间是用脚步分配出来的,
sub    ebx  ,  5    前面的  call  和  pop  是用来获取当前代码内存地址的  ,这种方法在很多病毒和壳代码中都能看到  ,  所以ebx  =  7C99AFC0
而  ebx  +  ffc  也是位于这段代码的空间内  ,所以  ebx  +  ffc  =    7C99AFC0 - 0x600 +  0xffc

而  [ebx  +  ffc]  中的值是在第一次断在  KiUserExceptionDispatcher  ,在脚步中通过  exec            mov  eax,fs:[0]    获取的SEHhandler

2017-4-12 23:05
0
雪    币: 12688
活跃值: (4294)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
13
思路清析,通俗易懂,谢谢分享
2017-4-13 02:23
0
雪    币: 171
活跃值: (519)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
14
中间那个乔巴什么意思.........
2017-4-13 19:15
0
雪    币: 346
活跃值: (129)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
15
不错    几年前我也搞了  但后面事情多了  又丢在一边了
支持一下
2017-4-13 23:02
0
雪    币: 144
活跃值: (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
2017-4-14 07:23
0
雪    币: 3836
活跃值: (4142)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
厉害了我的哥。。。。。。
2017-4-14 10:44
0
雪    币: 878
活跃值: (496)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
18

  .

2017-4-14 11:48
0
雪    币: 878
活跃值: (496)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
19

   感谢分享

2017-4-14 11:53
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
```
7C99AFC0                E8    00000000                                call            7C99AFC5
7C99AFC5                5B                                                                                                    pop                    ebx
7C99AFC6                83EB    05                                                                sub                ebx,    5       
7C99AFC9                81EB    00060000                sub                ebx,    600            //减出myexceptionhandle的地址
7C99AFCF                3B8B    FC0F0000            cmp                ecx,    dword    ptr    [ebx+FFC]    //比较是否是SE的SEHhandler
```
我还是不明白这个地方,
1.  为什么要减  600?  这个只是为了跳转到  `myexceptionHandle`  吗?  所以这样我需要把  `myexceptionhandle`  代码放在  `sub    ebx,    600`  的位置?

2.  假设我的  fs:[0]    的值为  ABCDEF  那么这  条语句  `cmp      ecx,    dword    ptr    [ebx+FFC]`    是不是就可以改成  `cmp  ecx  ABCDEF`  了?
2017-4-18 15:21
0
雪    币: 2166
活跃值: (3226)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
21
DannyZhou ``` 7C99AFC0 E8 00000000 call 7C99AFC5 7C99AFC5 5B ...
第一个问题你的理解是正确的,无所谓减多少,只要得出的地址是myexceptionhandler的位置就可以了。第二个问题,请查阅关于段寄存器的定义介绍,查看fs段的定义
2017-4-20 15:22
0
雪    币: 3181
活跃值: (1796)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22

谢谢上面的解释,

myexceptionhandle过程中

1.dword ptr [ebx+7E8]的来源是什么?

24:mov    eax, dword ptr [ebx+7E8] //这里考虑可以在hook setthreadcontext中赋值

2. dword ptr [ebx+7FC]的来源是什么?

41:mov    ecx, dword ptr [ebx+7FC]

3.原来的call ecx代码处的ECX值,未保存么?


2017-5-31 17:27
0
雪    币: 5
活跃值: (47)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
我想问下大神用的什么工具调试下断的,我用OD  上面没有显示DR0  DR1  DR2  ...调试寄存器.是EAX  EBX  EDX的意思吗?样本能发下吗?
2017-12-2 18:34
0
雪    币: 5
活跃值: (47)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
恕我无知,在OD寄存器窗口  右键  选择  显示调试寄存器.
2017-12-2 19:23
0
雪    币: 33
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
大神,有空能出个视频或者图文教程让我们新手学习学习多好啊。
2017-12-24 23:00
0
游客
登录 | 注册 方可回帖
返回
//