APP下载

用户态反调试检测模型

2023-09-13颜瑞彬李天洋

计算机工程与设计 2023年8期
关键词:插桩逆向调试

颜瑞彬,高 见,2+,李天洋

(1.中国人民公安大学 信息网络安全学院,北京 100038;2.中国人民公安大学 安全防范与风险评估公安部重点实验室,北京 102623)

0 引 言

近年来,随着软件保护技术不断发展,对于用户态程序的逆向分析越来越困难。逆向分析人员在调试用户态程序时,受到反调试技术、代码混淆、程序加壳等各类软件保护技术的阻碍。在Windows环境下,由于反调试技术种类众多,实现简单,因此,大量用户态程序均通过反调试技术进行加固保护。

在各个领域中,反调试技术虽然保护了用户态程序,但也造成了很多的问题。例如,在网络安全领域中,根据CNCERT互联网安全威胁报告[1],境内大量终端遭到木马的感染或僵尸网络恶意程序的攻击。由于反调试技术存在于木马或恶意程序中,安全人员无法顺利地分析此类用户态程序关键信息。在软件工程领域中,无论是在使用竞品分析技术开发软件时,还是在使用净室技术避免侵犯著作权时,反调试技术的应用均会阻碍逆向分析人员正常分析。因此,如何对抗反调试技术逐渐成为一个亟需解决的问题。现阶段,检测反调试技术的方法并不完善,大量研究均针对几种简单API反调试技术,无法检测其它种类反调试技术。同时,现存的检测反调试技术的框架存在着仅能识别部分反调试技术的问题或经常容易出现误报的情况。

为解决相关问题,本文提出了一种针对Windows操作系统的用户态反调试检测模型。此模型可以检测用户态程序使用的反调试技术的类型和具体位置。用户态反调试检测模型包含4个阶段:插桩筛选、粗过滤、细过滤和插桩验证,主要应用3种技术:①基于Pin插桩的反调试技术检测方法;②基于IDC的反调试检测算法;③基于机器码特征值的反调试检测算法。其中,基于Pin插桩的反调试技术检测方法主要使用Pin插桩技术,基于IDC的反调试检测算法和基于机器码特征值的反调试检测算法主要利用特征值匹配的技术。

1 相关工作

逆向分析技术,是通过反汇编、反编译、调试模拟程序运行等手段,分析现有的二进制可执行文件,得到程序的执行流程、数据结构等文件信息的一项重要技术。在逆向分析技术的研究领域方面,A.M.H.Al-Hakimi等[2]提出一种新的混合混淆加密技术来阻止逆向分析,经过此类混淆加密的代码几乎不会被逆向工具读取。Umair S等[3]在模型驱动逆向工程(model-driven reverse engineering,MDRE)的基础之上提出了一种新型MDRE框架。此框架通过Java语言生成了统一建模语言(unified modeling language,UML)的结构和行为图。Henry WC等[4]介绍了逆向分析人员在逆向分析过程中的困难和挑战,强调了有关逆向工程工具的重要性。Zhang ZY等[5]结合Android系统的安全检查设计,实现了对APP文件的逆向分析技术,介绍了逆向分析技术在操作系统中的重要价值。Sija BD等[6]介绍了协议自动化逆向工程的目标、方法、工具及其研究成果,阐述了协议自动化逆向工程的目标和障碍。

反调试技术是阻止逆向分析者正确定位主函数位置的一项技术,它会引导程序进入错误的执行流中。反调试技术的出现增大了逆向分析者对用户态程序逆向分析的难度。在反调试的研究中,Choi S等[7]介绍了一种混合仿真方案x64Unpack,此方案可以分析和打包可执行文件,并在64位Windows环境中自动解析它们,降低了逆向分析解析难度。Ping C等[8]介绍了恶意软件中使用的反调试技术和虚拟机检测技术,对比分析了普通恶意软件和具有目标的恶意软件所使用的反调试技术和虚拟机检测技术的区别。Shi H等[9]提出了用于对抗反调试的Apate框架,此框架隐藏了WinDbg的调试信息,有效地绕过了大部分的调试技术。Kim JW等[10]介绍了恶意软件在使用反调试技术时常用的5个函数和一个数据结构,并提出了绕过此类反调试技术的方式。Zhang F等[11]提出了MALT的调试框架,MALT框架不依赖于虚拟化或仿真,因此不会受到部分反调试技术的干扰。吴极等[12]分析并汇总了现有的反调试技术及其对应的绕过方法。

Pin插桩作为最流行的动态二进制插桩平台,被广泛应用于逆向分析、程序调试、恶意软件分析等多个领域。Lee YB等[13]首次提出了绕过软件中反VM技术和反DBI技术的算法,通过针对5种最常用的商业保护软件的实验,证明了算法的有效性。在Pin插桩的应用方面,Singh A等[14]开发了一种基于Pin插桩的Mutexis动态检测工具,此工具在较低的内存开销下可以实现动态跟踪。Zeng J等[15]在Pin的基础上,提出了一种PEMU框架。PEMU框架不仅支持用户态程序的二进制追踪,也支持操作系统级别的程序追踪。Zheng B等[16]提出了CBA-Detector精确检测器,它可以实现实时检测基于缓存的侧通道攻击。CBA-Detector精确检测器结合Pintools的指令级监控,可以准确地识别攻击。梁晓兵等[17]提出了一个轻量级的动态插桩解决方案,此方案不再使用动态二进制翻译的方法,并且可以在无源码的条件下完成对信息的动态获取。

2 反调试技术

本文介绍了3类反调试技术,分别是基于WindowsAPI的反调试技术,基于调试器信息的反调试技术与干扰调试器工作的反调试技术。本文解释了上述反调试技术的原理并分析了它们的特征,其结果见表1。

表1 3类反调试技术对比分析

2.1 基于Windows API的反调试技术

2.1.1 IsDebuggerPresent

IsDebuggerPresent是Windows下已公开的API,也是在用户态程序中最常用的API。它通过读取FS段中偏移量为0x30的进程环境块(process environment block,PEB)指针来检测BeingDebugged字段的值。如果有调试器附加,则返回值为1,否则为0。

2.1.2 NtQueryInformationProcess

作为微软未公开的API,它通过提取给定进程的信息检测进程是否被调试。NtQueryInformationProcess的第一个参数是进程句柄,第二个参数是指定特定值并调用该函数,相关信息将会被设置到第三个参数中。

2.1.3 CheckRemoteDebuggerPresent

CheckRemoteDebuggerPresent与IsDebuggerPresent类似,都是Windows公开的API,都会在反调试技术中检测BeingDebugged字段。但是,CheckRemoteDebuggerPresent主要是调用ntdll中的ZwQueryInformationProcess来检测进程是否被另一个独立的同步进程调试。

2.1.4 基于程序状态的APIs

基于程序状态的APIs利用调试时的进程状态,对程序是否有调试器附加进行检测。常用的基于程序状态的APIs主要如下:

(1)反调试技术通过调用OpenProcess,检测是否有权限打开csrss.exe进程,进而检测是否有调试器的附加。

(2)在获取进程信息的相关API中,反调试技术通过调用CreateToolhelp32Snapshot和Process32 Next,获取进程的相关信息,检测是否有调试器附加。

(3)反调试技术通过调用CloseHandle,造成程序抛出异常Invalid Handle(0xC0000008)。

(4)反调试技术也可以调用LoadLibrary、LoadLibraryEx或LdrLoadDll打开任意文件后,再次通过其它API打开此文件,以检测是否有调试器附加。

2.1.5 基于调试行为的APIs

基于调试行为的APIs是利用调试时调试器的行为,检测程序是否有调试器附加。常用的基于调试行为的APIs主要如下:

(1)反调试技术通过修改DbgBreakPoint中的汇编指令,阻止DbgBreakPoint在程序中加入断点,使调试器无法程序断下。

(2)DbgPrint等相关异常处理API与UEF异常处理类似,可以检测是否有调试器附加。

(3)反调试技术通过调用ReadFile可以修改返回地址,导致进程崩溃,实现反调试的效果。

2.2 基于调试器信息的反调试技术

2.2.1 进程信息检测

反调试技术常通过检测BeingDebugged标志,确定该进程是否被调试。反调试技术可以通过fs:[30]找到PEB的基地址,进而确定BeingDebugged标志。IsDebuggerPresent函数的本质就是通过这种方式实现反调试技术的。同样,可以通过汇编语言直接对BeingDebugged标志进行检测。

2.2.2 堆上信息检测

反调试技术可以检测堆上的ProcessHeap和NtGlobalFlag属性。ProcessHeap位于PEB结构体中偏移量0x18处,属性字段主要包括HeapForceFlags和HeapFlags,它们均可用来检测调试信息。NtGlobalFlag位于PEB结构体中偏移量0x68处,该字段的默认值为0,在调试器附加时,该字段会被设置为一个特定的值。

2.2.3 系统痕迹检测

在逆向分析者调试程序时,调试器的附加可能会留下痕迹。最常用的系统痕迹检测包括检测注册表项和检测窗口信息。

2.2.4 父进程检测

Windows系统程序的父进程一般都是explorer.exe。但在调试器附加时,程序的父进程则是调试器进程。因此,可以直接检测程序的父进程以确定是否有调试器附加。同时,在父进程的影响下,也可以通过STARTUPINFO信息或SeDebugPrivilege权限检测程序是否被调试。

2.2.5 时钟检测

调试时代码运行速率要远小于没有调试时的代码运行速率。反调试技术通过两次rdtsc指令比较时间戳的差值,进而判断是否被调试。QueryPerformanceCounter和GetTickCount也可以用来进行时钟检测。

2.2.6 TLS回调检测

TLS回调函数在线程建立或销毁时被调用,而在调试器附加时,调试线程的起点位于kernel32.dll中,这与普通线程不同。基于此,反调试技术可以检测线程的起点,进而确定是否存在调试器的附加。TLS回调函数也会在用户定义的主函数之前被调用,因此,也可以在TLS回调函数中调用其它反调试技术检测程序是否有调试器附加。

2.3 干扰调试器工作的反调试技术

2.3.1 异常处理

反调试技术中,常用RaiseException函数、UEF以及interrupt 3断点等方式干扰调试器工作。其中,在UEF异常处理中,如果程序通过SetUnhandledExceptionFilter函数设置了UEF,在调试器附加时,UEF不会被调用。另外,调用GenerateConsoleCtrlEvent时,查看程序是否会抛出EXCEPTION_CTL_C异常,进而检测程序是否被调试器附加。

2.3.2 调试器漏洞

用户态程序编写者有时通过调试器漏洞阻止分析人员进行调试,这类反调试手段通常针对Ollydbg。例如,如果设置的DataDirectory数组元素个数超过0x10,Ollydbg会自动退出。其它有关通过调试器漏洞实现反调试技术的方法与之类似。

2.3.3 步过(step over)失效

逆向分析人员在动态分析遇到汇编指令call或rep时,常常使用F8步过该汇编指令。在这种情况下,调试器会将0xCC断点设置在call或rep汇编指令的下一个汇编指令的位置。反调试技术可以检测下一条指令是否为0xCC,判断是否有调试器附加。

2.3.4 输入设备封锁

有关键盘封锁的反调试经常通过BlockInput实现。BlockInput会阻止键盘、鼠标等输入设备对该进程的输入,因此,调试器将无法使用F7、F8等调试命令进行动态调试。此外,SwitchDesktop也可以阻止键盘、鼠标事件传递给调试器,阻止分析人员的正常调试。

3 反调试检测算法与模型

传统的反调试检测大多是通过IDA pro的导入表,手动分析程序中使用的反调试技术。在使用大量反调试技术的用户态程序中,确定此程序使用的反调试技术比较困难。因此,本文提出了一种基于Pin插桩的反调试检测技术,以判断用户态程序是否使用反调试技术。同时,提出了两种特征值检测技术,分析并确定用户态程序使用反调试技术的种类和具体位置。

基于Pin插桩的反调试检测技术是通过检测主函数中call指令数量与ret指令数量是否相同,进而确定程序是否使用了反调试技术。基于IDC的反调试检测技术是通过IDA导出IDC-Database,在IDC-Database中遍历程序所调用的API以及相关函数,并依次与特征库进行对比,进而判断反调试技术的种类,定位调用反调试技术的位置。基于机器码特征值的反调试检测技术是对于可执行程序的机器码进行检测。可执行程序中,同样的反调试技术在对应位置具有相同或类似的机器码。基于此,检测算法将程序中的机器码依次与机器码库中的反调试特征机器码进行对比,进而确定反调试技术种类和位置。

同时,本文基于3种反调试检测技术提出了反调试检测模型。该模型分为插桩筛选、粗过滤、细过滤、插桩验证4部分,可以批量自动化检测用户态程序是否存在反调试技术,判断使用的反调试技术种类,并定位反调试技术的具体位置。

3.1 反调试检测模型

反调试检测模型以3种反调试检测技术为基础,由插桩筛选、粗过滤、细过滤、插桩验证4部分构成。上述3种反调试检测技术在单独使用时,存在着准确率不高、输出结果不理想等问题,无法获得逆向分析人员希望得到的结果。因此,反调试检测模型结合并改进了上述3种反调试检测技术,通过动态和静态的两个角度,检测程序是否含有反调试技术。反调试检测模型的框架如图1所示。

图1 反调试检测模型框架

反调试检测模型的插桩筛选模块主要使用基于Pin插桩的反调试检测技术(详见3.2节)。它将程序集合中含有反调试技术的程序筛选出来,作为第二部分的输入。此模块以待检测程序作为输入,通过Pin插桩程序动态监控,检测call指令数量与ret指令数量是否一致,进而确定程序中是否含有反调试技术。如果call指令数量与ret指令数量相同,则将此程序认定为不含有反调试技术的程序,并将其筛除;否则,将此程序认定为含有反调试技术的程序,并将其输入到粗过滤阶段。由于插桩筛选运行速度较快,可以快速排除掉不含有反调试技术的程序,减少了反调试检测模型中后续过滤过程的运行时间,降低了整体的时间复杂度。

粗过滤作为模型的第二部分,它是以基于IDC的反调试检测(算法1)为基础。其输入为筛选后含有反调试技术的程序。粗过滤主要通过IDC检测程序中是否含有反调试相关函数,并定位反调试函数在函数表中的具体位置。粗过滤中,主要以静态的方式定位反调试函数,获取与反调试技术相关的API名称和其在函数表中的具体位置,为反调试检测模型中的细过滤提供基础。

细过滤是此模型检测的核心。它结合了基于机器码特征的反调试检测(算法2)。原始机器码库以机器码形式存储了二进制层面上的反调试技术。在细过滤时,将粗过滤中获取到的与反调试技术相关的API的位置和名称作为机器码库的一部分,通过机器码库与原程序机器码进行逐一对比,确定此程序是否使用了反调试技术。机器码库不仅包含了相关API的位置和名称,还存储了与反调试技术相关的机器码。例如,反调试技术检测BeingDebugged标志时,机器码通常是固定的,此段机器码将存储在机器码库中。对于反调试技术相关API,32位程序可以直接使用函数表中的反调试函数位置。而64位程序需要时刻计算当前机器码位置与函数表中的反调试函数位置的差值,进而将差值作为机器码库的一部分。由于机器码特征的唯一性,细过滤可以较为准确地过滤掉不含有反调试技术的程序,并在存在反调试技术的程序中,判断和定位反调试技术的类型和位置。

插桩验证是此模型的最后一部分,其目的为自动化动态验证程序是否在特定位置使用了反调试技术。它同样以Pin插桩工具为基础,动态监控程序的运行。插桩位置选择在过滤阶段获取到的反调试技术具体位置,将动态检测过程中获取到的机器码或函数特征,与细过滤阶段静态检测得到的反调试技术特征进行对比,确定反调试技术检测是否正确。由于用户态程序很难在动态监控下隐藏反调试技术,因此,插桩验证为反调试技术检测模型在准确性上提供了可靠的保障。

3.2 基于Pin插桩的反调试检测

Pin是Intel提出的动态二进制插桩工具,它可以动态地监控程序的每一步运行。在程序正常运行时,call指令将改变IP寄存器的位置,进而完成函数调用。ret指令在程序调用结束时,将改变IP寄存器,程序将返回到call指令调用前IP寄存器的位置,相关示例如图2(a)所示。因此,主函数中的call指令数量与ret指令数量是一样的。然而,反调试技术通常使程序直接退出。在图2(b)所示的示例中,如果用户态程序属于调试状态,那么将进入函数function1中。程序在函数function1中调用了exit()函数,进而直接退出主程序,使得主函数中的call指令数量与ret指令数量不同。

基于Pin插桩的反调试检测是通过Pin插桩技术,动态检测主函数的call指令数量与ret指令数量是否相同,初步筛选出含有反调试技术的程序。基于Pin插桩的反调试检测流程如图3所示。

图3 基于Pin插桩的反调试检测流程

检测框架如下:

(1)输入:存在调试状态的待检测程序、Pin插桩程序、call指令计数器、ret指令计数器。

(2)检测:通过Pin插桩程序找到待检测程序主函数位置,动态监控待检测程序,即只检测主函数的执行流。在遇到call指令时,call指令计数器自增;在遇到ret指令时,ret指令计数器自增。最后,将call指令计数器的值与ret指令计数器的值进行对比。

(3)输出:如果call指令计数器的值与ret指令计数器的值相同,将程序标记为不含有反调试技术程序;否则,将程序标记为含有反调试技术程序。

基于Pin插桩的反调试检测可以初步确定程序中是否含有反调试技术,其检测速度快,效率高。

3.3 基于IDC的反调试检测

基于IDC的反调试检测是一种特征值检测技术,其原理为检测导出的IDC-Database文件中,是否存在与反调试API或调用函数相关的字符串信息,进而确定程序调用的反调试技术并定位到具体位置,算法如下所示:

算法1:IDC-based Anti-debugging Detection

Input: Programme Function In IDC-Database: X={x1,x2,…,xn}

Output: Anti-debugging Feature: F={f1,f2,…,fn}

(1)FunctionIDC_add(X, Feature_db):

(2)fori ← 1 to Xdo

(3)ifstr_name → Feature_dbdo

(4) name ←GetFunctionName(str_name)

(5) func_addr ←Funcaddr(str_name)

(6)endfor

(7)forj ← 1 tolen(name, func_addr)do

(8) Ad_feature[j].key ← name[j]

(9) Ad_feature[j].value ← func.addr[j]

(10)endfor

(11)returnAd_feature

第(2)~第(6)行遍历扫描待检测程序的IDC文件,将主函数中出现过的函数名与反调试函数检测库进行对比。如果主函数的函数名和反调试函数检测库中的函数名一致,则标记其函数名和函数在程序中的地址。第(7)~第(10)行对标记的地址与函数名存入特征库,并将上述符合要求的函数名与地址以键值对的形式作为输出。

在单独使用此算法时,为了更准确地确定用户态程序使用了哪些反调试技术,可以通过函数地址找到对应API并检测其是否起到了反调试的作用。此类反调试检测方法计算效率高,可以准确定位到与反调试相关的API或调用函数的具体位置。

3.4 基于机器码特征值的反调试检测

在大多数反调试使用时,其机器码是固定且唯一的。基于此种情况,机器码特征值反调试检测方法将用户态程序的机器码匹配有关反调试技术的机器码,进而确定是否使用此种反调试技术。由于其机器码的固定性与唯一性,几乎无需手动检查便可以确定该恶意程序是否使用了某种反调试技术。其算法如下所示:

算法2:Machine Code Feature Anti-debugging Detection

Input: Programme Sample: X={x1,x2,…,xn}

Output: Anti-debugging Feature: F={f1,f2,…,fn}

(1)FunctionBinary_add(X, Feature_binary):

(2)fori ← 1 to Xdo

(3)ifprogram_bytes → Feature_binarydo

(4)forj ← 1 tolen(Feature_binary)do

(5)ifprogramme_bytes → Feature_binarydo

(6) programme_bytes = program_bytes + 1

(7)elsebreak

(8)ifj ==len(Feature_binary)do

(9) Ad_addr ←Findaddr(programme_bytes-len(Feature_binary))

(10) Ad_function ←Findfunc(Ad_addr)

(11)endfor

(12) programme_bytes = 0

(13)endfor

(14)returnAd_function

第(2)~第(3)行,遍历扫描待检测程序的二进制,并将主程序的每个字节依次与反调试机器码库进行对比。第(4)~第(11)行,如果程序某位置的首字节与反调试技术机器码库中某段的首字节相同,继续对比反调试技术机器码库中此段后几位字节是否也同样依次出现在程序此位置中。如果同样出现,则将此函数及其位置存入特征库中,否则继续遍历主程序。

因为很难出现机器码序列一致但程序行为不同的情况,所以此类反调试检测技术具有较高的准确性。另外,在检测用户态程序时,我们常通过结合算法1与算法2的方式提高检测的准确率与效率。

4 实验与分析

本文实验分为两部分。其一,本文通过算法1与算法2展开了初步实验。初步实验可以确定两种算法的有效性,并为主体实验提供基础。其二,本文基于用户态反调试检测模型展开了主体实验。主体实验通过用户态反调试检测模型对3类真实程序进行检测,得到的检测结果可以验证用户态反调试检测模型的准确率与检测效率。另外,本文主体实验得到了真实代码中反调试技术使用分布情况,可以有效地预测其它种类的用户态程序中反调试技术使用分布情况。

4.1 实验数据

本文主体实验所用的程序和源代码来自3部分。分别是Github中Anti-debugging相关源代码、bazaar.abuse.ch真实恶意代码[18]以及Windows系统内程序样例。在Github中Anti-debugging相关源代码包含多种反调试技术。实验中,对源代码编译后形成的PE文件进行检测。Bazaar.abuse.ch收录了实时的恶意代码样本,本文样本选取的时间范围以2021年7月与8月为主。实验数据的分布情况见表2。

表2 实验数据分布

4.2 实验环境

本文实验的环境为Windows10 64位操作系统、IDA pro 7.5,初步实验的待检测程序为code.exe 64位、WeChat.exe 32位。

主体实验中部分代码由32位的Microsoft Visual C/C++(MSVC)编译器或64位Minimalist GNU for Windows(MINGW)编译器编译。实验平台具体参数见表3。

表3 实验平台参数

4.3 评价标准

本文通过实验程序的正检测率(true detection rate,TDR)、负检测率(false detection rate,FDR)、误报率(false alarm rate,FAR)以及各项反调试技术使用率(antidebug usage rate,AUR)进行分析。具体公式如下所示

TDR=含有并检测出反调试的样本数样本总数×100%

(1)

FDR=含有但未检测出反调试的样本数样本总数×100%

(2)

FAR=不含有但检测出反调试的样本数样本总数×100%

(3)

AUR=程序中含有并检测出反调试总数样本总数×1007

(4)

TDR、FDR和FAR可以衡量上述反调试技术的可实现性与准确性。AUR可以衡量部分用户态程序中的反调试技术比例且在一定程度上可以预测用户态程序中常用的反调试种类。另外,如果程序不含有反调试技术,模型也未检测到反调试技术,则在计算时忽略此程序。因为此类程序在实验中没有现实意义。

4.4 实验结果与分析

首先,通过算法1对code.exe中进行检测。在建立由反调试API函数构成的检测库后,通过算法1将code.exe导出的IDC文件中的API与检测库的API进行比对,得到code.exe中反调试技术相关API的种类和具体位置。但是,算法1得到的结果仅代表了code.exe存在使用此反调试技术的可能。算法1对code.exe的部分检测结果见表4。

表4 code.exe实验结果

在此实验中,检测了code.exe中一部分与反调试相关API,确定并定位了API的种类和具体位置。为了更准确地确定用户态程序中使用的反调试技术的种类,可以在IDA中通过函数地址找到对应API并检测其是否起到了反调试的作用。

另外,本文通过算法2对WeChat.exe中部分反调试技术进行检测。首先,通过反调试技术的机器码特征建立机器码库。在检测反调试技术相关API时,API函数在程序中的位置也需要导入机器码库中。然后,通过算法2将WeChat.exe的主函数中的二进制流与机器码库的机器码特征值进行比对,得到最终的检测结果。其部分结果见表5。

表5 WeChat.exe实验结果

此实验检测了WeChat.exe中部分反调试技术,通过算法2可以快速确定并定位反调试技术的种类和位置,且无需进行手动验证。在批量使用反调试技术时,通过算法2进行检测具有更高的效率和准确率。

本文主体实验通过用户态反调试检测模型对3类程序的反调试使用情况进行检测。首先,通过基于Pin插桩的反调试检测方法快速筛选出含有反调试技术的程序。其次,构建由反调试技术API构成的检测库,并通过算法1对这3类程序进行粗过滤,初步得到反调试技术相关API的种类和具体位置。然后,构建机器码库,并将得到的反调试技术相关API的信息导入机器码库中。通过算法2对这3类程序进行细过滤,得到准确的反调试技术相关API的种类和具体位置。最后,对用户态程序进行插桩验证,判断程序是否在获取到的位置中使用了对应的反调试技术。其结果见表6。

表6 反调试使用情况

由于现阶段暂时没有开源的反调试技术检测方法与本文结果进行对比。因此,为验证本文提出的检测方法,将多名逆向分析人员手动调试结果与实验结果进行对比,得到最终结果。检测结果与手动调试分析结果部分不一致的可能的原因包括:①用户态反调试检测模型检测到的反调试技术被使用,但是并没有阻碍逆向分析人员的正常分析过程,也就是没有起到反调试的作用;②用户态反调试检测模型在构建检测库和机器码库时遗漏了部分反调试技术的特征。

实验结果表明,用户态反调试检测模型在检测反调试技术时效果较好,具有较高的准确率。另外,该模型在不同类型的程序中表现情况不完全一致。Windows系统内程序样例的反调试技术使用较少,其检测结果不如较多使用反调试技术的真实恶意代码。

最后,本文实验通过上述相同的方法检测了部分反调试技术的使用分布情况,其结果见表7。

表7 使用分布情况

从实验结果中可以看出IsdebuggerPresent经常被应用在反调试技术中。这是由于此种反调试技术的实现最为容易,且阻碍逆向分析人员正常逆向分析的效果好,很多情况下,程序编写者会在主程序中加入此种反调试技术。

从整体上看,本文提出的算法和用户态反调试检测模型可以有效并准确地检测出反调试的使用情况。另外,通过反调试技术分布情况,可以初步得出部分用户态程序中各类反调试技术的应用情况。逆向分析人员可以使用本文提出的用户态反调试检测模型,对Golden Eye、Petya等主流恶意程序展开有关反调试技术使用情况、反调试技术分布情况等相关实验检测。

5 结束语

本文提出了一种用户态反调试检测模型,此模型通过插桩筛选、粗过滤、细过滤以及插桩验证,可以有效地检测出用户态程序中使用的反调试技术的类型和位置。用户态反调试检测模型使用了Pin插桩技术以及基于特征值匹配的反调试检测算法。实验结果表明,用户态反调试检测模型具有较高的准确性。另外,在使用大量反调试技术的程序中,此模型表现出更高的准确性。

总的来讲,用户态反调试检测模型可以系统化分析并定位用户态程序所使用的反调试技术,降低了逆向分析人员对用户态程序逆向分析的困难。下一步工作将在较小的时间复杂度和较高的准确率下,实现对用户态程序反调试技术检测的完全自动化。另外,在网络安全领域中,越来越多的恶意软件由GAN等机器学习模型生成[19],如何对抗此类恶意软件中反调试、代码混淆等技术同样是亟需解决的问题。

猜你喜欢

插桩逆向调试
逆向而行
基于TXL的源代码插桩技术研究
基于性能分析的自适应插桩框架
基于航拍无人机的设计与调试
FOCAS功能在机床调试中的开发与应用
基于记录重播的嵌入式系统死锁检测方法
无线通信中频线路窄带临界调试法及其应用
调压柜的调试与试运行探讨
基于顺序块的嵌入式白盒测试插桩技术研究
逆向工程技术及应用