{
int 2dh
inc eax;any opcode of singlebyte.
;or u can put some junkcode,\}
return true; }
__except(1) {
return false; }
三、 检测-专用调试器(FS_)
这一部分是我比较喜欢的,但内容还不是很丰富,比如:
1、 针对SoftIce的检测方法有很多,但由于我从没使用过Softice,也没有条件去测试,所以没有给出太多,有兴趣的可以自己查阅资料进行补充,针对softice网上资料较多,或查阅《软件加解密技术》。
2、 同样,这里也没有给出windbg等等其它调试器的检测方法。
3、 而针对Odplugin,也只给了几种HideOD的检测。事实上,目前OD的使用者通常都使用众多的强大插件,当OD的反调试越来越普遍时,自己设计几款常用的OD插件的反调试,将会是非常有效的反调试手段。
4、 对VME的检测也只给出了两种,如想丰富这一部分可以参考Peter Ferrie的一篇anti-vme的文章(http://bbs.pediy.com/showthread.php?t=68411)。里面有非常多的anti-vme方法。
针对专用调试器的函数列表如下: //find specific debugger
bool FS_OD_Exception_GuardPages(); bool FS_OD_Int3_Pushfd();
bool FS_SI_UnhandledExceptionFilter(); bool FS_ODP_Process32NextW(); bool FS_ODP_OutputDebugStringA(); bool FS_ODP_OpenProcess();
bool FS_ODP_CheckRemoteDebuggerPresent(); bool FS_ODP_ZwSetInformationThread(); bool FS_SI_Exception_Int1(); bool IsInsideVMWare_(); bool FV_VMWare_VMX(); bool FV_VPC_Exception();
int FV_VME_RedPill();//0:none,1:vmvare;2:vpc;3:others
3.1 FS_OD_Exception_GuardPages
“保护页异常”是一个简单的反调试技巧。当应用程序尝试执行保护页内的代码时,将会产生一个EXCEPTION_GUARD_PAGE(0x80000001)异常,但如果存在调试器,调试器有可能接收这个异常,并允许该程序继续运行,事实上,在OD中就是这样处理的,OD使用保护页来实现内存断点。
最开始实现时忘记了free申请的空间,多谢sessiondiy提醒。
SYSTEM_INFO sSysInfo; LPVOID lpvBase; BYTE * lptmpB;
GetSystemInfo(&sSysInfo);
DWORD dwPageSize=sSysInfo.dwPageSize; DWORD flOldProtect;
DWORD dwErrorcode;
lpvBase=VirtualAlloc(NULL,dwPageSize,MEM_COMMIT,PAGE_READWRITE); if(lpvBase==NULL) return false;
lptmpB=(BYTE *)lpvBase; *lptmpB=0xc3;//retn
VirtualProtect(lpvBase,dwPageSize,PAGE_EXECUTE_READ | PAGE_GUARD,&flOldProtect);
__try {
__asm call dword ptr[lpvBase];
VirtualFree(lpvBase,0,MEM_RELEASE); return true; }
__except(1) {
VirtualFree(lpvBase,0,MEM_RELEASE); return false; }
3.2 FS_OD_Int3_Pushfd
这是个最近比较牛X的反调试,据称是vmp1.64里发现的,好像ttprotect里面也有使用,我没有验证。Pediy里有帖子详细讨论,我是看到gkend的分析,才搞懂一些。下面摘自gkend分析
int3,pushfd和int3,popfd一样的效果。只要修改int3后面的popfd为其他值,OD都能通过。老掉牙的技术又重新被用了。SEH异常机制的运用而已。
原理:在SEH异常处理中设置了硬件断点DR0=EIP+2,并把EIP的值加2,那么应该在
int3,popfd后面的指令执行时会产生单步异常。但是OD遇到前面是popfd/pushfd时,OD会自动在popfd后一指令处设置硬件断点,而VMP的seh异常处理会判断是否已经设置硬件断点,如果已经有硬件断点就不产生单步异常,所以不能正常执行。
http://bbs.pediy.com/showthread.php?t=67737
大家也可以仔细研究下OD下的pushfd,popfd等指令,相信利用它们可以构造很多反调试,下面是我实现的一个,不过现在看起来有点没看懂,不知当时为什么用了两个int3。 __asm {
push offset e_handler; set exception handler push dword ptr fs:[0h] mov dword ptr fs:[0h],esp
xor eax,eax;reset EAX invoke int3 int 3h pushfd nop nop nop nop
pop dword ptr fs:[0h];restore exception handler add esp,4
test eax,eax; check the flag je rf_label jmp rt_label
e_handler:
push offset e_handler1; set exception handler push dword ptr fs:[0h] mov dword ptr fs:[0h],esp
xor eax,eax;reset EAX invoke int3 int 3h nop
pop dword ptr fs:[0h];restore exception handler add esp,4
;EAX = ContextRecord mov ebx,eax;dr0=>ebx
mov eax,dword ptr [esp+0xc] ;set ContextRecord.EIP inc dword ptr [eax+0xb8];
mov dword ptr [eax+0xb0],ebx;dr0=>eax xor eax,eax retn
e_handler1:
;EAX = ContextRecord
mov eax,dword ptr [esp+0xc] ;set ContextRecord.EIP inc dword ptr [eax+0xb8]; mov ebx,dword ptr[eax+0x04]
mov dword ptr [eax+0xb0],ebx;dr0=>eax xor eax,eax retn
rt_label: xor eax,eax inc eax mov esp,ebp pop ebp retn
rf_label: xor eax,eax mov esp,ebp pop ebp retn }
3.3 FS_SI_UnhandledExceptionFilter
这个针对SoftIce的反调试很简单,好像是SoftIce会修改UnhandledExceptionFilter这个函数的第一个字节为CC。因此判断这个字节是否为cc,就是一种检查softice的简便方法。
FARPROC Uaddr ; BYTE tmpB = 0; (FARPROC&) Uaddr =GetProcAddress ( GetModuleHandle(\tmpB = *((BYTE*)Uaddr); // 取UnhandledExceptionFilter函数第一字节 tmpB=tmpB^0x55;
if(tmpB ==0x99) // 如该字节为CC,则SoftICE己加载 return true; else
return false;
3.4 FS_ODP_Process32NextW
当我在调试FD_parentprocess时,感觉总是怪怪的,使用OD时运行Process32NextW总是返回失败,搞了一个晚上,才搞懂原来是OD的插件HideOD在作怪。当HideOD的Process32NextW的选项被选中时,它会更改Process32NextW的返回值,使其始终返回false,这主要是HideOD针对FD_parentprocess这个反调试的一个反反调试。但也正是这一点暴露的它的存在。
int OSVersion; FARPROC Func_addr; WORD tmpW;
//1.Process32Next
HMODULE hModule = GetModuleHandle(\
(FARPROC&) Func_addr =GetProcAddress ( hModule,\if (Func_addr != NULL) {
tmpW=*(WORD*)Func_addr; OSVersion=myGetOSVersion(); switch(OSVersion) {
case OS_winxp:
if(tmpW!=0xFF8B)//maybe option of Process32Next is selected. return true; break; default:
if(tmpW==0xC033) return true; break; } }
但上面的代码并不完美,因为有跨平台问题,所以要先获得当前操作系统版本。目前只在win2k和winxp下进行了测试。
3.5 FS_ODP_OutputDebugStringA
同样,HIDEOD的OutputDebugStringA选项,也对OutputDebugStringA这个api做了处理,具体修改内容我记不得了,大家可以自己比对一下。我的代码如下: int OSVersion; FARPROC Func_addr; WORD tmpW;
//2.OutputDebugStringA
HMODULE hModule = GetModuleHandle(\
(FARPROC&) Func_addr =GetProcAddress ( hModule,\if (Func_addr != NULL) {
tmpW=*(WORD*)Func_addr; OSVersion=myGetOSVersion(); switch(OSVersion) {
case OS_winxp:
if(tmpW!=0x3468)//maybe option of OutputDebugStringAt is selected. return true; break;
百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库OD反调试大全(4)在线全文阅读。
相关推荐: