一种栈探测器编译开关的检测方法和装置制造方法

文档序号:6500026阅读:208来源:国知局
一种栈探测器编译开关的检测方法和装置制造方法【专利摘要】本发明实施例公开了一种栈探测器编译开关的检测方法和装置,其中方法包括:对软件进行壳检测与脱壳处理后,查找所述软件的主函数入口确定主函数;对所述主函数进行特征扫描,若存在与栈探测器GS编译开关对应的特征指令,则确定GS编译开关被开启了。以上方案,通过对软件进行壳检测与脱壳处理,查到找主函数入口来确定主函数,然后对主函数进行特征扫描来可以确定GS编译开关是否被开启了。这样可以为软件漏洞挖掘等安全应用提供方便。【专利说明】一种栈探测器编译开关的检测方法和装置【
技术领域
】[0001]本发明涉及通信【
技术领域
】,特别涉及一种栈探测器编译开关的检测方法和装置。【
背景技术
】[0002]在软件漏洞挖掘等各种安全应用中,安全研究人员需要知道软件当前开启了哪些保护措施,常用的保护措施包括:DEP(DataExecutionPrevention,数据执行保护)、ALSR(Addressspacelayoutrandomization,内存随机化保护)、SafeSEH(SafeStructuredExceptionHandling,安全异常处理保护)以及GS(Controlsstackprobes,栈探测器)等。[0003]开启GS编译开关可以防止栈溢出攻击。若GS编译开关处于开启状态,那么在函数调用发生时会向栈帧中压入4个字节的随机数,该随机数被称为安全信息(securitycookie),位于栈底EBP(extendedbasepointer,扩展基址指针寄存器)之前,并且.data(数据段)的内存区域中还会存放一个securitycookie的副本。若GS编译开关没有打开,则不会压入securitycookie。打开GS编译开关的主要目的是防止栈溢出攻击,S卩:当溢出的数据破坏了securitycookie后,软件程序会取用存放的副本对securitycookie进行校验,如果校验失败则退出程序。这样就可以防止栈溢出攻击。[0004]目前有关于GS编译开关的原理以及作用的介绍,但是还没有可靠的检测方法来确定软件程序是否开启了GS编译开关对软件程序进行保护。【
发明内容】[0005]本发明实施例提供了一种栈探测器编译开关的检测方法和装置,用于检测GS编译开关是否开启。[0006]一种栈探测器编译开关的检测方法,包括:[0007]对软件进行壳检测与脱壳处理后,查找所述软件的主函数入口确定主函数;[0008]对所述主函数进行特征扫描,若存在与栈探测器GS编译开关对应的特征指令,则确定GS编译开关被开启了。[0009]一种栈探测器编译开关的检测装置,包括:[0010]确定单元,用于对软件进行壳检测与脱壳处理后,查找所述软件的主函数入口确定主函数;[0011]扫描单元,用于对所述确定单元确定的主函数进行特征扫描;[0012]判决单元,用于若所述扫描单元经扫描确定存在与栈探测器GS编译开关对应的特征指令,则确定GS编译开关被开启了。[0013]从以上技术方案可以看出,本发明实施例具有以下优点:通过对软件进行壳检测与脱壳处理,查到找主函数入口来确定主函数,然后对主函数进行特征扫描来可以确定GS编译开关是否被开启了。这样可以为软件漏洞挖掘等安全应用提供方便。【专利附图】【附图说明】[0014]为了更清楚地说明本发明实施例中的技术方案,下面将对实施例描述中所需要使用的附图作简要介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域的普通技术人员来讲,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。[0015]图1为本发明实施例方法流程示意图;[0016]图2为本发明实施例方法流程示意图;[0017]图3为本发明实施例装置结构示意图;[0018]图4为本发明实施例装置结构示意图;[0019]图5为本发明实施例装置结构示意图;[0020]图6为本发明实施例装置结构示意图。【具体实施方式】[0021]为了使本发明的目的、技术方案和优点更加清楚,下面将结合附图对本发明作进一步地详细描述,显然,所描述的实施例仅仅是本发明一部份实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其它实施例,都属于本发明保护的范围。[0022]本发明实施例提供了一种一种栈探测器编译开关的检测方法,如图1所示,包括:[0023]101:对软件进行壳检测与脱壳处理后,查找上述软件的主函数入口确定主函数;[0024]上述101中,壳检测是为了确定软件的壳,脱壳处理则是为了能够在后续找到软件的真实入口,即Main(主)函数的入口。由于一些程序,例如使用VS2005编译的程序,SP使关闭GS编译开关,某些初始化函数运行时还是会使用securitycookie,这样我们就不能准确地确认到底这个程序是否开启了GS编译开关。也就是说需要找到用户编写的代码部分有没有开启GS编译开关,采用以上方案可以检测到代码部分,因此这样就可以避免这个问题。[0025]更具体地,主函数入口的查找方式可能与软件的编译器类型相关,本发明实施例给出了如下可选方案:上述查找上述软件的主函数入口之前还包括:确定上述软件的编译器类型;[0026]上述查找上述软件的主函数入口包括:使用与上述编译器类型对应主函数的特征指令,识别上述软件的主函数入口。[0027]软件使用不同的编译器真实入口往往不一样。因此需要对不同的编译器Main函数入口进行识别。[0028]例如:vs2005编译器编译的程序,主函数入口前有3个压栈push指令,和两个mov指令,我们从PE文件入口开始扫描,遇到push->mov->push->mov->push即可找到其主入口,其中push指令是实现压入操作的堆栈操作指令,mov指令是传送指令。另外,为了防止识别错误,还可以在主函数调用的后面继续扫描几个字节,看有没有出现恢复堆栈平衡的add指令。[0029]又例如:VC++6.0编译器编译的程序,主函数入口前为4个push指令,一个call指令再一个push指令,然后是主函数。[0030]又例如:另外一个版本的编译器主函数入口前为2个mov指令紧接着是3个push指令。[0031]对于不同的编译器编译的程序,主函数的入口可能具有不同的特征,可以按照不同的特征来进行区别识别提高准确性。[0032]102:对上述主函数进行特征扫描,若存在与栈探测器GS编译开关对应的特征指令,则确定GS编译开关被开启了。[0033]在研究过程中发现,只要开启了GS编译开关,那么在函数返回结果前都会有一个校验函数,该校验函数调用指令前的几条指令比较特别,因此我们可以扫描这几条比较特别指令(即特征指令)是否存在,从而判断GS编译开关是否打开。[0034]以上方案,通过对软件进行壳检测与脱壳处理,查到找主函数入口来确定主函数,然后对主函数进行特征扫描来可以确定GS编译开关是否被开启了。这样可以为软件漏洞挖掘等安全应用提供方便。[0035]进一步地,GS编译开关开启后并不会保护软件下的所有的函数,每个函数是独立的,要确定是否开启了GS编译开关,本发明实施例采用了如下方案:在确定主函数之后还包括:对上述主函数内的所有函数进行特征扫描,若上述主函数内的任一函数存在与栈探测器GS编译开关对应的特征指令,则确定GS编译开关被开启了。[0036]上述主函数内的所有函数,可以包括:主函数的子函数,还可以是子函数的子函数。对于每个函数的扫描方式可以完全相同,采用迭代的方式实现即可。[0037]进一步地,并不是对所有函数都需要进行扫描,如以下情况:函数不包含缓冲区;函数被定义为具有变量参数列表;函数使用无保护的关键字标记;函数在第一个语句中包含内嵌会变代码;缓冲区不是8字节类型且大小不大于4个字节;这些情况下,GS并不保护这些函数,因此本发明实施例还提供了减少被扫描函数数量的方案,具体可以如下:对上述主函数内的所有函数进行特征扫描之前还包括:确定上述主函数内的函数的函数类型;[0038]那么,上述对上述主函数内的所有函数进行特征扫描包括:对除以下五种类型的函数以外的其他所有函数进行特征扫描;上述五种类型的函数包括:不包含缓冲区的函数、被定义为具有变量参数列表的函数、使用无保护的关键字标记的函数、在第一个语句中包含内嵌会变代码的函数、缓冲区不是8字节类型且大小不大于4个字节的函数。[0039]以上给出了五种可以不用扫描的函数举例,需要说明的是,可能还有其它不被GS所保护的函数,也不需要进行扫描,因此以上举例不应理解为对本发明实施例的穷举。[0040]进一步地,为了防止误判,本发明实施例还提供了如下方案:在确定存在与GS编译开关对应的特征指令之后还包括:确定上述特征指令之后的设定范围内是否出现返回指令,若存在,则确定GS编译开关被开启了。[0041]以下实施例以PE(PortableExecutable,可移植可执行)文件是否开启了GS编译开关为例进行举例说明如下:[0042]201:对软件进行壳检测与脱壳处理;[0043]壳检测是为了确定软件的壳,脱壳处理则是为了能够在后续找到软件的真实入口,即Main(主)函数的入口。[0044]202:查找真实入口;[0045]由于一些程序,例如使用VS2005编译的程序,即使关闭GS编译开关,某些初始化函数运行时还是会使用securitycookie,这样我们就不能准确地确认到底这个程序是否开启了GS编译开关。也就是说需要找到用户编写的代码部分有没有开启GS编译开关,采用以上方案可以检测到代码部分,因此这样就可以避免这个问题。[0046]软件使用不同的编译器真实入口往往不一样。因此需要对不同的编译器Main函数入口进行识别。[0047]例如:vs2005编译器编译的程序,主函数入口前有3个压栈push指令,和两个mov指令,我们从PE文件入口开始扫描,遇到push->mov->push->mov->push即可找到其主入口,其中push指令是实现压入操作的堆栈操作指令,mov指令是传送指令。另外,为了防止识别错误,还可以在主函数调用的后面继续扫描几个字节,看有没有出现恢复堆栈平衡的add指令。[0048]又例如:VC++6.0编译器编译的程序,主函数入口前为4个push指令,一个call指令再一个push指令,然后是主函数。[0049]又例如:另外一个版本的VC++编译器主函数入口前为2个mov指令紧接着是3个push指令。[0050]对于不同的编译器编译的程序,主函数的入口可能具有不同的特征,可以按照不同的特征来进行区别识别提高准确性。[0051]203:扫描特征指令。[0052]在研究过程中发现,只要是开启了GS编译开关,那么在函数(除后续举例的五种函数以外的函数)返回结果前都会有一个校验函数;该校验函数调用指令前的几条指令比较特别,因此我们可以扫描这几条比较特别指令(即特征指令)是否存在,从而判断GS编译开关是否打开。不过仅仅是扫描特征指令可能还不够,这是由于校验函数都是在函数返回结果前调用,所以我们还需要判断特征指令后的一个范围内是否出现了返回指令,这样就能避免出现误判。[0053]所以,依照上面扫描特征指令的方法,对Main函数、子函数、子函数的子函数等进行迭代即可确定所有函数是否开启了GS编译开关。[0054]由于GS编译开关开启后并不会保护所有的函数,譬如以下情况:[0055]1、函数不包含缓冲区;[0056]2、函数被定义为具有变量参数列表;[0057]3、函数使用无保护的关键字标记;[0058]4、函数在第一个语句中包含内嵌会变代码;[0059]5、缓冲区不是8字节类型且大小不大于4个字节。[0060]因此以上五种函数可以不用扫描特征指令,其他函数采用迭代方式扫描特征指令。[0061]采用以上方案,通过迭代来确定是否某一个函数被GS保护了,如果被保护了,那么就可以认为该PE文件开启了GS编译开关。[0062]通过上述找GS编译开关是否开启的方法,结合ALSR、DEP以及SafeSEH的检测,这样就可以编写一个软件测试工具。在漏洞挖掘中,直接使用该软件测试工具,就能发现这个软件使用了何种保护措施以及缺少的保护措施。然后可以针对性的作出相应的处理。[0063]本发明实施例还提供了一种栈探测器编译开关的检测装置,如图3所示,包括:[0064]确定单元301,用于对软件进行壳检测与脱壳处理后,查找上述软件的主函数入口确定主函数;[0065]确定单元301执行壳检测是为了确定软件的壳,脱壳处理则是为了能够在后续找到软件的真实入口,即Main(主)函数的入口。由于一些程序,例如使用VS2005编译的程序,即使关闭GS编译开关,某些初始化函数运行时还是会使用securitycookie,这样我们就不能准确地确认到底这个程序是否开启了GS编译开关。也就是说需要找到用户编写的代码部分有没有开启GS编译开关,采用以上方案可以检测到代码部分,因此这样就可以避免这个问题。[0066]软件使用不同的编译器真实入口往往不一样。因此需要对不同的编译器Main函数入口进行识别。[0067]例如:vs2005编译器编译的程序,主函数入口前有3个压栈push指令,和两个mov指令,我们从PE文件入口开始扫描,遇到push->mov->push->mov->push即可找到其主入口,其中push指令是实现压入操作的堆栈操作指令,mov指令是传送指令。另外,为了防止识别错误,还可以在主函数调用的后面继续扫描几个字节,看有没有出现恢复堆栈平衡的add指令。[0068]又例如:VC++6.0编译器编译的程序,主函数入口前为4个push指令,一个call指令再一个push指令,然后是主函数。[0069]有例如:另外一个版本的编译器主函数入口前为2个mov指令紧接着是3个push指令。[0070]对于不同的编译器编译的程序,主函数的入口可能具有不同的特征,可以按照不同的特征来进行区别识别提高准确性。[0071]扫描单元302,用于对上述确定单元301确定的主函数进行特征扫描;[0072]判决单元303,用于若上述扫描单元302经扫描确定存在与栈探测器GS编译开关对应的特征指令,则确定GS编译开关被开启了。[0073]在研究过程中发现,只要开启了GS编译开关,那么在函数返回结果前都会有一个校验函数,该校验函数调用指令前的几条指令比较特别,因此我们可以扫描这几条比较特别指令(即特征指令)是否存在,从而判断GS编译开关是否打开。[0074]以上方案,通过对软件进行壳检测与脱壳处理,查到找主函数入口来确定主函数,然后对主函数进行特征扫描来可以确定GS编译开关是否被开启了。这样可以为软件漏洞挖掘等安全应用提供方便。[0075]进一步地,GS编译开关开启后并不会保护软件下的所有的函数,每个函数是独立的,要确定是否开启了GS编译开关,本发明实施例采用了如下方案:上述扫描单元302,还用于在确定主函数之后对上述主函数内的所有函数进行特征扫描;上述主函数内的所有函数,可以包括:主函数的子函数,还可以是子函数的子函数。对于每个函数的扫描方式可以完全相同,采用迭代的方式实现即可。[0076]上述判决单元303,还用于若上述扫描单元302经扫描确定上述主函数内的任一函数存在与栈探测器GS编译开关对应的特征指令,则确定GS编译开关被开启了。[0077]进一步地,并不是对所有函数都需要进行扫描,如以下情况:函数不包含缓冲区;函数被定义为具有变量参数列表;函数使用无保护的关键字标记;函数在第一个语句中包含内嵌会变代码;缓冲区不是8字节类型且大小不大于4个字节;这些情况下,GS并不保护这些函数,因此本发明实施例还提供了减少被扫描函数数量的方案,具体可以如下:如图4所示,上述装置还包括:[0078]函数类型确定单元401,用于在上述扫描单元302对上述主函数内的所有函数进行特征扫描之前,确定上述主函数内的函数的函数类型;[0079]上述扫描单元302,用于对除以下五种类型的函数以外的其他所有函数进行特征扫描;上述五种类型的函数包括:不包含缓冲区的函数、被定义为具有变量参数列表的函数、使用无保护的关键字标记的函数、在第一个语句中包含内嵌会变代码的函数、缓冲区不是8字节类型且大小不大于4个字节的函数。[0080]进一步地,主函数入口的查找方式可能与软件的编译器类型相关,本发明实施例给出了如下可选方案:如图5所示,上述装置还包括:[0081]编译器类型确定单元501,用于在上述确定单元301查找上述软件的主函数入口之前,确定上述软件的编译器类型;[0082]上述确定单元301,用于使用与上述编译器类型确定单元501确定的编译器类型对应主函数的特征指令,识别上述软件的主函数入口。[0083]以上给出了五种可以不用扫描的函数举例,需要说明的是,可能还有其它不被GS所保护的函数,也不需要进行扫描,因此以上举例不应理解为对本发明实施例的穷举。[0084]进一步地,为了防止误判,本发明实施例还提供了如下方案:如图6所示,上述装置还包括:[0085]指令确定单元601,用于在上述扫描单元302确定存在与GS编译开关对应的特征指令之后,确定上述特征指令之后的设定范围内是否出现返回指令;[0086]上述判决单元303,用于若指令确定单元601确定上述特征指令之后的设定范围内出现了返回指令,则确定GS编译开关被开启了。[0087]值得注意的是,上述装置实施例中,所包括的各个单元只是按照功能逻辑进行划分的,但并不局限于上述的划分,只要能够实现相应的功能即可;另外,各功能单元的具体名称也只是为了便于相互区分,并不用于限制本发明的保护范围。[0088]另外,本领域普通技术人员可以理解实现上述各方法实施例中的全部或部分步骤是可以通过程序来指令相关的硬件完成,相应的程序可以存储于一种计算机可读存储介质中,上述提到的存储介质可以是只读存储器,磁盘或光盘等。[0089]以上仅为本发明较佳的【具体实施方式】,但本发明的保护范围并不局限于此,任何熟悉本【
技术领域
】的技术人员在本发明实施例揭露的技术范围内,可轻易想到的变化或替换,都应涵盖在本发明的保护范围之内。因此,本发明的保护范围应该以权利要求的保护范围为准。【权利要求】1.一种栈探测器编译开关的检测方法,其特征在于,包括:对软件进行壳检测与脱壳处理后,查找所述软件的主函数入口确定主函数;对所述主函数进行特征扫描,若存在与栈探测器GS编译开关对应的特征指令,则确定GS编译开关被开启了。2.根据权利要求1所述方法,其特征在于,在确定主函数之后还包括:对所述主函数内的所有函数进行特征扫描,若所述主函数内的任一函数存在与栈探测器GS编译开关对应的特征指令,则确定GS编译开关被开启了。3.根据权利要求2所述方法,其特征在于,对所述主函数内的所有函数进行特征扫描之前还包括:确定所述主函数内的函数的函数类型;所述对所述主函数内的所有函数进行特征扫描包括:对除以下五种类型的函数以外的其他所有函数进行特征扫描;所述五种类型的函数包括:不包含缓冲区的函数、被定义为具有变量参数列表的函数、使用无保护的关键字标记的函数、在第一个语句中包含内嵌会变代码的函数、缓冲区不是8字节类型且大小不大于4个字节的函数。4.根据权利要求1所述方法,其特征在于,所述查找所述软件的主函数入口之前还包括:确定所述软件的编译器类型;所述查找所述软件的主函数入口包括:使用与所述编译器类型对应主函数的特征指令,识别所述软件的主函数入口。5.根据权利要求1至4任意一项所述方法,其特征在于,在确定存在与GS编译开关对应的特征指令之后还包括:确定所述特征指令之后的设定范围内是否出现返回指令,若存在,则确定GS编译开关被开启了。6.一种栈探测器编译开关的检测装置,其特征在于,包括:确定单元,用于对软件进行壳检测与脱壳处理后,查找所述软件的主函数入口确定主函数;扫描单元,用于对所述确定单元确定的主函数进行特征扫描;判决单元,用于若所述扫描单元经扫描确定存在与栈探测器GS编译开关对应的特征指令,则确定GS编译开关被开启了。7.根据权利要求6所述装置,其特征在于,所述扫描单元,还用于在确定主函数之后对所述主函数内的所有函数进行特征扫描;所述判决单元,还用于若所述扫描单元经扫描确定所述主函数内的任一函数存在与栈探测器GS编译开关对应的特征指令,则确定GS编译开关被开启了。8.根据权利要求7所述装置,其特征在于,还包括:函数类型确定单元,用于在所述扫描单元对所述主函数内的所有函数进行特征扫描之前,确定所述主函数内的函数的函数类型;所述扫描单元,用于对除以下五种类型的函数以外的其他所有函数进行特征扫描;所述五种类型的函数包括:不包含缓冲区的函数、被定义为具有变量参数列表的函数、使用无保护的关键字标记的函数、在第一个语句中包含内嵌会变代码的函数、缓冲区不是8字节类型且大小不大于4个字节的函数。9.根据权利要求6所述装置,其特征在于,还包括:编译器类型确定单元,用于在所述确定单元查找所述软件的主函数入口之前,确定所述软件的编译器类型;所述确定单元,用于使用与所述编译器类型确定单元确定的编译器类型对应主函数的特征指令,识别所述软件的主函数入口。10.根据权利要求6至9任意一项所述装置,其特征在于,还包括:指令确定单元,用于在所述扫描单元确定存在与GS编译开关对应的特征指令之后,确定所述特征指令之后的设定范围内是否出现返回指令;所述判决单元,用于若指令确定单元确定所述特征指令之后的设定范围内出现了返回指令,则确定GS编译开关被开启了。【文档编号】G06F21/12GK104008314SQ201310057221【公开日】2014年8月27日申请日期:2013年2月22日优先权日:2013年2月22日【发明者】周力申请人:腾讯科技(深圳)有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1