CN113760770A - 基于自动静态资源检测的反调试方法和系统 - Google Patents

基于自动静态资源检测的反调试方法和系统 Download PDF

Info

Publication number
CN113760770A
CN113760770A CN202111072744.0A CN202111072744A CN113760770A CN 113760770 A CN113760770 A CN 113760770A CN 202111072744 A CN202111072744 A CN 202111072744A CN 113760770 A CN113760770 A CN 113760770A
Authority
CN
China
Prior art keywords
application program
suspicious
debugger
abnormal
debugged
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Pending
Application number
CN202111072744.0A
Other languages
English (en)
Inventor
舒娟
夏玉明
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Information and Data Security Solutions Co Ltd
Original Assignee
Information and Data Security Solutions Co Ltd
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Information and Data Security Solutions Co Ltd filed Critical Information and Data Security Solutions Co Ltd
Priority to CN202111072744.0A priority Critical patent/CN113760770A/zh
Publication of CN113760770A publication Critical patent/CN113760770A/zh
Pending legal-status Critical Current

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/36Preventing errors by testing or debugging software
    • G06F11/362Software debugging
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F18/00Pattern recognition
    • G06F18/20Analysing
    • G06F18/23Clustering techniques

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Data Mining & Analysis (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • General Engineering & Computer Science (AREA)
  • Bioinformatics & Cheminformatics (AREA)
  • Evolutionary Biology (AREA)
  • Evolutionary Computation (AREA)
  • Computer Vision & Pattern Recognition (AREA)
  • Bioinformatics & Computational Biology (AREA)
  • Artificial Intelligence (AREA)
  • Life Sciences & Earth Sciences (AREA)
  • Computer Hardware Design (AREA)
  • Quality & Reliability (AREA)
  • Debugging And Monitoring (AREA)

Abstract

本发明提供了一种基于自动静态资源检测的反调试方法和系统,包括特定访问规则的设计,对不同操作系统和框架的函数对应参数值建立授信专家资源关系库;主检测,应用程序启动时,通过特定访问规则检测文件是否有修改,即判断应用程序是否符合授信专家资源关系库,符合视为正常访问,直接打开应用程序,不符合则视为可疑行为,将对应的可疑行为或异常行为放入可疑样本库或异常样本库,将不匹配这两个库的静态资源使用隐马尔可夫模型自动分析是否存在可疑调试器,判定该未知行为对程序影响的风险概率;判断为可疑样本或异常样本后均触发代码混淆。本发明使用检测和混淆的方式保护应用程序,达到自动阻扰或延长未知程序威胁和调试器调试的时长。

Description

基于自动静态资源检测的反调试方法和系统
技术领域
本发明涉及计算机软件安全领域,尤其涉及一种应用程序的反调试方法和系统。
背景技术
随着大数据时代和人工智能的发展,互联网产业规模持续增长,应用程序安全问题日益引起重视,恶意软件威胁日益增多。程序员缺乏对软件的保护意识,或只依赖加壳软件加壳保护,以下2篇专利文献公开了加壳保护方法。
如申请号为201710550655.X的专利文献公开了一种加壳工具的测试方法,主要针对目前加壳工具测试的高强度工作提出的新的测试方法,其中提到了加壳工具对于样本的具体加壳方式不限定是:压缩加壳、名称混淆加壳、资源段加密加壳以及精简加壳中的一种。其中,名称混淆加壳是指对源程序中的函数名称进行混淆,以至于静态反编译工具显示的函数名为乱码。
如申请号为201811106444.8的专利文献提供了一种代码混淆方法,该方法针对现有保护应用程序时,对应用程序的源代码进行混淆,导致应用程序的体积增大及性能较差的问题。具体地,所述代码混淆方法包括获取目标应用程序的源代码文件,在对所述源代码文件进行编译的过程中,确定所述内置函数中选定的待混淆的常量字符串,作为目标常量字符串;对所述目标常量字符串进行混淆处理。
而现有这些加壳包括混淆加壳也并非安全,因为针对加壳有专门的脱壳工具。因此应用程序容易被逆向人员通过调试器破解。
调试器是先自动分析其中的库函数和API函数,并将识别出的函数名替换到函数列表中。未能识别或识别错误的代码进行手工分析其参数类型、参数个数、起始位置、结束位置、调用方式等,并对相应参数进行非法修改。
围绕确保应用程序安全分为静态反调试和动态反调试。静态反调试是使用系统提供的应用程序接口、使用痕迹检测、检测父进程等人工检测,在调试开始阻拦调试者,需要专门的人员,遇到高阶版调试器或大量分析的文件时,耗费时间长和需要加入更多人员。
以手动检查ProcessHeap为例,对破解方式具体说明如下:
1.通过判断PEB.ProcessHeap中具体的标志位来确定是否被调试;
2.对应不同的系统,标志位所在的偏移可能也不同,通过dt_HEAP可以查看到当前系统中具体所在的位置;
3.Flags与ForceFlags在正常情况下应为2与0,如果是被附加状态,那么无法判断当前是否被调试;
4.通过修改具体的字段进行反调试。
这种手动检查的方式耗时长,需要更多的人员参与。
综上,现有反调试技术存在的不足:
现有加壳方式防止应用程序被调试,壳的特征也很明显,比如在内存中能找到对应的内存段,容易借助工具查壳脱壳。增加大量的混淆指令,程序的打开速度变慢,降低了运行效率影响用户体验,也可能导致原程序报错。静态反调试耗时长且需要更多的人员。
发明内容
本发明所要解决的技术问题在于如何保护程序从而将应用程序风险降至最低且不影响运行效率。
本发明通过以下技术手段实现解决上述技术问题的:
一种基于自动静态资源检测的反调试方法,包括:
步骤S1、特定访问规则的设计,通过对不同操作系统和框架如x86、x64的函数对应参数值等建立授信专家资源关系库,使应用程序在正常启动时不受混淆代码影响;
步骤S2、主检测,应用程序启动时,会加载PE文件,通过特定访问规则检测文件是否有修改,即判断应用程序是否符合授信专家资源关系库,符合视为正常访问,直接打开应用程序,如果不符合授信专家资源关系库,则视为可疑行为,监听可疑静态资源,并建立调试器可疑样本库和调试器异常样本库,将对应的可疑行为或者异常行为放入可疑样本库或异常样本库,并且将不匹配这两个库的静态资源使用隐马尔可夫模型自动分析是否存在可疑调试器,判定该未知行为对程序影响的风险概率;
步骤S3、代码混淆,如果经过步骤S2判断为可疑样本或异常样本后触发代码混淆,扰乱反调式程序的关键值。被修改替换的目标指令最终形成的字节码有前后相关性,即改变其他任意一个字节会影响到所有被虚拟化的指令混淆代码模块其实是一个字节码解释器,循环的读取指令并执行,并且只有一个入口和一个出口,虚假跳转和垃圾指令,混淆代码会使用大量的虚拟跳转和垃圾指令将原有简单的代码变得复杂。
本发明使用首先设计特定访问规则、检测和混淆的方式保护应用程序,达到自动阻扰或延长未知程序威胁和调试器调试的时长。当检测出正常访问(处于非调试状态)时,直接打开应用程序,正常合规访问程序时对程序打开速度延时几乎可忽略,提高了运行效率,具有良好的用户体验。判断为可疑调试器时,加入混淆代码插件对代码加固,保护程序,增强软件安全。
作为进一步优化的技术方案,步骤S1中,特定访问规则是将PE结构体、调试器函数、接口函数作为特征因子,预设特征因子对应的标志位状态码,值为布尔变量,如果标志位状态码赋值为0,则判定为未获取到调试器,标志位状态码赋值为1,则判定为获取到调试行为,或者预设特征因子的阈值,特征因子低于阈值,则判定为未获取到调试器,高于阈值,则判定为获取到调试行为,或者预设特征因子的值,如果特征因子与预设的值匹配,则判定为未获取到调试器,如果特征因子与预设的值不匹配,则判定为获取到调试行为。
作为进一步优化的技术方案,所述步骤S2主检测具体包括下述步骤:
步骤S21、使用特定访问规则检查PE格式的文件头,以判定应用程序是否符合授信专家资源关系库里预先存储的特定访问规则;
步骤S22、应用程序符合授信专家资源关系库的特定访问规则时,判定为正常访问,直接打开应用程序,如果不符合特定访问规则,进入步骤S23;
步骤S23、检测应用程序是否符合异常样本库或可疑样本库,如果符合异常样本库,判定为应用程序被调试,如果符合可疑样本库,判定为应用程序疑似被调试,当判定应用程序被调试或疑似被调试时,均进入步骤S3,如果应用程序不符合异常样本库或可疑样本库,进入步骤S24;
步骤S24、使用隐马尔可夫模型检测可疑概率,根据检测结果判定是否启动代码混淆防御机制,需要启动混淆防御的进入步骤S3,同时将检测结果对应添加到授信专家资源关系库、或可疑样本库、或异常样本库。
作为进一步优化的技术方案,步骤S24的具体实现步骤如下:
步骤S241、将待检测库中的每组静态资源构造训练样本集,用静态资源构造隐马尔可夫模型参数λ={A,B,π},π为初始状态向量,A为状态转移概率矩阵,B为观测概率矩阵;
步骤S242、对隐马尔可夫模型参数中的每组静态资源采用K均值聚类算法进行聚类;
步骤S243、设定静态资源内容的阈值或布尔值,通过对静态资源内容返回布尔值结果或是否超出阈值进行判定是否为异常行为,如状态码为设定布尔值或者未超出设定阈值,则判定应用程序没有被调试,直接打开应用程序,如果状态码为设定布尔值或者超出设定阈值,则说明应用程序正在被调试,进入步骤S3;
步骤S244、经过步骤S243判定的应用程序没有被调试的行为加入授信专家资源关系库,经过步骤S243判定的应用程序被调试的行为加入异常样本库,经过步骤S243无法判定的样本本身不可疑或恶意的活动,但与其他指令或函数结合时,可能表明存在可疑调试或恶意行为,则加入可疑样本库,以不断的扩展样本库。
作为进一步优化的技术方案,该基于自动静态资源检测的反调试方法还包括步骤S4:检测,执行完步骤S1至S3的反调试方法后,将应用程序调试,如果程序在被调试时出现异常,则该基于自动静态资源检测的反调试方法有效,如果应用程序在被调试时未出现异常,需要确认系统是否处在调试环境中,需要在特定规则中预设系统环境相关函数成员,然后循环执行步骤S1至S3。
本发明还提供一种基于自动静态资源检测的反调试系统,包括
特定访问规则设计模块,用于特定访问规则的设计,对不同操作系统和框架的函数对应参数值建立授信专家资源关系库;
主检测模块,用于在应用程序启动时,通过特定访问规则检测文件是否有修改,即判断应用程序是否符合授信专家资源关系库,符合视为正常访问,直接打开应用程序,如果不符合授信专家资源关系库,则视为可疑行为,监听可疑静态资源,并建立调试器可疑样本库和调试器异常样本库,将对应的可疑行为或者异常行为放入可疑样本库或异常样本库,并且将不匹配这两个库的静态资源使用隐马尔可夫模型自动分析是否存在可疑调试器,判定该未知行为对程序影响的风险概率,判定应用程序被调试或疑似被调试时均进入混淆代码逻辑模块;
混淆代码逻辑模块,用于将通过主检测模块判断为存在可疑调试器的应用程序加入混淆代码逻辑。
作为进一步优化的技术方案,特定访问规则设计模块中,特定访问规则是将PE结构体、调试器函数、接口函数作为特征因子,预设特征因子对应的标志位状态码,值为布尔变量,如果标志位状态码赋值为0,则判定为未获取到调试器,标志位状态码赋值为1,则判定为获取到调试行为,或者预设特征因子的阈值,特征因子低于阈值,则判定为未获取到调试器,高于阈值,则判定为获取到调试行为,或者预设特征因子的值,如果特征因子与预设的值匹配,则判定为未获取到调试器,如果特征因子与预设的值不匹配,则判定为获取到调试行为。
作为进一步优化的技术方案,主检测模块包括:
检查单元,使用特定访问规则检查PE格式的文件头,以判定应用程序是否符合授信专家资源关系库里预先存储的特定访问规则;
授信专家资源关系库判定单元,应用程序符合授信专家资源关系库的特定访问规则时,判定为正常访问,直接打开应用程序,如果不符合特定访问规则,进入异常样本库或可疑样本库判定单元;
异常样本库或可疑样本库判定单元,检测应用程序是否符合异常样本库或可疑样本库,如果符合异常样本库,判定为应用程序被调试,如果符合可疑样本库,判定为应用程序疑似被调试,当判定应用程序被调试或疑似被调试时,均进入混淆代码逻辑模块,如果应用程序不符合异常样本库或可疑样本库,进入隐马尔可夫模型检测单元;
隐马尔可夫模型检测单元,使用隐马尔可夫模型检测可疑概率,根据检测结果判定是否启动代码混淆防御机制,需要启动混淆防御的进入混淆代码逻辑模块,同时将检测结果对应添加到授信专家资源关系库、或可疑样本库、或异常样本库。
作为进一步优化的技术方案,隐马尔可夫模型检测单元具体检测方法如下:
将待检测库中的每组静态资源构造训练样本集,用静态资源构造隐马尔可夫模型参数λ={A,B,π},π为初始状态向量,A为状态转移概率矩阵,B为观测概率矩阵;
对隐马尔可夫模型参数中的每组静态资源采用K均值聚类算法进行聚类;
设定静态资源内容的阈值或布尔值,通过对静态资源内容返回布尔值结果或是否超出阈值进行判定是否为异常行为,如状态码为设定布尔值或者未超出设定阈值,则判定应用程序没有被调试,直接打开应用程序,如果状态码为设定布尔值或者超出设定阈值,则说明应用程序正在被调试,进入混淆代码逻辑模块;
判定应用程序没有被调试的行为加入授信专家资源关系库,判定应用程序被调试的行为加入异常样本库,无法判定的样本本身不可疑或恶意的活动,但与其他指令或函数结合时,可能表明存在可疑调试或恶意行为,则加入可疑样本库,以不断的扩展样本库。
作为进一步优化的技术方案,该基于自动静态资源检测的反调试系统还包括检测模块,用于将应用程序调试,如果程序在被调试时出现异常,则该基于自动静态资源检测的反调试方法有效,如果应用程序在被调试时未出现异常,需要确认系统是否处在调试环境中,需要在特定规则中预设系统环境相关函数成员,然后循环执行特定访问规则设计模块、主检测模块以及混淆代码逻辑模块。
本发明的优点在于:
(1)使用检测和混淆的方式保护应用程序,达到自动阻扰或延长未知程序威胁和调试器调试的时长。
(2)预先设计特定访问规则,建立授信专家资源关系库,正常合规访问程序时对程序打开速度延时几乎可忽略,提高了运行效率,具有良好的用户体验。
(3)判断为可疑调试器时,加入混淆代码插件对代码加固,保护程序,增强软件安全。
(4)因为基于自动静态资源检测的反调试方法,极大减少了静态反调试时间,且人员需求大大减少。
附图说明
图1为本发明中的基于自动静态资源检测的反调试方法的机制示意图;
图2为本发明中的基于自动静态资源检测的反调试方法的主检测方法示意图;
图3为本发明中使用隐马尔夫模型检测可疑调试行为的流程图;
图4为适用于静态分析的混淆代码方式示意图;
图5为静态动态分析通用的混淆代码方法示意图。
具体实施方式
为使本发明实施例的目的、技术方案和优点更加清楚,下面将结合本发明实施例,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
如图1和图2所示,本发明提供一种基于自动静态资源检测的反调试方法,包括:
步骤S1、特定访问规则的设计,通过对不同操作系统和框架如x86、x64的函数对应参数值等建立授信专家资源关系库,使应用程序在正常启动时不受混淆代码影响。
特定访问规则是将PE结构体、调试器函数、接口函数等作为特征因子,预设特征因子对应的标志位状态码,标志位状态码的值为布尔变量,如果标志位状态码赋值为0,则判定为未获取到调试器,标志位状态码赋值为1,则判定为获取到调试行为,或者预设特征因子的阈值,特征因子低于阈值,则判定为未获取到调试器,高于阈值,则判定为获取到调试行为,或者预设特征因子的值,如果特征因子与预设的值匹配,则判定为未获取到调试器,如果特征因子与预设的值不匹配,则判定为获取到调试行为。
特定访问规则是规则集合,解释为多个规则集。其中包括上述PE结构体规则集、调试器函数规则集、接口函数规则集等等,规则集因系统环境等因素定制添加。
步骤S2、主检测,应用程序启动时,会加载PE文件,通过特定访问规则检测文件是否有修改,即判断应用程序是否符合授信专家资源关系库,符合视为正常访问,直接打开应用程序,如果不符合授信专家资源关系库,则视为可疑行为,监听可疑静态资源,并建立调试器可疑样本库和调试器异常样本库,将对应的可疑行为或者异常行为放入可疑样本库或异常样本库,并且将不匹配这两个库的静态资源使用隐马尔可夫模型自动分析是否存在可疑调试器,判定该未知行为对程序影响的风险概率。
具体包括下述步骤:
步骤S21、使用特定访问规则检查PE格式的文件头,以判定应用程序是否符合授信专家资源关系库里预先存储的特定访问规则;
步骤S22、应用程序符合授信专家资源关系库的特定访问规则视为正常访问,直接打开应用程序,如果不满足特定访问规则,进入步骤S23;
步骤S23、检测应用程序是否符合异常样本库或可疑样本库,如果符合异常样本库,判定为被调试,如果符合可疑样本库,判定为疑似被调试,均进入步骤S3,如果否,进入步骤S24;
步骤S24、如果检测不属于授信专家资源关系库、可疑样本库、异常样本库,则放入待检测库,使用隐马尔夫模型检测可疑概率,根据监测结果判定是否启动代码混淆防御机制,需要启动混淆防御的进入步骤S3,隐马尔可夫模型异常指标识别由隐藏的马尔可夫链生成状态序列,再由状态序列生成观测序列,隐马尔可夫模型的检测结果同时也添加到授信专家资源关系库、可疑样本库、异常样本库,将不断的扩展样本库同时支持人工核查。
如图3所示,具体实现步骤如下:
步骤S241、将待检测库中的每组静态资源,如汇编指令、PE结构体构造训练样本集,用静态资源构造隐马尔可夫模型参数λ={A,B,π},π为初始状态向量,A为状态转移概率矩阵,B为观测概率矩阵;
步骤S242、对隐马尔可夫模型参数中的每组静态资源采用K均值聚类算法进行聚类;
步骤S243、设定静态资源内容的阈值或bool(布尔)值,通过对静态资源内容返回布尔值结果或是否超出阈值进行判定是否为异常行为,具体为使用偏移矩阵,获取到静态资源的内容,获取内偏移变量如(+0x18),利用前向后向算法判断偏移矩阵的值是否异常。如下表所示,如判定结果为0(状态码为设定布尔值或者未超出设定阈值),则判定应用程序没有被调试,直接打开应用程序,如果输出结果为1(状态码为设定布尔值或者超出设定阈值),则说明应用程序正在被调试,进入步骤S3;
Figure BDA0003261000820000081
步骤S244、经过步骤S243判定的应用程序没有被调试的行为加入授信专家资源关系库,经过步骤S243判定的应用程序被调试的行为加入异常样本库,经过步骤S243无法判定的样本本身不可疑或恶意的活动,但与其他指令或函数结合时,可能表明存在可疑调试或恶意行为,则加入可疑样本库,以不断的扩展样本库。
所述步骤S1特定访问规则设计包括如下几个部分:
一、应用程序调试前
(1)API(Application Programming Interface,应用程序接口)检测
通过检测当前桌面中是否存在特定的调试窗口来判断是否存在调试器,例如,检测桌面中的窗口类名和窗口名是否与字符“Ollydbg””x64dbg”相匹配,如果返回值为0,则未获取到调试器,如果返回值为1,则判断存在调试器,即存在调试行为,具体检测代码如下:
Figure BDA0003261000820000082
(2)行为占用附加调试
是指在需要保护的程序中,程序自身将一些只能同时有1个实例的功能占为己用。比如一般情况下,一个进程只能同时被1个调试器调试,不允许同时被两个调试器调试,那么就可以设计一种自调式模式,将程序以调试方式启动,自己先调试运行自己,然后利用系统的调试机制防止被其他调试器调试附加调试。
有如下2种自调式方式:
进程第1次运行时会尝试访问同步内核对象,如果不存在,则说明当前进程第1次运行,利用这个规则,创建一个内核对象,并以调试方式创建进程打开“自己”,用CreateProcess()指令实现,这时若调试器首次调试运行进程则相当于在调试一个调试器,由于第2次运行的进程是被第1次运行的调试打开的,所以调试器也无法继续调试第2次运行的进程;
还可以选择正常创建自身,然后马上附加创建进程的操作来实现,DebugActiveProcess()就可以做到这一点。
二、应用程序调试中
1、使用Windows API检测
使用Windows API函数检测调试器是否存在是最简单的反调试技术。Windows操作系统中提供了这样一些API,应用程序可以通过调用这些API,来检测自己是否正在被调试。
1.1 IsDebuggerPresent
IsDebuggerPresent查询进程环境块(PEB)中的IsDebugged标志。如果进程没有运行在调试器环境中,函数返回0;如果调试附加了进程,函数返回一个非零值。
1.2 CheckRemoteDebuggerPresent
CheckRemoteDebuggerPresent同IsDebuggerPresent几乎一致。它不仅可以探测系统其他进程是否被调试,通过传递自身进程句柄还可以探测自身是否被调试。
1.3 NtQueryInformationProcess
这个函数是Ntdll.dll中一个API,它用来提取一个给定进程的信息。它的第一个参数是进程句柄,第二个参数告诉我们它需要提取进程信息的类型。为第二个参数指定特定值并调用该函数,相关信息就会设置到第三个参数。第二个参数是一个枚举类型,其中与反调试有关的成员有ProcessDebugPort(0x7)、ProcessDebugObjectHandle(0x1E)和ProcessDebugFlags(0x1F)。例如将该参数置为ProcessDebugPort,如果进程正在被调试,则返回调试端口,否则返回0
第二个参数ProcessInformationClass给定了需要查询的进程信息类型。当给定值为0(ProcessBasicInformation)或7(ProcessDebugPort)时,就能得到相关调试信息,返回信息会写到第三个参数ProcessInformation指向的缓冲区中。
2、检测数据结构
2.1 PEB中的BeingDebugged
检测BeingDebugged标志,进而判断是否正在被调试。
Windows操作系统维护着每个正在运行的进程的PEB结构,它包含与这个进程相关的所有用户态参数。这些参数包括进程环境数据,进程环境数据包括环境变量、加载的模块列表、内存地址,以及调试器状态。
进程运行时,位置fs:[30h]指向PEB的基地址。为了实现反调试技术,恶意代码通过这个位置检查BeingDebugged标志,如果返回值为0,则未获得调试器,如果返回值非0,则说明应用程序正在被调试,检测程序代码如下:
Figure BDA0003261000820000101
2.2检测ProcessHeap属性
Reserved数组中一个未公开的位置叫作ProcessHeap,它被设置为加载器为进程分配的第一个堆的位置。ProcessHeap位于PEB结构的0x18处。第一个堆头部有一个属性字段,它告诉内核这个堆是否在调试器中创建,这些属性叫作ForceFlags和Flags,检测ForceFlags和Flags,如果返回值为0,则未获得调试器,如果返回值非0,则说明应用程序正在被调试。在Windows XP系统中,ForceFlags属性位于堆头部偏移量0x10处;在Windows 7系统中,对于32位的应用程序来说ForceFlags属性位于堆头部偏移量0x44处。
2.3检测NTGlobalFlag属性
由于调试器中启动进程与正常模式下启动进程有些不同,所以它们创建内存堆的方式也不同。系统使用PEB结构偏移量0x68处的一个未公开位置,来决定如何创建堆结构。如果这个位置的值为0x70,我们就知道进程正运行在调试器中。
Figure BDA0003261000820000111
操作系统创建堆时,值0x70是下列标志的一个组合。如果进程从调试器启动,那么进程的这些标志将被设置:
FLG_HEAP_ENABLE_TAIL_CHECK|FLG_HEAP_ENABLE_FREE_CHECK|FLG_HEAP_VALIDATE_PARAMETERS。
避免这种问题方法和前面的差不多。如果用OllyDbg的命令行插件修改,输入的命令为dump fs:[30]+0x68。如果用PhantOm插件,它会逃避使用NTGlobalFlag的反调试技术而不需要手动设置。
3、系统痕迹检测
通常,我们使用调试工具来分析恶意代码,但这些工具会在系统中驻留一些痕迹。恶意代码通过搜索这种系统痕迹,来确定你是否试图分析它。
3.1下面是调试器在注册表中的一个常用位置
SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug(32位系统)
SOFTWARE\Wow6432Node\Microsoft\WindowsNT\CurrentVersion\AeDebug(64位系统)
该注册表项指定当应用程序发生错误时,触发哪一个调试器。默认情况下,它被设置为Dr.Watson。如果该注册表的键值被修改为OllyDbg,则恶意代码就可能确定它正在被调试。
3.2查找窗体信息
FindWindow函数检索处理顶级窗口的类名和窗口名称匹配指定的字符串,如果匹配则确定未被调试,如果不匹配说明正在被调试。
4、识别调试器行为
在逆向工程中,为了帮助恶意代码分析人员进行分析,可以使用调试器设置一个断点,或是单步执行一个进程。然而,在调试器中执行这些操作时,它们会修改进程中的代码。因此,恶意代码常使用几种反调试技术探测软件/硬件断点、完整性校验、时钟检测等几种类型的调试器行为。直接运行恶意代码与在调试器中运行恶意代码也会在一些细节上不同,如父进程信息、STARTUPINFO信息、SeDebugPrivilege权限等。
4.1软件断点检测
调试器设置断点的基本机制是用软件中断指令INT 3临时替换运行程序中的一条指令,然后当程序运行到这条指令时,调用调试异常处理例程。INT 3指令的机器码是0xCC,因此无论何时,使用调试器设置一个断点,它都会插入一个0xCC来修改代码。恶意代码常用的一种反调试技术是在它的代码中查找机器码0xCC,来扫描调试器对它代码的INT 3修改。repne scasb指令用于在一段数据缓冲区中搜索一个字节。EDI需指向缓冲区地址,AL则包含要找的字节,ECX设为缓冲区的长度。当ECX=0或找到该字节时,比较停止。
4.2硬件断点检测
在OllyDbg的寄存器窗口按下右键,点击View debug registers可以看到DR0、DR1、DR2、DR3、DR6和DR7这几个寄存器。DR0、Dr1、Dr2、Dr3用于设置硬件断点,由于只有4个硬件断点寄存器,所以同时最多只能设置4个硬件断点。DR4、DR5由系统保留。DR6、DR7用于记录Dr0-Dr3中断点的相关属性。如果没有硬件断点,那么DR0、DR1、DR2、DR3这4个寄存器的值都为0,如果返回值为非零,则说明有硬件断点。
4.3执行代码校验和检查
恶意代码可以计算代码段的校验并实现与扫描中断相同的目的,返回是否被调试的结果。与扫描0xCC不同,这种检查仅执行恶意代码中机器码CRC或者MD5校验和检查。
5、时间检测
被调试时,进程的运行速度大大降低,例如,单步调试大幅降低恶意代码的运行速度,所以时钟检测是恶意代码探测调试器存在的最常用方式之一。有如下两种用时钟检测来探测调试器存在的方法。
记录一段操作前后的时间戳,然后比较这两个时间戳,如果存在滞后,则可以认为存在调试器。
记录触发一个异常前后的时间戳。如果不调试进程,可以很快处理完异常,因为调试器处理异常的速度非常慢。默认情况下,调试器处理异常时需要人为干预,这导致大量延迟。虽然很多调试器允许我们忽略异常,将异常直接返回程序,但这样操作仍然存在不小的延迟
5.1使用rdtsc指令
较常用的时钟检测方法是利用rdtsc指令(操作码0x0F31),它返回至系统重新启动以来的时钟数,并且将其作为一个64位的值存入EDX:EAX中。恶意代码运行两次rdtsc指令,然后比较两次读取之间的差值。
5.2使用QueryPerformanceCounter和GetTickCount
同rdtsc指令一样,这两个Windows API函数也被用来执行一个反调试的时钟检测。使用这种方法的前提是处理器有高分辨率能力的计数器-寄存器,它能存储处理器活跃的时钟数。为了获取比较的时间差,调用两次QueryPerformanceCounter函数查询这个计数器。若两次调用之间花费的时间过于长,则可以认为正在使用调试器。GetTickCount函数返回最近系统重启时间与当前时间的相差毫秒数(由于时钟计数器的大小原因,计数器每49.7天就被重置一次)
6、干扰调试器的功能
恶意代码可以用一些技术来干扰调试器的正常运行。例如线程本地存储(TLS)回调、插入中断、异常等。这些技术当且仅当程序处于调试器控制之下时才试图扰乱程序的运行。
6.1使用TLS回调
Thread Local Storage(TLS),即线程本地存储,是Windows为解决一个进程中多个线程同时访问全局变量而提供的机制。TLS可以简单地由操作系统代为完成整个互斥过程,也可以由用户自己编写控制信号量的函数。当进程中的线程访问预先制定的内存空间时,操作系统会调用系统默认的或用户自定义的信号量函数,保证数据的完整性与正确性。下面是一个简单的TLS回调的例子,TLS_CALLBACK1函数在main函数执行前调用IsDebuggerPresent函数检查它是否正在被调试。
TLS_CALLBACK:Debugger Detected!
使用PEview查看.tls段,可以发现TLS回调函数。通常情况下,正常程序不使用.tls段,如果在可执行程序中看到.tls段,应该立即怀疑它使用了反调试技术。
6.2利用中断
因为调试器使用INT 3来设置软件断点,所以一种反调试技术就是在合法代码段中插入0xCC(INT 3)欺骗调试器,使其认为这些0xCC机器码是自己设置的断点。
Figure BDA0003261000820000141
6.3设置陷阱标志位
EFLAGS寄存器的第八个比特位是陷阱标志位。如果设置了,就会产生一个单步异常,认为是被调试。
6.4 SetUnhandledExceptionFilter
进程中发生异常时若SEH未处理或注册的SEH不存在,会调用UnhandledExceptionFilter,它会运行系统最后的异常处理器。UnhandledExceptionFilter内部调用了前面提到过的NtQueryInformationProcess以判断是否正在调试进程。若进程正常运行,则运行最后的异常处理器;若进程处于调试,则将异常派送给调试器。SetUnhandledExceptionFilter函数可以修改系统最后的异常处理器。下面的代码先触发异常,然后在新注册的最后的异常处理器内部判断进程正常运行还是调试运行。进程正常运行时pExcept->ContextRecord->Eip+=4;将发生异常的代码地址加4使得其能够继续运行;进程调试运行时产生无效的内存访问异常,从而无法继续调试。
步骤S3、代码混淆,包括下述步骤:
步骤S31、通过步骤S2中判断为存在可疑调试器的加入混淆代码逻辑;
步骤S32、执行混淆代码逻辑,扰乱反调式程序的关键值,通过混淆代码被修改替换的目标指令最终形成的字节码有前后相关性,即改变其他任意一个字节会影响到所有被虚拟化的指令。
如图4所示,代码混淆是指不能反汇编到真正的程序代码,此图以破坏堆栈的方法,使调试者在IDA静态分析此程序上不能使用快捷键F5直接查看程序伪代码所做的一种防护,如图5所示,在执行混淆代码(壳代码)逻辑之前,通过调试看到程序只有两部,程序入口点(OEP)和程序代码段,加入混淆代码后,相当于给源程序加入一个新的区段,然后先运行这个区段的代码,更改了程序入口点,使看到的代码段为加壳的代码,是虚拟化的垃圾代码,即混淆代码使用大量的虚拟跳转和垃圾指令将原有简单的代码变得复杂。代码混淆为现有技术,在此不做赘述。
该基于自动静态资源检测的反调试方法还包括步骤S4:检测,具体包括
执行完上述反调试方法后,将应用程序调试,如果程序在被调试时出现异常,则该基于自动静态资源检测的反调试方法有效,如果应用程序在被调试时未出现异常,需要确认系统是否处在调试环境中,如是否在对应的win32或win64的调试环境中,需要在特定规则中预设系统环境相关函数成员,然后循环执行步骤S1至S3。
上述静态资源的定义包括:静态资源、汇编指令、标志位等及其结果,如:ProcessDebugFlags(0x1F),NtGlobalFlag。采集参数如下表所示:
Figure BDA0003261000820000151
以上实施例仅用以说明本发明的技术方案,而非对其限制;尽管参照前述实施例对本发明进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本发明各实施例技术方案的精神和范围。

Claims (10)

1.一种基于自动静态资源检测的反调试方法,其特征在于:包括:
步骤S1、特定访问规则的设计,对不同操作系统和框架的函数对应参数值建立授信专家资源关系库;
步骤S2、主检测,应用程序启动时,通过特定访问规则检测文件是否有修改,即判断应用程序是否符合授信专家资源关系库,符合视为正常访问,直接打开应用程序,如果不符合授信专家资源关系库,则视为可疑行为,监听可疑静态资源,并建立调试器可疑样本库和调试器异常样本库,将对应的可疑行为或者异常行为放入可疑样本库或异常样本库,并且将不匹配这两个库的静态资源使用隐马尔可夫模型自动分析是否存在可疑调试器,判定该未知行为对程序影响的风险概率;
步骤S3、代码混淆,经过步骤S2判断为可疑样本或异常样本后均触发代码混淆。
2.如权利要求1所述的基于自动静态资源检测的反调试方法,其特征在于:步骤S1中,特定访问规则是将PE结构体、调试器函数、接口函数作为特征因子,预设特征因子对应的标志位状态码,值为布尔变量,如果标志位状态码赋值为0,则判定为未获取到调试器,标志位状态码赋值为1,则判定为获取到调试行为,或者预设特征因子的阈值,特征因子低于阈值,则判定为未获取到调试器,高于阈值,则判定为获取到调试行为,或者预设特征因子的值,如果特征因子与预设的值匹配,则判定为未获取到调试器,如果特征因子与预设的值不匹配,则判定为获取到调试行为。
3.如权利要求1所述的基于自动静态资源检测的反调试方法,其特征在于:所述步骤S2主检测具体包括下述步骤:
步骤S21、使用特定访问规则检查PE格式的文件头,以判定应用程序是否符合授信专家资源关系库里预先存储的特定访问规则;
步骤S22、应用程序符合授信专家资源关系库的特定访问规则时,判定为正常访问,直接打开应用程序,如果不符合特定访问规则,进入步骤S23;
步骤S23、检测应用程序是否符合异常样本库或可疑样本库,如果符合异常样本库,判定为应用程序被调试,如果符合可疑样本库,判定为应用程序疑似被调试,当判定应用程序被调试或疑似被调试时,均进入步骤S3,如果应用程序不符合异常样本库或可疑样本库,进入步骤S24;
步骤S24、使用隐马尔可夫模型检测可疑概率,根据检测结果判定是否启动代码混淆防御机制,需要启动混淆防御的进入步骤S3,同时将检测结果对应添加到授信专家资源关系库、或可疑样本库、或异常样本库。
4.如权利要求3所述的基于自动静态资源检测的反调试方法,其特征在于:步骤S24的具体实现步骤如下:
步骤S241、将待检测库中的每组静态资源构造训练样本集,用静态资源构造隐马尔可夫模型参数λ={A,B,π},π为初始状态向量,A为状态转移概率矩阵,B为观测概率矩阵;
步骤S242、对隐马尔可夫模型参数中的每组静态资源采用K均值聚类算法进行聚类;
步骤S243、设定静态资源内容的阈值或布尔值,通过对静态资源内容返回布尔值结果或是否超出阈值进行判定是否为异常行为,如状态码为设定布尔值或者未超出设定阈值,则判定应用程序没有被调试,直接打开应用程序,如果状态码为设定布尔值或者超出设定阈值,则说明应用程序正在被调试,进入步骤S3;
步骤S244、经过步骤S243判定的应用程序没有被调试的行为加入授信专家资源关系库,经过步骤S243判定的应用程序被调试的行为加入异常样本库,经过步骤S243无法判定的样本本身不可疑或恶意的活动,但与其他指令或函数结合时,可能表明存在可疑调试或恶意行为,则加入可疑样本库,以不断的扩展样本库。
5.如权利要求1所述的基于自动静态资源检测的反调试方法,其特征在于:
还包括步骤S4:检测,执行完步骤S1至S3的反调试方法后,将应用程序调试,如果程序在被调试时出现异常,则该基于自动静态资源检测的反调试方法有效,如果应用程序在被调试时未出现异常,需要确认系统是否处在调试环境中,需要在特定规则中预设系统环境相关函数成员,然后循环执行步骤S1至S3。
6.一种基于自动静态资源检测的反调试系统,其特征在于:包括:
特定访问规则设计模块,用于特定访问规则的设计,对不同操作系统和框架的函数对应参数值建立授信专家资源关系库;
主检测模块,用于在应用程序启动时,通过特定访问规则检测文件是否有修改,即判断应用程序是否符合授信专家资源关系库,符合视为正常访问,直接打开应用程序,如果不符合授信专家资源关系库,则视为可疑行为,监听可疑静态资源,并建立调试器可疑样本库和调试器异常样本库,将对应的可疑行为或者异常行为放入可疑样本库或异常样本库,并且将不匹配这两个库的静态资源使用隐马尔可夫模型自动分析是否存在可疑调试器,判定该未知行为对程序影响的风险概率;
代码混淆模块,用于将通过主检测模块判断为可疑样本或异常样本的应用程序触发代码混淆。
7.如权利要求6所述的基于自动静态资源检测的反调试系统,其特征在于:特定访问规则设计模块中,特定访问规则是将PE结构体、调试器函数、接口函数作为特征因子,预设特征因子对应的标志位状态码,值为布尔变量,如果标志位状态码赋值为0,则判定为未获取到调试器,标志位状态码赋值为1,则判定为获取到调试行为,或者预设特征因子的阈值,特征因子低于阈值,则判定为未获取到调试器,高于阈值,则判定为获取到调试行为,或者预设特征因子的值,如果特征因子与预设的值匹配,则判定为未获取到调试器,如果特征因子与预设的值不匹配,则判定为获取到调试行为。
8.如权利要求6所述的基于自动静态资源检测的反调试系统,其特征在于:主检测模块包括:
检查单元,使用特定访问规则检查PE格式的文件头,以判定应用程序是否符合授信专家资源关系库里预先存储的特定访问规则;
授信专家资源关系库判定单元,应用程序符合授信专家资源关系库的特定访问规则时,判定为正常访问,直接打开应用程序,如果不符合特定访问规则,进入异常样本库或可疑样本库判定单元;
异常样本库或可疑样本库判定单元,检测应用程序是否符合异常样本库或可疑样本库,如果符合异常样本库,判定为应用程序被调试,如果符合可疑样本库,判定为应用程序疑似被调试,当判定应用程序被调试或疑似被调试时,均进入混淆代码逻辑模块,如果应用程序不符合异常样本库或可疑样本库,进入隐马尔可夫模型检测单元;
隐马尔可夫模型检测单元,使用隐马尔可夫模型检测可疑概率,根据检测结果判定是否启动代码混淆防御机制,需要启动混淆防御的进入混淆代码逻辑模块,同时将检测结果对应添加到授信专家资源关系库、或可疑样本库、或异常样本库。
9.如权利要求8所述的基于自动静态资源检测的反调试系统,其特征在于:隐马尔可夫模型检测单元具体检测方法如下:
将待检测库中的每组静态资源构造训练样本集,用静态资源构造隐马尔可夫模型参数λ={A,B,π},π为初始状态向量,A为状态转移概率矩阵,B为观测概率矩阵;
对隐马尔可夫模型参数中的每组静态资源采用K均值聚类算法进行聚类;
设定静态资源内容的阈值或布尔值,通过对静态资源内容返回布尔值结果或是否超出阈值进行判定是否为异常行为,如状态码为设定布尔值或者未超出设定阈值,则判定应用程序没有被调试,直接打开应用程序,如果状态码为设定布尔值或者超出设定阈值,则说明应用程序正在被调试,进入混淆代码逻辑模块;
判定应用程序没有被调试的行为加入授信专家资源关系库,判定应用程序被调试的行为加入异常样本库,无法判定的样本本身不可疑或恶意的活动,但与其他指令或函数结合时,可能表明存在可疑调试或恶意行为,则加入可疑样本库,以不断的扩展样本库。
10.如权利要求6所述的基于自动静态资源检测的反调试系统,其特征在于:
还包括检测模块,用于将应用程序调试,如果程序在被调试时出现异常,则该基于自动静态资源检测的反调试方法有效,如果应用程序在被调试时未出现异常,需要确认系统是否处在调试环境中,需要在特定规则中预设系统环境相关函数成员,然后循环执行特定访问规则设计模块、主检测模块以及混淆代码逻辑模块。
CN202111072744.0A 2021-09-14 2021-09-14 基于自动静态资源检测的反调试方法和系统 Pending CN113760770A (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN202111072744.0A CN113760770A (zh) 2021-09-14 2021-09-14 基于自动静态资源检测的反调试方法和系统

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN202111072744.0A CN113760770A (zh) 2021-09-14 2021-09-14 基于自动静态资源检测的反调试方法和系统

Publications (1)

Publication Number Publication Date
CN113760770A true CN113760770A (zh) 2021-12-07

Family

ID=78795421

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202111072744.0A Pending CN113760770A (zh) 2021-09-14 2021-09-14 基于自动静态资源检测的反调试方法和系统

Country Status (1)

Country Link
CN (1) CN113760770A (zh)

Cited By (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN114625639A (zh) * 2022-03-03 2022-06-14 上海先楫半导体科技有限公司 一种基于片上系统的调试方法、系统以及芯片
CN115859292A (zh) * 2023-02-20 2023-03-28 卓望数码技术(深圳)有限公司 一种涉诈app检测系统和判定方法以及存储介质

Citations (7)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20050183072A1 (en) * 1999-07-29 2005-08-18 Intertrust Technologies Corporation Software self-defense systems and methods
CN104978522A (zh) * 2014-04-10 2015-10-14 北京启明星辰信息安全技术有限公司 一种检测恶意代码的方法和装置
CN107463836A (zh) * 2017-08-17 2017-12-12 郑州云海信息技术有限公司 一种Windows系统下的综合反调试方法及系统
CN107590388A (zh) * 2017-09-12 2018-01-16 南方电网科学研究院有限责任公司 恶意代码检测方法和装置
KR101990028B1 (ko) * 2018-11-27 2019-06-17 강원대학교산학협력단 바이너리 파일 복원을 위한 하이브리드 언패킹 방법 및 시스템
CN112733093A (zh) * 2021-01-04 2021-04-30 中国电力科学研究院有限公司 基于ring3环对抗的程序行为保护方法、系统及存储介质
KR20210057239A (ko) * 2019-11-11 2021-05-21 강원대학교산학협력단 안티 디버깅 무력화 장치 및 그 방법

Patent Citations (7)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20050183072A1 (en) * 1999-07-29 2005-08-18 Intertrust Technologies Corporation Software self-defense systems and methods
CN104978522A (zh) * 2014-04-10 2015-10-14 北京启明星辰信息安全技术有限公司 一种检测恶意代码的方法和装置
CN107463836A (zh) * 2017-08-17 2017-12-12 郑州云海信息技术有限公司 一种Windows系统下的综合反调试方法及系统
CN107590388A (zh) * 2017-09-12 2018-01-16 南方电网科学研究院有限责任公司 恶意代码检测方法和装置
KR101990028B1 (ko) * 2018-11-27 2019-06-17 강원대학교산학협력단 바이너리 파일 복원을 위한 하이브리드 언패킹 방법 및 시스템
KR20210057239A (ko) * 2019-11-11 2021-05-21 강원대학교산학협력단 안티 디버깅 무력화 장치 및 그 방법
CN112733093A (zh) * 2021-01-04 2021-04-30 中国电力科学研究院有限公司 基于ring3环对抗的程序行为保护方法、系统及存储介质

Non-Patent Citations (4)

* Cited by examiner, † Cited by third party
Title
ASMA\'A MAHFOUD HEZAM AL-HAKIMI 等: "Hybrid Obfuscation Technique to Protect Source Code From Prohibited Software Reverse Engineering", 《IEEE ACCESS》, vol. 8, pages 187326 - 187342, XP011815367, DOI: 10.1109/ACCESS.2020.3028428 *
FA1C4: "反调试总结:静态", pages 1 - 4, Retrieved from the Internet <URL:https://blog.csdn.net/qq_33976344/article/details/115187531> *
吴超: "windows环境下隐蔽调试器的设计与实现", 《中国优秀硕士学位论文全文数据库》, no. 2009, pages 138 - 208 *
徐剑 等: "面向Android应用程序的代码保护方法研究", 《信息网络安全》, no. 10, pages 11 - 17 *

Cited By (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN114625639A (zh) * 2022-03-03 2022-06-14 上海先楫半导体科技有限公司 一种基于片上系统的调试方法、系统以及芯片
CN115859292A (zh) * 2023-02-20 2023-03-28 卓望数码技术(深圳)有限公司 一种涉诈app检测系统和判定方法以及存储介质

Similar Documents

Publication Publication Date Title
Kawakoya et al. Memory behavior-based automatic malware unpacking in stealth debugging environment
Guo et al. A study of the packer problem and its solutions
US8117660B2 (en) Secure control flows by monitoring control transfers
JP4518564B2 (ja) 不正コード実行の防止方法、不正コード実行の防止用プログラム、及び不正コード実行の防止用プログラムの記録媒体
Branco et al. Scientific but not academical overview of malware anti-debugging, anti-disassembly and anti-vm technologies
CN109583200B (zh) 一种基于动态污点传播的程序异常分析方法
Cesare et al. Classification of malware using structured control flow
US10572665B2 (en) System and method to create a number of breakpoints in a virtual machine via virtual machine trapping events
Carmony et al. Extract Me If You Can: Abusing PDF Parsers in Malware Detectors.
Galloro et al. A Systematical and longitudinal study of evasive behaviors in windows malware
Pan et al. Digtool: A {virtualization-based} framework for detecting kernel vulnerabilities
Shi et al. Hiding debuggers from malware with apate
CN113760770A (zh) 基于自动静态资源检测的反调试方法和系统
WO2013154459A1 (ru) Способ обнаружения вредоносного программного обеспечения в ядре операционной системы
Quist et al. Covert debugging circumventing software armoring techniques
Kim et al. Large-scale analysis on anti-analysis techniques in real-world malware
D’Elia et al. Designing robust API monitoring solutions
CN111814119B (zh) 一种反调试的方法
Zeng et al. Tailored application-specific system call tables
Shields Anti-debugging–a developers view
Zhang Research summary of anti-debugging technology
Mori et al. A tool for analyzing and detecting malicious mobile code
US10460108B1 (en) Method and system to identify and rectify input dependency based evasion in dynamic analysis
KR102421394B1 (ko) 하드웨어와 소프트웨어 기반 트레이싱을 이용한 악성코드 탐지 장치 및 방법
Nicchi et al. Designing Robust API Monitoring Solutions.

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication
SE01 Entry into force of request for substantive examination
SE01 Entry into force of request for substantive examination