CN116956297A - 检测方法、装置、设备、存储介质及计算机程序产品 - Google Patents

检测方法、装置、设备、存储介质及计算机程序产品 Download PDF

Info

Publication number
CN116956297A
CN116956297A CN202210389924.XA CN202210389924A CN116956297A CN 116956297 A CN116956297 A CN 116956297A CN 202210389924 A CN202210389924 A CN 202210389924A CN 116956297 A CN116956297 A CN 116956297A
Authority
CN
China
Prior art keywords
function
pointer
variable
code
statement
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
CN202210389924.XA
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.)
Tencent Technology Shenzhen Co Ltd
Original Assignee
Tencent Technology Shenzhen 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 Tencent Technology Shenzhen Co Ltd filed Critical Tencent Technology Shenzhen Co Ltd
Priority to CN202210389924.XA priority Critical patent/CN116956297A/zh
Publication of CN116956297A publication Critical patent/CN116956297A/zh
Pending legal-status Critical Current

Links

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F21/00Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
    • G06F21/50Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
    • G06F21/57Certifying or maintaining trusted computer platforms, e.g. secure boots or power-downs, version controls, system software checks, secure updates or assessing vulnerabilities
    • G06F21/577Assessing vulnerabilities and evaluating computer system security
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F8/00Arrangements for software engineering
    • G06F8/40Transformation of program code
    • G06F8/41Compilation
    • G06F8/43Checking; Contextual analysis
    • G06F8/433Dependency analysis; Data or control flow analysis
    • G06F8/434Pointers; Aliasing
    • YGENERAL TAGGING OF NEW TECHNOLOGICAL DEVELOPMENTS; GENERAL TAGGING OF CROSS-SECTIONAL TECHNOLOGIES SPANNING OVER SEVERAL SECTIONS OF THE IPC; TECHNICAL SUBJECTS COVERED BY FORMER USPC CROSS-REFERENCE ART COLLECTIONS [XRACs] AND DIGESTS
    • Y02TECHNOLOGIES OR APPLICATIONS FOR MITIGATION OR ADAPTATION AGAINST CLIMATE CHANGE
    • Y02DCLIMATE CHANGE MITIGATION TECHNOLOGIES IN INFORMATION AND COMMUNICATION TECHNOLOGIES [ICT], I.E. INFORMATION AND COMMUNICATION TECHNOLOGIES AIMING AT THE REDUCTION OF THEIR OWN ENERGY USE
    • Y02D10/00Energy efficient computing, e.g. low power processors, power management or thermal management

Landscapes

  • Engineering & Computer Science (AREA)
  • General Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Computer Hardware Design (AREA)
  • Computer Security & Cryptography (AREA)
  • Software Systems (AREA)
  • Physics & Mathematics (AREA)
  • General Physics & Mathematics (AREA)
  • Computing Systems (AREA)
  • Debugging And Monitoring (AREA)

Abstract

一种检测方法、装置、设备、存储介质及计算机程序产品,方法包括:在对代码文件进行编译的过程中,将代码文件中的目标结构体存储在结构体存储空间中;目标结构体包括指向代码文件中目标函数的函数指针,目标结构体对应的结构体指针指向函数指针;针对目标函数插入包括第一变量和第二变量的验证函数;第一变量为函数指针的地址,第二变量为函数指针的值;在运行编译后的代码文件的过程中,从结构体存储空间中获取结构体指针所指示的函数指针地址和函数指针所指示的目标值,并获取验证函数对应的第一变量值和第二变量值;基于函数指针地址、目标值、第一变量值和第二变量值,确定代码文件的检测结果。采用此方式,可以提高代码检测的效率和适用性。

Description

检测方法、装置、设备、存储介质及计算机程序产品
技术领域
本申请涉及计算机技术领域,尤其涉及检测方法、检测装置、计算机设备计算机可读存储介质及计算机程序产品。
背景技术
零日(zeroday)漏洞对操作系统的破坏日益增大,而通过修改结构体内的函数指针来控制机器的零日漏洞又占了很大一部分。目前,为了确定结构体内的函数指针是否被修改,往往需要对所有间接调用处都插入验证函数,以对所有的间接调用均进行检测。但对于内核来说,漏洞可以利用的结构体的类型只有几种,对所有的间接调用进行检测,会使得检测的效率较低。
并且,在对代码文件进行编译时,是根据函数指针的类型计算出一个64位大小的哈希值作为比较值,以在运行编译后的代码文件时,可以将该函数指针的前8个字节与该比较值进行比较,从而判断函数指针是否被修改。但是,若攻击者将函数指针修改为相同类型的函数指针,或者把与比较值相同的哈希值放置于代码文件之前,则通常无法通过上述检测方法进行漏洞检测。
发明内容
本申请实施例提供检测方法、装置、设备、存储介质及计算机程序产品,可以提高代码检测的效率和适用性。
本申请实施例一方面提供了一种检测方法,包括:
在对代码文件进行编译的过程中,将代码文件中的目标结构体存储在结构体存储空间中;其中,目标结构体为具有扩展属性的结构体,目标结构体包括函数指针,函数指针指向代码文件中的具有扩展属性的目标函数,目标结构体对应的结构体指针指向函数指针;
针对目标函数插入验证函数;验证函数包括第一变量和第二变量,第一变量为函数指针的地址,第二变量为函数指针的值;
在运行编译后的代码文件的过程中,从结构体存储空间中获取结构体指针所指示的函数指针地址和函数指针所指示的目标值,并获取验证函数对应的第一变量的第一变量值和第二变量的第二变量值;
基于函数指针地址、目标值、第一变量值和第二变量值,确定代码文件的检测结果。
本申请实施例一方面提供了一种检测装置,包括:
存储模块,用于在对代码文件进行编译的过程中,将代码文件中的目标结构体存储在结构体存储空间中;其中,目标结构体为具有扩展属性的结构体,目标结构体包括函数指针,函数指针指向代码文件中的具有扩展属性的目标函数,目标结构体对应的结构体指针指向函数指针;
处理模块,用于针对目标函数插入验证函数;验证函数包括第一变量和第二变量,第一变量为函数指针的地址,第二变量为函数指针的值;
获取模块,用于在运行编译后的代码文件的过程中,从结构体存储空间中获取结构体指针所指示的函数指针地址和函数指针所指示的目标值,并获取验证函数对应的第一变量的第一变量值和第二变量的第二变量值;
确定模块,用于基于函数指针地址、目标值、第一变量值和第二变量值,确定代码文件的检测结果。
本申请实施例一方面提供了一种计算机设备,包括存储器和处理器,存储器存储有计算机程序,计算机程序被处理器执行时,使得处理器执行本申请实施例提供的检测方法。
本申请实施例一方面提供了一种计算机存储介质,计算机存储介质存储有计算机程序,计算机程序包括程序指令,程序指令当被处理器执行时,执行本申请实施例提供的检测方法。
本申请实施例一方面提供了一种计算机程序产品,计算机程序产品包括计算机程序或计算机指令,计算机程序或计算机指令存储在计算机可读存储介质中,计算机程序或计算机指令被计算机设备的处理器执行时,执行本申请实施例提供的检测方法。
本申请实施例中,在对代码文件进行编译的过程中,通过将具有扩展属性目标结构体存储在结构体存储空间中,可以针对上述代码文件中具有扩展属性的目标结构体进行保护,并针对具有扩展属性的目标函数插入包括了第一变量和第二变量的验证函数,可以针对上述代码文件中具有扩展属性目标函数进行插桩保护;在运行编译后的代码文件过程中,可以从上述结构体存储空间中获取目标结构体对应的结构体指针所指示的函数指针地址,以及该函数指针所指示的目标值,并从验证函数中获取到第一变量值(即为函数指针的地址)和第二变量值(即为函数指针的值),以基于该函数指针地址、目标值、第一变量值和第二变量值确定出代码文件的检测结果,即确定漏洞检测的结果,从而通过针对具有扩展属性的目标结构体和目标函数进行检测,可以提高检测的效率,并根据结构体对应的结构体指针和指针所指向的函数指针之间的对应关系,进而可以获取到更准确的针对代码文件的检测结果。
附图说明
为了更清楚地说明本申请实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本申请的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。
图1是本申请实施例提供的一种检测系统;
图2是本申请实施例提供的一种检测方法的流程示意图;
图3是本申请实施例提供的一种结构体实例1中目标结构体对应的结构体指针以及结构体内的函数指针对应的代码示意图;
图4是本申请实施例提供的另一种检测方法的流程示意图;
图5是本申请实施例提供的又一种检测方法的流程示意图;
图6是本申请实施例提供的还一种检测方法的流程示意图;
图7是本申请实施例提供的一种检测装置的结构示意图;
图8是本申请实施例提供的一种计算机设备的结构示意图。
具体实施方式
下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。
为了更好的理解本申请实施例,下面先对本申请实施例涉及的一些专业术语进行介绍:
控制流完整性(Control-Flow Integrity,CFI):是计算机安全技术的通用术语,可防止各种恶意软件攻击重定向程序的执行流(控制流)。
复用攻击保护(Reuse Attack Protection,RAP):Grsecurity公司实现的一套控制流完整性商业产品的名称。
数据执行保护(Data Execution Prevention,DEP):是一项Microsoft安全功能,可监测和保护某些页面或内存区域,防止它们执行(通常是恶意的)代码。
面向返回的编程(Return Oriented Programming,ROP):是一种计算机安全漏洞利用技术,它允许攻击者在存在安全防御(例如可执行空间保护和代码签名)的情况下执行代码。
面向跳转的编程(Jump Oriented Programming,JOP):是一种计算机安全漏洞利用技术,它允许攻击者在存在安全防御(例如可执行空间保护和代码签名)的情况下执行代码。
中间表示(Intermediate representation,IR):是编译器或虚拟机内部用于表示源代码的数据结构或代码。IR也可称作中间语言,IR旨在有利于进一步处理,例如优化和翻译。
静态单赋值形式(Static single assignment,SSA):在编译器设计中,是中间表示(IR)的一种属性,它要求每个变量只被赋值一次,并且每个变量在使用之前都要定义。
零日漏洞(ZERO DAY):指软件产商还不知道的软件错误。
GUN项目(GNU project):其中,GNU是“GNU is Not Unix”的递归缩写;1983年9月27日由理查德·斯托曼在麻省理工学院公开发起。它的目标是创建一套完全自由的操作系统,称为GNU。
GNU编译器套件(GNU Compiler Collection,GCC):是由GNU项目产生的优化编译器,支持各种编程语言、硬件架构和操作系统。
低级虚拟机(Low Level Virtual Machine,LLVM):一套编译器基础设施,为自由软件,以C++语言写成,包含一系列模块化的编译器组件和工具链。
本申请实施例提供了一种检测方法,可以基于函数指针的地址、目标值、第一变量值和第二变量值,确定代码文件的检测结果,以根据代码文件的检测结果判断函数指针的值是否被篡改,即检测是否存在漏洞,进而提升检测精度。在可行的实施例中,本申请实施例提供的检测方法可以基于云技术和/或区块链技术实现。其中,云技术中的云计算(cloudcomputing)是一种计算模式,它将计算任务分布在大量计算机构成的资源池上,使各种应用系统能够根据需要获取计算力、存储空间和信息服务。提供资源的网络被称为“云”。“云”中的资源在使用者看来是可以无限扩展的,并且可以随时获取,按需使用,随时扩展。作为云计算的基础能力提供商,会建立云计算资源池(简称云平台,一般称为基础设施即服务(Infrastructure as a Service,IaaS)平台,在资源池中部署多种类型的虚拟资源,供外部客户选择使用。云计算资源池中主要包括:计算设备(为虚拟化机器,包含操作系统)、存储设备、网络设备。
区块链(Blockchain)是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式。区块链本质上是一个去中心化的数据库,是一串使用密码学方法相关联产生的数据块,每一个数据块中包含了一批次网络交易的信息,用于验证其信息的有效性(防伪)和生成下一个区块。区块链可以包括区块链底层平台、平台产品服务层以及应用服务层。
区块链底层平台可以包括用户管理、基础服务、智能合约以及运营检测等处理模块。其中,用户管理模块负责所有区块链参与者的身份信息管理,包括维护公私钥生成(账户管理)、密钥管理以及用户真实身份和区块链地址对应关系维护(权限管理)等,并且在授权的情况下,监管和审计某些真实身份的交易情况,提供风险控制的规则配置(风控审计);基础服务模块部署在所有区块链节点设备上,用来验证业务请求的有效性,并对有效请求完成共识后记录到存储上,对于一个新的业务请求,基础服务先对接口适配解析和鉴权处理(接口适配),然后通过共识算法将业务信息加密(共识管理),在加密之后完整一致的传输至共享账本上(网络通信),并进行记录存储;智能合约模块负责合约的注册发行以及合约触发和合约执行,开发人员可以通过某种编程语言定义合约逻辑,发布到区块链上(合约注册),根据合约条款的逻辑,调用密钥或者其它的事件触发执行,完成合约逻辑,同时还提供对合约升级注销的功能;运营检测模块主要负责产品发布过程中的部署、配置的修改、合约设置、云适配以及产品运行中的实时状态的可视化输出,例如:告警、检测网络情况、检测节点设备健康状态等。
请参见图1,图1为本申请实施例提供的一种检测系统的架构示意图。由图1所示,该检测系统可以包括检测设备10和数据库11。其中,检测设备10可以是具备代码编译功能和检测功能的服务器或者终端设备;服务器可以是独立的物理服务器,也可以是多个物理服务器构成的服务器集群或者分布式系统,还可以是提供云服务、云数据库、云计算、云函数、云存储、网络服务、云通信、中间件服务、域名服务、安全服务、CDN、以及大数据和人工智能平台等基础云计算服务的云服务器,等等;终端设备可以是智能手机、平板电脑、笔记本电脑、台式计算机、智能语音交互设备、智能家电、车载终端,等等,但并不局限于此。数据库11可以是检测设备10的本地数据库,也可以是检测设备10能够访问的云端数据库。需要说明的是,图1中以需要进行编译的代码文件和编译后的代码文件均存于数据库11为例进行说明,不对本申请造成限制。可选的,需要进行编译的代码文件可以存于一个数据库,编译后的代码文件可以存于另一个数据库,本申请对此不作限制。
本申请实施例提供的检测方法可以由检测设备10执行,具体的:在对代码文件进行编译的过程中,从数据库11中获取代码文件,并将该代码文件中具有扩展属性的目标结构体存储在结构体空间中,可以针对上述代码文件中具有扩展属性的目标结构体进行保护;并将去除结构体后的代码文件转换为IR,可以从该IR中获取到具有扩展属性的目标函数对应的函数代码,并从函数代码中确定出目标结构体对应的结构体指针的赋值语句,从而根据该结构体指针的赋值语句确定验证函数,并在该目标函数的函数代码插入包括第一变量(即为函数指针的地址)和第二变量(即为函数指针的值)的验证函数,从而针对代码文件中具有扩展属性的目标函数进行插桩保护,进而提高检测的效率。在运行编译后的代码文件的过程中,从数据库11中获取编译后的代码文件,并从结构体存储空间中获取结构体指针所指示的函数指针地址和函数指针所指示的目标值,并从验证函数获取第一变量值和第二变量值;以基于函数指针的地址、目标值、第一变量值和第二变量值,确定代码文件的检测结果,从而根据结构体对应的结构体指针和指针所指向的函数指针之间的对应关系,获得更准确的检测结果,进而更精确地判断出是否存在漏洞。
请参见图2,图2是本申请实施例提供的一种检测方法的流程示意图。该方法可以由图1所示的检测设备执行,该检测方法包括如下步骤:
S201,在对代码文件进行编译的过程中,将代码文件中的目标结构体存储在结构体存储空间中;其中,目标结构体为具有扩展属性的结构体,目标结构体包括函数指针,函数指针指向代码文件中的具有扩展属性的目标函数,目标结构体对应的结构体指针指向函数指针。
其中,上述代码文件可以为C语言或者C++语言形式的源代码文件。在本申请实施例中,检测设备是基于GCC编译器对代码文件进行编译的,该编译器插件可以对有特定GUN扩展属性的函数进行保护。其中,GUN扩展属性是GCC提供的一种可以在编程语言手册中进行语法扩展的方法。通过该方法对函数或者变量进行定义时,可以在类型声明时紧跟一个_attribute_(“xxx”)的标记;其中,“xxx”为需要保护的关键字。
示例性的,在本申请实施例中,关键字可以为“sanitize_struct”,以对类型中带有_attribute_(“sanitize_struct”)标记的函数或者变量(如结构体变量)进行保护。可选的,上述关键字也可以为其他关键字,本申请实施例以关键字为“sanitize_struct”进行举例说明,不对本申请造成限制。
需要说明的是,在对代码文件进行编译时,检测设备可以通过获取代码文件中的结构体,并将带有_attribute_(“sanitize_struct”)标记的结构体作为目标结构体,以将该目标结构体存储在结构体存储空间中。
示例性的,如下代码1示例性地示出了结构体的定义代码:
上述代码1中所定义的结构体类型为_attribute_((sanitize_struct))pipe_buf_operations。其中,上述代码1对应的{}中的内容,可以理解为针对该结构体的批注,以用于告诉其他开发人员该结构体的语法规则。示例性的,其中的void(*release)(structpipe_inode_info*,struct pipe_buffer*)语句,可以告诉其他开发人员,在使用返回值类型为void的release函数时,需要给出struct pipe_inode_info*和struct pipe_buffer*两个参数,从而使得计算机可以执行*release。
可以理解的是,由于该结构体的类型中带有_attribute_(sanitize_struct)标记,也就是说,该结构体为检测设备需要获取的目标结构体。检测设备在获取到该目标结构体时,可以将该目标结构体存储在结构体存储空间中。
其中,上述结构体存储空间可以理解为结构体段(也可称为结构体字段)。检测设备可以对目标结构体原始的结构体段进行修改,以将目标结构体存储至特定的结构体段。例如:检测设备可以将目标结构体所在的段名字重新设置为.sanitize_struct,以在该结构体段中存储带有_attribute_(“sanitize_struct”)标记的目标结构体。可选的,将结构体所在的段名字设置为.sanitize_struct,仅用于举例,不对本申请造成限制。
需要说明的是,每个结构体都对应一个的结构体指针,一个结构体的结构体指针可以用于表示该结构体在内存中的起始地址。例如,结构体A的结构体指针A可以用于表示结构体A在内存中的起始地址为地址A,结构体B的结构体指针B可以用于表示结构体B在内存中的起始地址为地址B。
还需要说明的是,结构体指针还可以用于指向一个结构体或者结构体中的成员。本申请实施例中,目标结构体对应的结构体指针可以用于指向目标结构体的成员;其中,该目标结构体的成员为函数指针,该函数指针指向具有扩展属性的目标函数。也就是说,目标结构体的结构体指针所指向的函数指针指向了带有_attribute_(“sanitize_struct”)标记的目标函数。
S202,针对目标函数插入验证函数;验证函数包括第一变量和第二变量,第一变量为函数指针的地址,第二变量为函数指针的值。
其中,上述验证函数为GCC编译器生成的用于验证结构体内的函数指针是否被篡改的函数。该验证函数所包括的第一变量和第二变量可以根据下文提及的结构体指针对应的赋值语句确定,具体可参见下文的详细描述,本申请在此不再赘述。
在一种实现方式中,将去除结构体后的代码文件进行编程语言转换,得到转换后的代码文件;从转换后的代码文件中确定目标函数对应的函数代码,并从函数代码中确定结构体指针对应的赋值语句;基于赋值语句确定验证函数。
由前述内容可知,代码文件可以为C语言或者C++语言的源代码。检测设备在从源代码中获取目标结构体的过程中,可以将源代码中所包括的所有结构体相关的代码文件除去,以便将剩余的代码文件转换为编程语言,进而从该编程语言中获取目标函数。
其中,上述编程语言可以为IR。在GCC编译器中,与该编译器对应的IR可以称为GIMPLE(GCC编译器中的中间表示)。检测设备将去除结构体后的代码文件转换为IR后,可以通过GCC提供的迭代器,遍历每一条SSA形式的IR。其中,对于SSA形式的IR所对应的每一个赋值表达式,该赋值表达式的左值都是一个新的变量,以便于在后续插入验证函数时,可以为赋值表达式的左值进行新变量的赋值。
在一种实现方式中,对函数代码中的每一条代码语句进行检测,从函数代码中确定间接调用语句;从函数代码中获取间接调用语句的定义语句;当定义语句中与结构体指针具有对应关系时,将定义语句确定为结构体指针对应的赋值语句。
其中,上述间接调用语句可以为GCC编译器中的GIMPLE_CALL(对应高级语言中的函数调用语句)语句,该GIMPLE_CALL语句可以对应高级语言中的函数调用语句。在本申请实施例中,GCC中的GIMPLE_CALL语句可以对应C语言或C++语言中的函数调用语句。
在一种实现方式中,针对函数代码中的任一条代码语句,检测该任一条代码语句是否为函数调用类型的代码语句;若为函数调用类型的代码语句,且该任一条代码语句对应的抽象语法树(Abstract Syntax Tree,AST)的类型为静态单赋值形式SSA变量,并且针对所述静态单赋值形式SSA变量的定义变量为空,则确定该任一条代码语句为间接调用语句。
其中,上述函数调用类型的代码语句可以为上述GIMPLE_CALL语句。
需要说明的是,上述SSA变量可以理解为只被赋值一次的变量。例如,假设源代码中首先将x赋值为1(即x=1),再将x赋值为2(即x=2),并将y赋值为x(y=x);在将上述源代码转换为SSA形式的IR时,可以先把各个变量进行编号,即得到:x1=1;x2=2;y1=x2;由于每个变量只被赋值一次,因此,按照SSA的定义原则,对x1的赋值语句为无用语句,得到优化之后的IR可以为:x2=2;y1=x2。其中,上述IR中的x2和y1可以为SSA变量。
需要说明的是,SSA变量的定义变量为空可以理解为,该SSA变量在源代码中未被定义。假设上述x2和y1两个变量在源代码中未被定义,即上述x2和y1两个变量在源代码中,未被定义为结构体或未被定义为其他变量时,则可以确定上述x2和y1的定义变量为空。
具体的,检测设备可以首先从函数代码的任一条代码语句中获取到GIMPLE_CALL语句,再判断该GIMPLE_CALL语句对应的AST的类型是否为SSA变量;若该GIMPLE_CALL语句对应的AST的类型为SSA变量,再判断该SSA变量的定义变量是否为空;若该SSA变量的定义变量为空,则可以确定上述GIMPLE_CALL语句为间接调用语句。
在检查设备从上述函数代码中确定出间接调用语句后,可以从上述函数代码中获取到该间接调用语句的定义语句。具体的,若获取到的间接调用语句的定义语句中与结构体指针的具有对应关系,则可以将该间接调用语句的定义语句确定为该结构体指针对应的赋值语句。换言之,间接调用语句的定义语句中若存在结构体指针,则该定义语句可以确定为针对结构体指针的定义语句,即上述结构体指针对应的赋值语句。
示例性的,如下代码2示例性地示出了C语言中的一个函数的代码:
上述代码2中所定义的函数的返回值类型为void,即该函数为无返回值的函数;该函数的函数名为pipe_buf_release,该函数的参数为structpipe_inode_info*pipe和struct pipe_buffer*buf。其中,structpipe_inode_info*pipe定义了指向struct pipe_inode_info的结构体指针pipe,struct pipe_buffer*buf定义了指向struct pipe_buffer的结构体指针buf。具体的,在该函数的执行语句中还定义了一个指向struct pipe_buf_operations的结构体指针ops。其中,该结构体指针ops可以为buf指向的结构体(即结构体struct pipe_buffer)中的成员。该函数的执行语句还将buf指向的结构体内的ops设置为NULL,即为空;并让ops指向了结构体pipe_buf_operations内的release函数,即通过ops调用release函数。
需要说明的是,检测设备在对如代码1所示的目标结构体进行存储之后,可以将代码文件中去除结构体的代码文件进行编程语言的转换。可以理解的是,上述代码2不为结构体对应的代码,因此,上述代码2可以为去除结构体的代码文件中的一部分。也就是说,检测设备可以将上述代码2进行编程语言转换,以得到与上述代码2对应的IR。
示例性的,如下代码3示例性地示出了将上述代码2进行编程语言转换后的代码:
/>
上述代码3中示例性地示出了代码2所示函数的声明语句、基本块语句以及函数的执行语句。由上述代码3中的__attribute__((sanitize_struct,noinline))语句,可以确定该函数为带有_attribute_(“sanitize_struct”)标记的函数,即上述目标函数。可以理解的是,上述代码3可以为目标函数对应的函数代码。
具体的,检测设备在确定上述目标函数后,可以对函数代码中的每一条IR进行检测,以从函数代码中确定出函数调用对应的代码语句,即上述_1(pipe_6(D),buf_3(D))语句。由于该函数调用语句中的_1为编译器生成的临时变量,因此它所对应源代码中的变量为空,因此,检测设备可以确定该函数调用类型的代码语句为间接调用语句。
检测设备根据该间接调用语句,可以获取到该间接调用语句中_1的定义语句,即上述_1=ops_4->release语句。由于该定义语句中的结构体指针ops指向结构体pipe_buf_operations,且由前述目标结构体对应的代码文件的示例可知,该结构体pipe_buf_operations可以为需要保护的目标结构体。因此,可以理解的是,上述_1=ops_4->release语句可以为检测设备需要获取的目标结构体对应的结构体指针对应的赋值语句。
可选的,检测设备可以生成一个名为“__sanitizer_struct_guard__”,类型为void*__sanitizer_struct_guard__(void*p1,void*p2)的验证函数,并基于上述结构体指针对应的赋值语句,确定为该验证函数所包括的第一变量(即p1)和第二变量(即p2)。具体的,检测设备可以将赋值语句中的右值(即赋值表达式右边的值),即由上述ops_4->release重新构建成的取值表达式&ops_4->release作为验证函数的第一变量值;并将赋值语句中的左值(即赋值表达式左边的值),即上述_1的值作为验证函数的第二变量值。
需要说明的是,由于在上述函数代码中的IR均为SSA形式的IR,因此,在函数代码中插入验证函数时,可以生成一个SSA形式的临时变量,以将该临时变量作为验证函数的左值。在生成上述临时变量之后,检测设备还可以遍历所有使用上述结构体指针赋值语句中左值的语句,即使用上述_1的语句,以将其替换为生成的临时变量。
示例性的,如下代码4示例性地示出了在上述代码3中插入了验证函数后的代码:
/>
上述代码4中,检测设备将ops_4->release(即上述结构体指针对应的赋值语句的右值)变换成一个取地址表达式(即&ops_4->release)后作为验证函数的第一变量值,将_1(即上述结构体指针对应的赋值语句的左值)为验证函数的第二变量值,即生成验证函数__sanitizer_struct_guard__(&ops_4->release,_1),并将该验证函数插入上述代码3中。具体的,检测设备还可以生成STRUCT_I_8以作为一个SSA形式的临时变量,并将该STRUCT_I_8作为验证函数的左值,即STRUCT_I_8=__sanitizer_struct_guard__(&ops_4->release,_1)。检测设备还可以遍历所有使用上述_1的语句,将该语句中的_1替换为STRUCT_I_8;即检测设备可以获取到_1(pipe_6(D),buf_3(D))语句,并将该语句替换为STRUCT_I_8(pipe_6(D),buf_3(D))。
检测设备通过获取到的赋值语句的左值和右值,可以生成上述验证函数,以在针对该验证函数进行运行的过程中,可以从该验证函数中获取到函数指针的地址(上述左值)以及函数指针的值(上述右值),从而根据上述函数指针的地址以及上述函数指针的值,判断函数指针是否被篡改。
本申请实施例在对代码文件进行编译的过程中,可以将目标结构体存储在结构体存储空间中,并将去除结构体后的代码文件转换为IR,以从该IR中获取到目标函数对应的函数代码,并从函数代码中确定出目标结构体对应的结构体指针的赋值语句,从而根据该结构体指针的赋值语句确定验证函数,从而在函数代码中插入该验证函数,进而实现对具有扩展属性的目标结构体以及具有扩展属性的目标函数的保护。
S203,在运行编译后的代码文件的过程中,从结构体存储空间(段名字为.sanitize_struct)中获取结构体指针所指示的函数指针地址和函数指针所指示的目标值,并获取验证函数对应的第一变量的第一变量值和第二变量的第二变量值。
检测设备对上述代码文件进行编译之后,可以对编译后的代码文件进行运行。具体的,运行过程主要可以分为两个部分,一是初始化部分,即上述从结构体存储空间(段名字为.sanitize_struct)中获取结构体指针所指示的函数指针地址和函数指针所指示的目标值;二是验证函数的运行部分,即上述获取验证函数对应的第一变量的第一变量值和第二变量的第二变量值。
需要说明的是,在运行过程,检测设备可以申请一个特定大小的内存空间,如128M大小的内存空间,以作为结构体的影子内存,用于保存各个结构体实例中每个结构体实例和该结构体内的函数指针的对应关系。可选的,本申请实施例以128M大小的内存空间作为结构体的影子内存进行说明,不对本申请造成限制。
其中,在代码文件中获取并保存的目标结构体,可以在运行过程中根据获取到的函数的不同,而生成不同的结构体实例。示例性的,如下代码示例性地示出了3个不同的结构体实例。
结构体实例1:
其中,结构体实例1名为“default_pipe_buf_ops”,该结构体实例1中的结构体(如称为目标结构体1)类型为pipe_buf_operations,该结构体内的函数指针(即前述函数代码中的release,如称为函数指针1)指向的函数为“generic_pipe_buf_release”。也就是说,针对该结构体实例1,在影子内存中可以保存目标结构体1与函数指针1的对应关系。
结构体实例2:
其中,结构体实例2名为“nosteal_pipe_buf_ops”,该结构体实例2中的结构体(如称为目标结构体2)类型为pipe_buf_operations,该结构体内的函数指针(如称为函数指针2)指向的函数为“generic_pipe_buf_release”。也就是说,针对该结构体实例2,在影子内存中可以保存目标结构体2与函数指针2的对应关系。其中,可以看出函数指针2指向的函数与函数指针1指向的函数为同一函数,即函数指针2和函数指针1可以为同一函数指针。
结构体实例3:
其中,结构体实例3名为“page_cache_pipe_buf_ops”,该结构体实例3中的结构体(如称为目标结构体3)类型为pipe_buf_operations,该结构体内的函数指针(如称为函数指针3)指向的函数为“page_cache_pipe_buf_release”。也就是说,针对该结构体实例3,在影子内存中可以保存目标结构体3与函数指针3的对应关系。
需要说明的是,上述3个不同的结构体实例中,3个结构体的类型均为“pipe_buf_operations”,即为前述目标结构体。也就是说,该3个结构体可以为同一类型的结构体所对应的不同结构体实例。
可以理解的是,影子内存中可以保存需要保护的各个结构体实例中每个目标结构体与该目标结构体内函数指针的对应关系。例如,在结构体实例1中的release函数指针指向generic_pipe_buf_release,则针对结构体实例1可以在影子内存中存储结构体实例1中release的地址以及release所指向的generic_pipe_buf_release函数的值。在结构体实例3中的release函数指针指向page_cache_pipe_buf_release,则针对结构体实例3可以在影子内存中存储结构体实例3中release的地址以及release所指向的page_cache_pipe_buf_release函数的值。
示例性的,图3示例性地示出了结构体实例1中目标结构体对应的结构体指针以及结构体内的函数指针对应的代码示意图。检测设备在针对结构体实例1的初始化过程中,可以获取到目标结构体1对应的结构体指针所指示的函数指针地址。其中,由目标结构体1“default_pipe_buf_ops”所对应的结构体指针的值(首地址),即图3中301所示的“0xffffffff89bb51a0”,可以获取到该结构体内的函数指针地址为“0xffffffff89bb51a8”。检测设备还可以获取到该函数指针所指示的目标值(即函数指针1的值,或函数指针1所指向的函数“generic_pipe_buf_release”的地址),即图3中302所示的“0xffffffff81cd3400”。可选的,函数指针1所指向的函数“generic_pipe_buf_release”的地址,可以从图3中303所示部分获取,本申请对此不作限制。
需要说明的是,检测设备在对验证函数进行运行的过程中,可以获取到该验证函数对应的第一变量的第一变量值和第二变量的第二变量值。由前述内容可知,第一变量为函数指针的地址,也就是结构体成员的地址,即图3中302所对应的地址,即上述“0xffffffff89bb51a8”;第二变量为函数指针的值,也就是结构体内成员的具体值,即图3中302所对应的值,即上述“0xffffffff81cd3400”。可选的,在结构体内的成员为函数指针时,该结构体成员的值即为函数指针所指向的函数的地址,如图3中303所示,即“0xffffffff81cd3400”。
S204,基于函数指针地址、目标值、第一变量值和第二变量值,确定代码文件的检测结果。
检测设备通过初始化运行获取到目标结构体内函数指针地址和函数指针指示的目标值,并通过运行验证函数获取到第一变量值和第二变量值后,可以基于函数指针地址和目标值进行运算,并将第一变量值和第二变量值进行运算,从而根据两次运算结果,确定代码文件的检测结果。
在一种实现方式中,将函数指针地址和目标值进行异或运算,得到第一运算结果;将第一变量值和第二变量值进行异或运算,得到第二运算结果;基于第一运算结果和第二运算结果确定检测结果。
需要说明的是,检测设备可以将函数指针地址和目标值进行异或运算,并将第一变量值和第二变量值进行异或运算,以得到第一运算结果和第二运算结果,从而使得检测设备可以根据该第一运算结果和该第二运算结果确定检测结果。
在一种实现方式中,将第一运算结果和影子内存参数进行取模运算,得到第一运算结果对应的在影子内存中的第一位置;影子内存为用于存储结构体实例和其内指针的对应关系的内存空间;将第二运算结果和影子内存参数进行取模运算,得到第二运算结果对应的在影子内存中的第二位置;根据第一位置和第二位置的比较结果确定检测结果。
其中,上述影子内存参数即为影子内存的大小,如前述128M的大小。换言之,检测设备可以将上述第一运算结果和128M大小的影子内存进行取模运算,得到对应在影子内存中的第一位置;检测设备还可以将第二运算结果和128M大小的影子内存进行取模运算,得到对应在影子内存中的第二位置。
需要说明的是,将第一运算结果和128M大小的影子内存取模,可以理解为将第一运算结果控制在128M大小以内,已将各个结构体实例的各个运算结果都对应在影子内存中对应的位置上。
在一种实现方式中,将第一位置和第二位置进行比较,得到比较结果;若比较结果指示第一位置和第二位置相匹配,则得到用于指示函数指针的值未被篡改的检测结果;若比较结果指示第一位置和第二位置不相匹配,则得到用于指示函数指针的值被篡改的检测结果。
由前述内容可知,各个结构体实例中的不同的目标结构体与该目标结构体内的函数指针的对应关系是不同的。因此,各个结构体实例中函数指针地址与目标值进行异或运算之后的运算结果也是不同的,将该运算结果与128M大小的影子内存取模对应在影子内存中的位置也是不同的。换言之,在初始化运行过程中,检测设备可以将存储在结构体存储空间中的各个目标结构体对应到影子内存中的各个位置上,以便在运行验证函数的过程中对上述各个位置进行检测。
需要说明的是,由于上述第一变量的值可以为从目标函数的函数代码中获取的函数指针的地址,上述第二变量可以为从目标函数的函数代码中获取的函数指针的值。因此,在函数指针的值未被篡改的情况下,通过第一变量值与第二变量值得到的第二位置,可以与通过函数指针地址和目标值得到的第一位置相匹配,即第二位置与上述第一位置一致。可选的,在函数指针的值被篡改的情况下,通过第一变量值与第二变量值得到的第二位置,与通过函数指针地址和目标值得到的第一位置将不相匹配,即第二位置与上述第一位置不一致。
可选的,检测设备在获取到函数指针的值未被篡改的情况下,即未检测到漏洞的情况下,可以返回第二变量值,即继续运行上述函数指针;检测设备在获取到函数指针的值被篡改的情况下,即检测到漏洞的情况下,可以中断程序的运行,如运行ud2指令以指示产生了异常。
本申请实施例在对编译后的代码文件进行运行的过程中,可以通过从结构体存储空间中获取结构体指针所指示的函数指针地址和函数指针所指示的目标值,并从验证函数中获取到第一变量值和第二变量值,以基于该函数指针地址、目标值、第一变量值和第二变量值确定出代码文件的检测结果,从而判断出结构体内的函数指针是否被篡改。
图4是本申请实施例提供的一种检测方法的流程示意图。该检测方法可以由图1所示的检测设备执行,该检测方法包括如下步骤:
S401,获取代码文件。其中,上述代码文件可以为带编译的源代码,如C语言或C++语言形式的代码文件。
S402,对代码文件进行词法和语法的解析。
需要说明的是,检测设备可以对源代码中的语句逐句进行词法和语法的解析,以在后续的步骤中可以从该源代码中确定出为结构体的语句,以及不为结构体的语句。
S403,判断代码文件中的语句是否为结构体。若是结构体,则执行S404;若不是结构体,则执行S406。
S404,判断结构体的类型中是否存在_attribute_(sanitize_struct)。若结构体的类型中存在_attribute_(sanitize_struct),则执行S405;若结构体的类型中不存在_attribute_(sanitize_struct),则不做操作。
S405,修改结构体段为.sanitize_struct。
需要说明的是,将类型中存在_attribute_(sanitize_struct)的结构体对应的结构体所在的段名字重新设置为.sanitize_struct之后,即已将需要保护的结构体完成了编译过程的操作。换言之,如下S406及之后的步骤,则是在对需要保护的目标函数进行查找以及插桩保护的过程。
S406,针对不是结构体的代码文件,生成IR。
检测设备将不为结构体的语句转换为IR,可以将源代码转换为编译器可以进行编译的代码文件,以便后续可以针对目标函数的函数代码插入验证函数。
S407,在生成的IR中运行struct_sanitizer PASS。
检测函数可以调用一个PASS函数(将具体任务集中在一起的函数),并设置该PASS函数的任务为struct_sanitizer,以使得该PASS函数可以从上述IR中获取到目标函数对应的函数代码,即存在_attribute_(sanitize_struct)的函数对应的IR。
S408,判断通过上述struct_sanitizer PASS获取到的函数属性中是否有_attribute_(sanitize_struct)。若函数属性中有_attribute_(sanitize_struct),即为目标函数对应的函数代码,则执行S409;若函数属性中没有_attribute_(sanitize_struct),则结束对上述函数对应的函数代码的操作。
S409,遍历属性中有_attribute_(sanitize_struct)属性的函数的基本块。
其中,上述基本块可以为目标函数中顺序执行的语句序列。需要说明的是,每一个基本块只有一个入口和一个出口,入口就是该基本块的第一个语句,出口就是该基本块的最后一个语句。对于每一个基本块来说,执行时只从其入口进入,从其出口退出。例如,目标函数的操作流程中所有“是”对应的语句,即为该目标函数的一个基本块。可以理解的是,一个目标函数中可以存在一个或多个基本块。
S410,获取上述函数基本块中的每一条中间表达式。
其中,上述中间表达式可以为SSA形式的IR。检测设备在确定了目标函数后,可以遍历目标函数的基本块,以获取到目标函数对应的每一条中间表达式。
S411,判断中间表达式中的函数调用类型的语句是否为间接调用(即GIMPLE_CALL语句)。若为间接调用语句,则执行S412,若不为间接调用语句,则结束对上述中间表达式的操作。
S412,获取上述间接调用对应的定义语句。
S413,判断上述定语语句中的结构体类型属性是否有(sanitize_struct)属性。若结构体类型属性有(sanitize_struct)属性,则执行S414;若结构体类型属性没有(sanitize_struct)属性,则结束针对上述定义语句的操作。
检测设备在判断了上述函数调用类型的语句为间接调用语句之后,可以获取该间接调用语句对应的定义语句,并根据该定义语句判断该定义语句中的结构体类型属性是否有(sanitize_struct)属性。
S414,根据上述定语语句,生成_sanitizer_struct_guard_函数。
检测设备可以根据上述定义语句的左值和右值,生成_sanitizer_struct_guard_函数,即验证函数。
S415,将函数调用(即上述间接调用)语句中的左值,替换为生成_sanitizer_struct_guard_函数的返回值。
检测设备生成验证函数之后,可以遍历函数代码中所有使用定语语句左值的语句,并将该语句中的左值替换为验证函数的左值。
需要说明的是,对于用户态程序(上述对代码文件进行编译的过程可以为用户态程序),检测设备可以利用编译器生成一个“.init_array”的段,在C运行库(GUN发布的libc库,glibc)里的装载器则会自动调用该“.init_array”段里面的函数。
还需要说明的是,上述S401-S415对应的具体内容,可参见前述图2对应实施例中S201-S202中的详细描述,本申请在此不再赘述。
本申请实施例中,通过对源代码文件进行分析,可以修改需要保护的目标结构体对应的结构体段,以在编译过程中完成对目标结构体的保护;并从生成的IR中获取到需要保护的目标函数,以从该目标函数的函数代码中获取到间接调用语句的定义语句,从而根据该定义语句生成验证函数,进而在编译过程中完成对目标函数的保护。
图5是本申请实施例提供的一种检测方法的流程示意图。该检测方法可以由图1所示的检测设备执行,该检测方法包括如下步骤:
S501,初始化128M影子内存。
其中,初始化128M影子内存,可以理解为申请一个大小为128M的内存空间作为影子内存,以在后续的步骤中,可以通过该初始化的影子内存存储结构体实例和其内函数指针的对应关系。
需要说明的是,S501对应的具体内容,可参见前述图2对应实施例中S203中的详细描述,本申请在此不再赘述。
S502,按结构体段.sanitize_struct中的内容,初始化对应影子内存的位置。
可选的,检测设备可以将初始化得到的位置(即上述第一位置),作为在影子内存中的偏移。例如,检测设备可以将上述初始化得到的位置偏移处置为1,该偏移的大小为一个字节。
需要说明的是,检测设备将结构体所在段的名字重新设置为.sanitize_struct之后,为了能确定该结构体段的内容在初始化时可以被自行识别,运行时需要修改链接工具的脚本,以增加对“.sanitize_struct”段的链接脚本,并在开头和结尾要加入“__sanitize_struct_start”和“__sanitize_struct_stop”两个全局变量,从而使得在程序初始化时会从开始(即“__sanitize_struct_start”)到结束(即“__sanitize_struct_stop”)去遍历。
需要说明的是,对于内核态程序(上述对编译后代码文件运行的过程可以为内核态程序),检测可以在load_moudle()函数中加入查找“.sanitize_struct”段,并获取其段的大小和该段的起始地址,以针对“.sanitize_struct”段的内容执行影子内存的初始化。可选的,检测设备还可以将128M的影子内存设置为只读,以保证该影子内存中的内容不会被修改。
还需要说明的是,S502对应的具体内容,可参见前述图2对应实施例中S203-S204中的详细描述,本申请在此不再赘述。
本申请实施例中,通过初始化影子内存,以得到初始化后的影子内存,并获取结构体段中存储的各个结构体实例,以将各个结构体实例中的结构体与其内的函数指针的对应关系,保存至影子内存中的位置,从而通过初始化过程获取到结构体与其内的函数指针之间的一一对应关系,进而使得在后续的验证过程中,可以根据该一一对应关系对目标函数进行验证。
图6是本申请实施例提供的一种检测方法的流程示意图。该检测方法可以由图1所示的检测设备执行,该检测方法包括如下步骤:
S601,获取验证函数的参数1(即前述第一变量值)和参数2(即前述第二变量值)进行异或运算,并对128M影子内存取模。
S602,判断上述运算结果在影子内存中对应的偏移是否为1。若在影子内存中对应的偏移为1,则执行S603;若在影子内存中对应的偏移不为1,则执行S604。
由前述内容可知,检测设备可以将初始化得到的位置在影子内存中偏移处置为1;也就是说,检测设置可以通过判断S601中的运算结果(即前述第二位置)在影子内存中的偏移是否为1,即可以判断该运算结果是否与初始化的结果一致,从而判断目标函数中的函数指针是否被篡改。
S603,返回前述验证函数中参数2的值,即继续运行函数指针。
S604,执行ud2指令。
需要说明的是,S601-S604对应的具体内容,可参见前述图2对应实施例中S203-S204中的详细描述,本申请在此不再赘述。
本申请实施例中,通过获取验证函数中的参数1和参数2,以将该参数1和参数2进行异或运算并对128M影子内存取模,从而判断在影子内存中是否上述运算结果(即位置),进而在影子内存中存在上述运算结果的情况下(即函数指针未被篡改),继续运行函数指针;在影子内存中不存在上述运算结果的情况下(即函数指针被篡改),中断程序的运行以报告产生异常。
另外,在本申请的具体实施方式中,涉及到代码文件(可以包括如源代码、编译后的代码文件、函数代码、目标结构体、目标函数等等)中的相关的数据,所涉及使用到的数据均是经过用户授权的。当本申请以上实施例运用到具体产品或技术中时,所涉及使用到的数据需要获得用户许可或者同意,且相关数据的收集、使用和处理需要遵守相关国家和地区的相关法律法规和标准。
进一步的,请参见图7,图7是本申请实施例提供的一种检测装置的结构示意图。如图7所示,检测装置700可以应用于上述图1对应实施例中的检测设备。具体的,检测装置700可以是运行于检测设备中的一个计算机程序(包括程序代码),例如该检测装置700为一个应用软件;该检测装置700可以用于执行图2-图6对应实施例提供的方法中的相应步骤。
检测装置700可以包括:存储单元701、处理单元702、获取单元703和确定单元704。
存储单元701,用于在对代码文件进行编译的过程中,将代码文件中的目标结构体存储在结构体存储空间中;其中,目标结构体为具有扩展属性的结构体,目标结构体包括函数指针,函数指针指向代码文件中的具有扩展属性的目标函数,目标结构体对应的结构体指针指向函数指针;
处理单元702,用于针对目标函数插入验证函数;验证函数包括第一变量和第二变量,第一变量为函数指针的地址,第二变量为函数指针的值;
获取单元703,用于在运行编译后的代码文件的过程中,从结构体存储空间中获取结构体指针所指示的函数指针地址和函数指针所指示的目标值,并获取验证函数对应的第一变量的第一变量值和第二变量的第二变量值;
确定单元704,用于基于函数指针地址、目标值、第一变量值和第二变量值,确定代码文件的检测结果。
在一种可能的实现方式中,上述处理单元702,还用于将函数指针地址和目标值进行异或运算,得到第一运算结果;上述处理单元702,还用于将第一变量值和第二变量值进行异或运算,得到第二运算结果;上述确定单元704,还用于基于第一运算结果和第二运算结果确定检测结果。
在一种可能的实现方式中,上述处理单元702,还用于将第一运算结果和影子内存参数进行取模运算,得到第一运算结果对应的在影子内存中的第一位置;影子内存为用于存储结构体实例和其内指针的对应关系的内存空间;上述处理单元702,还用于将第二运算结果和影子内存参数进行取模运算,得到第二运算结果对应的在影子内存中的第二位置;上述确定单元704,还用于根据第一位置和第二位置的比较结果确定检测结果。
在一种可能的实现方式中,上述处理单元702,还用于将第一位置和第二位置进行比较,得到比较结果;若比较结果指示第一位置和第二位置相匹配,则得到用于指示函数指针的值未被篡改的检测结果;若比较结果指示第一位置和第二位置不相匹配,则得到用于指示函数指针的值被篡改的检测结果。
在一种可能的实现方式中,上述处理单元702,还用于将去除结构体后的代码文件进行编程语言转换,得到转换后的代码文件;上述确定单元704,还用于从转换后的代码文件中确定目标函数对应的函数代码,并从函数代码中确定结构体指针对应的赋值语句;上述确定单元704,还用于基于赋值语句确定验证函数。
在一种可能的实现方式中,上述确定单元704,还用于对函数代码中的每一条代码语句进行检测,从函数代码中确定间接调用语句;上述获取单元703,还用于从函数代码中获取间接调用语句的定义语句;当定义语句中与结构体指针具有对应关系时,上述确定单元704,还用于将定义语句确定为结构体指针对应的赋值语句。
在一种可能的实现方式中,上述处理单元702,还用于针对函数代码中的任一条代码语句,检测任一条代码语句是否为调用类型的代码语句;若为调用类型的代码语句,且任一条代码语句对应的抽象语法树AST的类型为静态单赋值形式SSA变量,并且针对静态单赋值形式SSA变量的定义变量为空,则上述确定单元704,还用于确定任一条代码语句为间接调用语句。
根据本申请的实施例,图7所示的检测装置中的各个单元可以分别或全部合并为一个或若干个另外的单元来构成,或者其中的某个(些)单元还可以再拆分为功能上更小的多个单元来构成,这可以实现同样的操作,而不影响本申请的实施例的技术效果的实现。上述单元是基于逻辑功能划分的,在实际应用中,一个单元的功能也可以由多个单元来实现,或者多个单元的功能由一个单元实现。在本申请的其它实施例中,基于检测装置也可以包括其它单元,在实际应用中,这些功能也可以由其它单元协助实现,并且可以由多个单元协作实现。
根据本申请的实施例,可以通过在包括中央处理单元(CPU)、随机存取存储介质(RAM)、只读存储介质(ROM)等处理元件和存储元件的例如计算机的通用计算设备上运行能够执行如图2-图6所示的相应方法所涉及的各步骤的计算机程序(包括程序代码),来构造如图7中所示的检测装置,以及来实现本申请实施例检测方法。上述计算机程序可以记载于例如计算机存储介质上,并通过计算机存储介质装载于上述计算设备中,并在其中运行。
进一步地,请参见图8,图8是本申请实施例提供的一种计算机设备的结构示意图。该计算机设备800还可以用于实现上述方法实施例中服务器的功能。如图8所示,该计算机设备800至少可包括:处理器801、通信接口802以及计算机存储介质803。其中,处理器801、通信接口802以及计算机存储介质803可通过总线或其他方式连接。
计算机存储介质803可以存储在计算机设备800的存储器804中,该计算机存储介质803用于存储计算机程序,该计算机程序包括程序指令,上述处理器801用于执行计算机存储介质803存储的程序指令。处理器801(或称CPU(Central Processing Unit,中央处理器))是计算机设备800的计算核心以及控制核心,其适于实现一条或多条指令,具体适于加载并执行:
在对代码文件进行编译的过程中,将代码文件中的目标结构体存储在结构体存储空间中;其中,目标结构体为具有扩展属性的结构体,目标结构体包括函数指针,函数指针指向代码文件中的具有扩展属性的目标函数,目标结构体对应的结构体指针指向函数指针;
针对目标函数插入验证函数;验证函数包括第一变量和第二变量,第一变量为函数指针的地址,第二变量为函数指针的值;
在运行编译后的代码文件的过程中,从结构体存储空间中获取结构体指针所指示的函数指针地址和函数指针所指示的目标值,并获取验证函数对应的第一变量的第一变量值和第二变量的第二变量值;
基于函数指针地址、目标值、第一变量值和第二变量值,确定代码文件的检测结果。
在一种可能的实现方式中,上述处理器801,还用于将函数指针地址和目标值进行异或运算,得到第一运算结果;上述处理器801,还用于将第一变量值和第二变量值进行异或运算,得到第二运算结果;上述处理器801,还用于基于第一运算结果和第二运算结果确定检测结果。
在一种可能的实现方式中,上述处理器801,还用于将第一运算结果和影子内存参数进行取模运算,得到第一运算结果对应的在影子内存中的第一位置;影子内存为用于存储结构体实例和其内指针的对应关系的内存空间;上述处理器801,还用于将第二运算结果和影子内存参数进行取模运算,得到第二运算结果对应的在影子内存中的第二位置;上述处理器801,还用于根据第一位置和第二位置的比较结果确定检测结果。
在一种可能的实现方式中,上述处理器801,还用于将第一位置和第二位置进行比较,得到比较结果;若比较结果指示第一位置和第二位置相匹配,则得到用于指示函数指针的值未被篡改的检测结果;若比较结果指示第一位置和第二位置不相匹配,则得到用于指示函数指针的值被篡改的检测结果。
在一种可能的实现方式中,上述处理器801,还用于将去除结构体后的代码文件进行编程语言转换,得到转换后的代码文件;上述处理器801,还用于从转换后的代码文件中确定目标函数对应的函数代码,并从函数代码中确定结构体指针对应的赋值语句;上述处理器801,还用于基于赋值语句确定验证函数。
在一种可能的实现方式中,上述处理器801,还用于对函数代码中的每一条代码语句进行检测,从函数代码中确定间接调用语句;上述处理器801,还用于从函数代码中获取间接调用语句的定义语句;当定义语句中与结构体指针具有对应关系时,上述处理器801,还用于将定义语句确定为结构体指针对应的赋值语句。
在一种可能的实现方式中,上述处理器801,还用于针对函数代码中的任一条代码语句,检测任一条代码语句是否为调用类型的代码语句;若为调用类型的代码语句,且任一条代码语句对应的抽象语法树AST的类型为静态单赋值形式SSA变量,并且针对静态单赋值形式SSA变量的定义变量为空,则上述处理器801,还用于确定任一条代码语句为间接调用语句。
应当理解,本申请实施例中所描述的计算机设备800可执行前文图2-图6所对应实施例中对检测方法的描述,也可执行前文图7实施例中对检测装置700在此不再赘述。另外,对采用相同方法的有益效果描述,也不再进行赘述。
此外,这里需要指出的是:本申请实施例还提供了一种计算机存储介质,且计算机存储介质中存储有前文提及的检测装置700所执行的计算机程序,且计算机程序包括程序指令,当处理器执行程序指令时,能够执行前文图2-图6所对应实施例中对检测方法的描述,因此,这里将不再进行赘述。另外,对采用相同方法的有益效果描述,也不再进行赘述。对于本申请所涉及的计算机存储介质实施例中未披露的技术细节,请参照本申请方法实施例的描述。作为示例,程序指令可以被部署在一个计算机设备上执行,或者在位于一个地点的多个计算机设备上执行,又或者,分布在多个地点且通过通信网络互联的多个计算机设备上执行,分布在多个地点且通过通信网络互联的多个计算机设备可以组合为区块链网络。
根据本申请的一个方面,提供了一种计算机程序产品或计算机程序,该计算机程序产品或计算机程序包括计算机指令,该计算机指令存储在计算机可读存储介质中。计算机设备的处理器从计算机可读存储介质读取该计算机指令,处理器执行该计算机指令,使得该计算机设备可以执行前文图2-图6所对应实施例中的方法,因此,这里将不再进行赘述。
本领域普通技术人员可以意识到,结合本申请中所公开的实施例描述的各示例的单元及步骤,能够以电子硬件、或者计算机软件和电子硬件的结合来实现。这些功能究竟以硬件还是软件方式来执行,取决于技术方案的特定应用和设计约束条件。专业技术人员可以对每个特定的应用,使用不同方法来实现所描述的功能,但是这种实现不应认为超出本申请的范围。
在上述实施例中,可以全部或部分地通过软件、硬件、固件或者其任意组合来实现。当使用软件实现时,可以全部或部分地以计算机程序产品的形式实现。计算机程序产品包括一个或多个计算机指令。在计算机上加载和执行计算机程序指令时,全部或部分地产生按照本发明实施例所述的流程或功能。计算机可以是通用计算机、专用计算机、计算机网络、或者其他可编程设备。计算机指令可以存储在计算机存储介质中,或者通过计算机存储介质进行传输。计算机指令可以从一个网站站点、计算机、服务器或数据中心通过有线(例如,同轴电缆、光纤、数字用户线(DSL))或无线(例如,红外、无线、微波等)方式向另一个网站站点、计算机、服务器或数据中心进行传输。计算机存储介质可以是计算机能够存取的任何可用介质或者是包含一个或多个可用介质集成的服务器、数据中心等数据存储设备。可用介质可以是磁性介质(例如,软盘、硬盘、磁带)、光介质(例如,DVD)、或者半导体介质(例如,固态硬盘(Solid State Disk,SSD))等。
以上所述,仅为本申请的具体实施方式,但本申请的保护范围并不局限于此,任何熟悉本技术领域的技术人员在本发明揭露的技术范围内,可轻易想到变化或替换,都应涵盖在本申请的保护范围之内。因此,本申请的保护范围应以所述权利要求的保护范围为准。

Claims (11)

1.一种检测方法,其特征在于,所述方法包括:
在对代码文件进行编译的过程中,将所述代码文件中的目标结构体存储在结构体存储空间中;其中,所述目标结构体为具有扩展属性的结构体,所述目标结构体包括函数指针,所述函数指针指向所述代码文件中的具有所述扩展属性的目标函数,所述目标结构体对应的结构体指针指向所述函数指针;
针对所述目标函数插入验证函数;所述验证函数包括第一变量和第二变量,所述第一变量为所述函数指针的地址,所述第二变量为所述函数指针的值;
在运行编译后的代码文件的过程中,从所述结构体存储空间中获取所述结构体指针所指示的函数指针地址和所述函数指针所指示的目标值,并获取所述验证函数对应的所述第一变量的第一变量值和所述第二变量的第二变量值;
基于所述函数指针地址、所述目标值、所述第一变量值和所述第二变量值,确定所述代码文件的检测结果。
2.根据权利要求1所述的方法,其特征在于,所述基于所述函数指针地址、所述目标值、所述第一变量值和所述第二变量值,确定所述代码文件的检测结果,包括:
将所述函数指针地址和所述目标值进行异或运算,得到第一运算结果;
将所述第一变量值和所述第二变量值进行异或运算,得到第二运算结果;
基于所述第一运算结果和所述第二运算结果确定检测结果。
3.根据权利要求2所述的方法,其特征在于,所述基于所述第一运算结果和所述第二运算结果确定检测结果,包括:
将所述第一运算结果和影子内存参数进行取模运算,得到所述第一运算结果对应的在影子内存中的第一位置;所述影子内存为用于存储结构体实例和其内指针的对应关系的内存空间;
将所述第二运算结果和所述影子内存参数进行取模运算,得到所述第二运算结果对应的在所述影子内存中的第二位置;
根据所述第一位置和所述第二位置的比较结果确定检测结果。
4.根据权利要求3所述的方法,其特征在于,所述根据所述第一位置和所述第二位置的比较结果确定检测结果,包括:
将所述第一位置和所述第二位置进行比较,得到比较结果;
若所述比较结果指示所述第一位置和所述第二位置相匹配,则得到用于指示所述函数指针的值未被篡改的检测结果;
若所述比较结果指示所述第一位置和所述第二位置不相匹配,则得到用于指示所述函数指针的值被篡改的检测结果。
5.根据权利要求1至4任一项所述的方法,其特征在于,所述方法还包括:
将去除结构体后的代码文件进行编程语言转换,得到转换后的代码文件;
从所述转换后的代码文件中确定所述目标函数对应的函数代码,并从所述函数代码中确定所述结构体指针对应的赋值语句;
基于所述赋值语句确定所述验证函数。
6.根据权利要求5所述的方法,其特征在于,所述从所述函数代码中确定所述结构体指针对应的赋值语句,包括:
对所述函数代码中的每一条代码语句进行检测,从所述函数代码中确定间接调用语句;
从所述函数代码中获取所述间接调用语句的定义语句;
当所述定义语句中与所述结构体指针具有对应关系时,将所述定义语句确定为所述结构体指针对应的赋值语句。
7.根据权利要求6所述的方法,其特征在于,所述对所述函数代码中的每一条代码语句进行检测,从函数代码中确定间接调用语句,包括:
针对所述函数代码中的任一条代码语句,检测所述任一条代码语句是否为调用类型的代码语句;
若为所述调用类型的代码语句,且所述任一条代码语句对应的抽象语法树AST的类型为静态单赋值形式SSA变量,并且针对所述静态单赋值形式SSA变量的定义变量为空,则确定所述任一条代码语句为间接调用语句。
8.一种检测装置,其特征在于,包括:
存储模块,用于在对代码文件进行编译的过程中,将所述代码文件中的目标结构体存储在结构体存储空间中;其中,所述目标结构体为具有扩展属性的结构体,所述目标结构体包括函数指针,所述函数指针指向所述代码文件中的具有所述扩展属性的目标函数,所述目标结构体对应的结构体指针指向所述函数指针;
处理模块,用于针对所述目标函数插入验证函数;所述验证函数包括第一变量和第二变量,所述第一变量为所述函数指针的地址,所述第二变量为所述函数指针的值;
获取模块,用于在运行编译后的代码文件的过程中,从所述结构体存储空间中获取所述结构体指针所指示的函数指针地址和所述函数指针所指示的目标值,并获取所述验证函数对应的所述第一变量的第一变量值和所述第二变量的第二变量值;
确定模块,用于基于所述函数指针地址、所述目标值、所述第一变量值和所述第二变量值,确定所述代码文件的检测结果。
9.一种计算机设备,其特征在于,所述计算机设备包括存储器和处理器,所述存储器存储有计算机程序,所述计算机程序被所述处理器执行时,使得所述处理器实现如权利要求1-7中任一项所述的检测方法。
10.一种计算机可读存储介质,其特征在于,所述计算机可读存储介质存储有计算机程序,所述计算机程序包括程序指令,所述程序指令被处理器执行时,使得具有所述处理器的计算机设备实现如权利要求1-7中任一项所述的检测方法。
11.一种计算机程序产品,其特征在于,所述计算机程序产品包括计算机程序或计算机指令,所述计算机程序或计算机指令被处理器执行时,用以实现如权利要求1-7中任一项所述的检测方法。
CN202210389924.XA 2022-04-14 2022-04-14 检测方法、装置、设备、存储介质及计算机程序产品 Pending CN116956297A (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN202210389924.XA CN116956297A (zh) 2022-04-14 2022-04-14 检测方法、装置、设备、存储介质及计算机程序产品

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN202210389924.XA CN116956297A (zh) 2022-04-14 2022-04-14 检测方法、装置、设备、存储介质及计算机程序产品

Publications (1)

Publication Number Publication Date
CN116956297A true CN116956297A (zh) 2023-10-27

Family

ID=88460580

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202210389924.XA Pending CN116956297A (zh) 2022-04-14 2022-04-14 检测方法、装置、设备、存储介质及计算机程序产品

Country Status (1)

Country Link
CN (1) CN116956297A (zh)

Similar Documents

Publication Publication Date Title
US9715593B2 (en) Software vulnerabilities detection system and methods
US7849509B2 (en) Detection of security vulnerabilities in computer programs
Altekar et al. OPUS: Online Patches and Updates for Security.
US8356351B2 (en) Method and device for verification of code module in virtual machine
CN104537309A (zh) 应用程序漏洞检测方法、装置及服务器
CN110225029B (zh) 注入攻击检测方法、装置、服务器及存储介质
Vivar et al. An analysis of smart contracts security threats alongside existing solutions
Xu et al. A novel machine learning-based analysis model for smart contract vulnerability
KR20170063662A (ko) 소프트웨어 시스템의 자동화된 검증 기법
CN104537308A (zh) 提供应用安全审计功能的系统及方法
Zhang et al. Ripple: Reflection analysis for android apps in incomplete information environments
CN109271789B (zh) 恶意进程检测方法、装置、电子设备及存储介质
CN114996126B (zh) 一种针对eosio智能合约的漏洞检测方法及系统
Pérez et al. Lapse+ static analysis security software: Vulnerabilities detection in java ee applications
US11048621B2 (en) Ensuring source code integrity in a computing environment
Bodell III et al. Proxy hunting: Understanding and characterizing proxy-based upgradeable smart contracts in blockchains
CN103810096A (zh) 混合程序分析方法和系统
CN116910712A (zh) 代码保护方法、系统、电子设备及存储介质
Jones et al. A service-oriented approach to mobile code security
CN113449330B (zh) 对Javascript加密文件进行传输的方法
CN116956297A (zh) 检测方法、装置、设备、存储介质及计算机程序产品
CN109344577A (zh) 一种art下使用自修改技术进行软件保护的方法
CN115168861A (zh) 数据安全验证方法、装置、设备及存储介质
CN111475152B (zh) 一种代码处理方法及装置
Ashouri Kaizen: a scalable concolic fuzzing tool for scala

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