首页
论坛
专栏
课程

[原创]五花八门的反调试

2019-7-16 15:46 4274

[原创]五花八门的反调试

2019-7-16 15:46
4274
关于反调试技术,知道这些反调试技术可以让我们很好的应对他,然而不知道这些技术会让我们在逆向中屡屡受挫。恶意代码编写者意识到分析人员经常使用调试器来观察恶意代码的操作,因此他们使用反调试技术尽可能地延长恶意代码的分析时间。下面我会介绍一些常用的反调试手段。

1. Windows API

使用Windows API函数检测调试器是否存在是最简单的反调试技术。Windows操作系统中提供了这样一些API,应用程序可以通过调用这些API,来检测自己是否正在被调试。

1.1      IsDebuggerPresent

IsDebuggerPresent查询进程环境块(PEB)中的IsDebugged标志。如果进程没有运行在调试器环境中,函数返回0;如果调试附加了进程,函数返回一个非零值。

1.2      CheckRemoteDebuggerPresent

CheckRemoteDebuggerPresent不仅可以查询系统其他进程是否被调试,而且还可以通过传递自己的进程句柄来判断自己是否被调试。

1.3      GetLastError

我们在编写程序的时候,经常会涉及到错误处理问题。我们用的最多的应该就是GetLastError()这个函数了。恶意代码可以使用异常来检查调试器。调试器捕获异常后,并不会立即将处理权返回被调试进程处理,大多数利用异常的反调试技术往往据此来检测调试器。

对于OutputDebugString函数,它的作用是在调试器中显示一个字符串,同时它也可以用来探测调试器的存在。使用SetLastError函数,将当前的错误码设置为一个任意值。如果进程没有被调试器附加,调用OutputDebugString函数会失败,错误码会重新设置,因此GetLastError获取的错误码应该不是我们设置的任意值。但如果进程被调试器附加,调用OutputDebugString函数会成功,这时GetLastError获取的错误码应该没改变。

对于DeleteFiber函数,如果给它传递一个无效的参数的话会抛出ERROR_INVALID_PARAMETER异常。如果进程正在被调试的话,异常会被调试器捕获。所以,同样可以通过验证LastError值来检测调试器的存在。如代码所示,0x57就是指ERROR_INVALID_PARAMETER。

同样还可以使用CloseHandle、CloseWindow产生异常,使得错误码改变

2. 系统检测

2.1      查找调试器引用的注册表项

下面是调试器在注册表中的一个常用位置。

32位系统:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug


64位系统:HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug


如果该这册表的键值被修改为OllyDbg,则恶意代码就可能确定它正在被调试。

2.2      查找窗口信息


比较简单的FindWindow函数会搜索顶级窗口的类名和窗口名称然后匹配指定的字符串。


EnumWindows函数枚举所有屏幕上的顶层窗口,并将窗口句柄传送给应用程序定义的回调函数。

GetForegroundWindow获取一个前台窗口的句柄。

2.3      查找进程信息

查找进程信息和枚举进程的思路大致是一样的,遍历进程比较字符串。


3.  调试器断点

3.1      软件断点检查

调试器设置软件断点的基本机制利用INT 3临时替换运行程序中的一条指令,然后当程序运行到这条指令时,调用调试异常处理例程。INT 3指令的机器码是0xCC,因此无论何时,使用调试器设置一个断点,它都会插入一个0xCC来修改代码。恶意代码常用的一种反调试技术是在它的代码中查找机器码0xCC,来扫描调试器对它代码的INT 3修改。repne scasb指令用于在一段数据缓冲区中搜索一个字节。EDI需指向缓冲区地址,AL则包含要找的字节,ECX设为缓冲区的长度。当ECX=0或找到该字节时,比较停止。

3.2      硬件断点检查

在OllyDbg的寄存器窗口我们可以看到DR0、DR1、DR2、DR3、DR6和DR7这几个寄存器。

DR0、Dr1、Dr2、Dr3用于设置硬件断点,DR4、DR5由系统保留。  DR6、DR7用于记录Dr0-Dr3中断点的相关属性。如果没有硬件断点,那么DR0、DR1、DR2、DR3这4个寄存器的值都为0。

3.3      时钟检测

我们知道机器运行的速度,远远比我们分析代码的速度快得多,利用这个差异性我们找到了用时钟检测来探测调试器存在的方法。记录一段操作前后的时间戳,然后比较这两个时间戳,如果存在滞后,则可以认为存在调试器。

较常用的时钟检测方法是利用rdtsc指令(操作码0x0F31),它返回至系统重新启动以来的时钟数,并且将其作为一个64位的值存入EDX:EAX中。恶意代码运行两次rdtsc指令,然后比较两次读取之间的差值。

3.4      判断STARTUPINFO

explorer.exe创建进程的时候会把STARTUPINFO结构中的值设为0,然而不是explorer.exe创建进程的时候会忽略这个结构中的值,也就是结构中的值不为0。所以可以利用STARTUPINFO来判断程序是否在被调试。



3.5      判断SeDebugPrivilege权限

默认情况下进程是没有SeDebugPrivilege权限的,但是当进程通过调试器启动时,由于调试器本身启动了SeDebugPrivilege权限,所以我们可以检测进程的SeDebugPrivilege权限来间接判断是否存在调试器,而对SeDebugPrivilege权限的判断可以用能否打开csrss.exe进程来判断。

4. 使用异常

4.1      RaiseException

RaiseException函数产生的若干不同类型的异常可以被调试器捕获

4.2     SetUnhandledExceptionFilter

进程中发生异常时若SEH未处理或注册的SEH不存在,会调用UnhandledExceptionFilter,它会运行系统最后的异常处理器。若进程正常运行,则运行最后的异常处理器;若进程处于调试,则将异常派送给调试器。SetUnhandledExceptionFilter函数可以修改系统最后的异常处理器。下面的代码先触发异常,然后在新注册的最后的异常处理器内部判断进程正常运行还是调试运行。进程正常运行时pExcept->ContextRecord->Eip+=4;将发生异常的代码地址加4使得其能够继续运行;进程调试运行时产生无效的内存访问异常,从而无法继续调试。

总结

反调试的手段可以说是五花八门,我这里只是列举了一部分反调试的手段,当我们在逆向过程中碰到他们的时候不要慌张,认真研究肯定可以找到解决的办法,逆向在我看来也就是与创作者的一场战斗,这场战争没有所谓的输赢,创作者会想方设法的阻挠你达到目的,而我们要做的就是对困难死磕到底。



[公告]安全服务和外包项目请将项目需求发到看雪企服平台:https://qifu.kanxue.com

最后于 2019-7-18 20:35 被一谷米粒编辑 ,原因:
最新回复 (19)
上海刘一刀 2 2019-7-16 16:00
2
0
感觉大佬最近很高产啊 厉害厉害
miWusn 2019-7-16 16:13
3
0
涨姿势了
pureGavin 2019-7-16 16:18
4
0
mark,lz辛苦了,正好能用到,就是还没说怎么绕过这些反调试
DeeLMind 2019-7-16 16:25
5
0
大哥辛苦总结了
haovcf 2019-7-17 00:00
6
0
哈哈,有意思。
yy虫子yy 2019-7-17 02:10
7
0
谢谢分享,留个mark
杨开银 2019-7-17 08:32
8
0
666
xuanzee 2019-7-17 09:32
9
0
谢谢分享,留个mark
司马仲达 2019-7-17 10:39
10
0
感谢大佬分享
lookzo 2019-7-17 11:05
11
0
反调试确实又是一门值得研究的艺术
kalikaikai 1 2019-7-17 11:10
12
0
源码留一下?
一谷米粒 2019-7-17 12:56
13
0
kalikaikai 源码留一下?
非常抱歉,这个代码我没有保存的。
MCYMYC 2019-7-17 15:02
14
0
fs寄存器里还有很多方法没列举出来
kalikaikai 1 2019-7-17 17:59
15
0
一谷米粒 非常抱歉,这个代码我没有保存的。
https://bbs.pediy.com/thread-225740.htm  这篇更全 还有代码
minorory 2019-7-18 19:29
16
0
2.3和3.5的图贴错咯,望更正
一谷米粒 2019-7-18 20:36
17
0
minorory 2.3和3.5的图贴错咯,望更正
感谢,图2.3已更正,3.5的图没问题哦
sun setting 2019-7-21 18:58
18
0
谢谢分享,留个mark
编程小白 2019-7-22 10:55
19
0
mark 一下
Mr_heiio 1 2019-7-22 14:47
20
0
mark
游客
登录 | 注册 方可回帖
返回