最近又在论坛上看到不少人求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]位置
3、CPU窗口中显示调试寄存器
DR0 =
00E57016
DR1 =
00E57000
DR2 =
00E57004
DR3 = 00E57008
DR7 = 33330555
由于SE会产生数个线程来进行反调试检测,内存完整性检测等,为了减少干扰项,把SE创建的检测线程先patch掉,不让他启动,可能会对后面的程序运行有副作用,但是便于我一开始的脱壳调试。
PS: SE会把NTDLL.dll和krenel32.dll中的一些代码Shadow到一段自己分配的空间中,所以需要利用内存搜索的方法,搜索特定代码找到这些被Shadow的API。
先在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+Dr3之Total值
我们在壳欲取得Drx的值时,将之清为0,并设TlsValue为0
至于SetTlsValue的Index应为多少才对,很多方法可以得知.
例如断Shadow的SetTlsValue ,XP SP2用的Index是4 , XP SP3则是6
这里是重头戏,反anti硬件断点必须从这里开始,由于壳会检测异常信息中的DRx寄存器,所以我们必须在SE的SEH 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期)