智能合约漏洞修复方法、设备以及介质转让专利

申请号 : CN202211244063.2

文献号 : CN115310100B

文献日 :

基本信息:

PDF:

法律信息:

相似专利:

发明人 : 冯禹铭张伟哲邱志豪张宇刘鹏辉

申请人 : 鹏城实验室

摘要 :

本申请公开了一种智能合约漏洞修复方法、设备以及介质,涉及智能合约领域。方法包括:获取以太坊虚拟机运行智能合约时的运行数据,运行数据包括区块信息、交易信息和指令信息;根据运行数据,检测出智能合约的漏洞,并确定漏洞对应的指令执行序列;根据运行数据,从智能合约的控制流图中确定出指令执行序列所在的目标基本块,并获得漏洞的上下文逻辑关联信息;根据漏洞的类型、字节码级关联信息和预设补丁模板,生成目标补丁;根据目标补丁和执行顺序信息,对智能合约的原程序代码进行修复,得到漏洞修复后的智能合约。本申请在修复后不改变智能合约的运行逻辑,进而实现智能合约的自动修复。

权利要求 :

1.一种智能合约漏洞修复方法,其特征在于,所述方法包括:

获取以太坊虚拟机运行智能合约时的运行数据,所述运行数据包括区块信息、交易信息和指令信息;

根据所述运行数据,检测出所述智能合约的漏洞,并确定所述漏洞对应的指令执行序列;

根据所述运行数据,从所述智能合约的控制流图中确定出所述指令执行序列所在的目标基本块,并获得所述漏洞的上下文逻辑关联信息,所述上下文逻辑关联信息包括所述目标基本块在所述控制流图中的执行顺序信息以及所述指令执行序列的字节码级关联信息;

根据所述漏洞的类型、所述字节码级关联信息和预设补丁模板,生成目标补丁;

根据所述目标补丁和所述执行顺序信息,对所述智能合约的原程序代码进行修复,得到漏洞修复后的智能合约;

所述根据所述漏洞的类型、所述字节码级关联信息和预设补丁模板,生成目标补丁,包括:若所述漏洞的类型为重入漏洞,则根据所述字节码级关联信息,确定所述预设补丁模板中第一修复操作的类型为第一新增操作、所述第一新增操作对应的位置为CALL指令的上一指令以及所述第一新增操作对应指令为状态变量更新指令序列;

根据所述字节码级关联信息,确定所述预设补丁模板中第二修复操作的类型为删除操作、所述删除操作对应的位置为CALL指令的下一指令以及所述删除操作对应指令为所述状态变量更新指令序列,以生成所述目标补丁。

2.根据权利要求1所述的智能合约漏洞修复方法,其特征在于,所述根据所述目标补丁和所述执行顺序信息,对所述智能合约的原程序代码进行修复,得到漏洞修复后的智能合约,包括:从所述原程序代码中确定出所述目标基本块对应的目标代码段;

在所述原程序代码的末尾处创建所述目标代码段的复制副本;

根据所述目标补丁对所述复制副本进行更改,得到修复后代码段;

利用第一预设跳转指令替换所述目标代码段中的入口指令,所述第一预设跳转指令指向所述修复后代码段的入口指令;

利用预设无效指令替换所述目标代码段中除所述入口指令之外的剩余指令;

根据所述执行顺序信息,将所述修复后代码段与目标基本块的后续基本块相关联,得到漏洞修复后的智能合约。

3.根据权利要求2所述的智能合约漏洞修复方法,其特征在于,所述根据所述执行顺序信息,将所述修复后代码段与目标基本块的后续基本块相关联,得到漏洞修复后的智能合约,包括:根据所述执行顺序信息,判断所述目标基本块是否存在待跳转的所述后续基本块;

若存在,则在所述修复后代码段后新增第二预设跳转指令,得到漏洞修复后的智能合约;其中,所述第二预设跳转代码指向所述后续基本块中的入口指令。

4.根据权利要求3所述的智能合约漏洞修复方法,其特征在于,所述判断所述目标基本块是否存在待跳转的所述后续基本块之后,所述方法还包括:若不存在,则根据所述执行顺序信息,判断所述目标基本块的下一基本块的入口指令是否为预设跳转地址指令;

若所述目标基本块的下一基本块的入口指令为所述预设跳转地址指令,则在所述修复后代码段后新增第二预设跳转指令,得到漏洞修复后的智能合约;其中,所述第二预设跳转代码指向所述预设跳转地址指令;

若所述目标基本块的下一基本块的入口指令不为所述预设跳转地址指令,则在所述修复后代码段之后新增所述下一基本块的复制代码段,得到漏洞修复后的智能合约。

5.根据权利要求1所述的智能合约漏洞修复方法,其特征在于,所述获得所述漏洞的上下文逻辑关联信息,包括:确定所述目标基本块在所述控制流图中的执行顺序信息;

根据所述运行数据,对数据的存储过程进行模拟,获得任一所述数据关联的两个指令;

根据所有所述数据关联的两个指令,确定指令间的依赖关系,以得到所述指令执行序列的字节码级关联信息。

6.一种智能合约漏洞修复设备,其特征在于,包括:处理器,存储器以及存储在所述存储器中的智能合约漏洞修复程序,所述智能合约漏洞修复程序被所述处理器运行时实现如权利要求1‑5中任一项所述智能合约漏洞修复方法的步骤。

7.一种计算机可读存储介质,其特征在于,所述计算机可读存储介质上存储有智能合约漏洞修复程序,所述数据缓存程序被处理器执行时实现如权利要求1至5任一项所述的智能合约漏洞修复方法。

说明书 :

智能合约漏洞修复方法、设备以及介质

技术领域

[0001] 本申请涉及智能合约领域,尤其涉及一种智能合约漏洞修复方法、设备以及介质。

背景技术

[0002] 相关技术中,智能合约的出现拓宽了区块链的应用场景,使得区块链使用场景不再局限于货币支付领域,更是拓展到了金融、医疗保健、物联网等领域。目前智能合约安全问题的研究主要集中于智能合约的漏洞检测,但是仅仅进行检测漏洞的工作还远远不够,更重要的对智能合约漏洞进行修补。
[0003] 但是,人工进行修补的方式耗时耗力,效率较低。

发明内容

[0004] 本申请的主要目的在于提供一种智能合约漏洞修复方法、设备以及介质,旨在解决现有人工对智能合约进行漏洞修复效率低的技术问题。
[0005] 为实现上述目的,本申请提供一种智能合约漏洞修复方法,所述方法包括:
[0006] 获取以太坊虚拟机运行智能合约时的运行数据,所述运行数据包括区块信息、交易信息和指令信息;
[0007] 根据所述运行数据,检测出所述智能合约的漏洞,并确定所述漏洞对应的指令执行序列;
[0008] 根据所述运行数据,从所述智能合约的控制流图中确定出所述指令执行序列所在的目标基本块,并获得所述漏洞的上下文逻辑关联信息,所述上下文逻辑关联信息包括所述目标基本块在所述控制流图中的执行顺序信息以及所述指令执行序列的字节码级关联信息;
[0009] 根据所述漏洞的类型、所述字节码级关联信息和预设补丁模板,生成目标补丁;
[0010] 根据所述目标补丁和所述执行顺序信息,对所述智能合约的原程序代码进行修复,得到漏洞修复后的智能合约。
[0011] 在本申请可能的一实施例中,所述根据所述目标补丁和所述执行顺序信息,对所述智能合约的原程序代码进行修复,得到漏洞修复后的智能合约,包括:
[0012] 从所述原程序代码中确定出所述目标基本块对应的目标代码段;
[0013] 在所述原程序代码的末尾处创建所述目标代码段的复制副本;
[0014] 根据所述目标补丁对所述复制副本进行更改,得到修复后代码段;
[0015] 利用第一预设跳转指令替换所述目标代码段中的入口指令,所述第一预设跳转指令指向所述修复后代码段的入口指令;
[0016] 利用预设无效指令替换所述目标代码段中除所述入口指令之外的剩余指令;
[0017] 根据所述执行顺序信息,将所述修复后代码段与目标基本块的后续基本块相关联,得到漏洞修复后的智能合约。
[0018] 在本申请可能的一实施例中,所述根据所述执行顺序信息,将所述修复后代码段与目标基本块的后续基本块相关联,得到漏洞修复后的智能合约,包括:
[0019] 根据所述执行顺序信息,判断所述目标基本块是否存在待跳转的所述后续基本块;
[0020] 若存在,则在所述修复后代码段后新增第二预设跳转指令,得到漏洞修复后的智能合约;其中,所述第二预设跳转代码指向所述后续基本块中的入口指令。
[0021] 在本申请可能的一实施例中,所述判断所述目标基本块是否存在待跳转的所述后续基本块之后,所述方法还包括:
[0022] 若不存在,则根据所述执行顺序信息,判断所述目标基本块的下一基本块的入口指令是否为预设跳转地址指令;
[0023] 若所述目标基本块的下一基本块的入口指令为所述预设跳转地址指令,则在所述修复后代码段后新增第二预设跳转指令,得到漏洞修复后的智能合约;其中,所述第二预设跳转代码指向所述预设跳转地址指令;
[0024] 若所述目标基本块的下一基本块的入口指令不为所述预设跳转地址指令,则在所述修复后代码段之后新增所述下一基本块的复制代码段,得到漏洞修复后的智能合约。
[0025] 在本申请可能的一实施例中,所述根据所述漏洞的类型、所述字节码级关联信息和预设补丁模板,生成目标补丁,包括:
[0026] 若所述漏洞的类型为重入漏洞,则根据所述字节码级关联信息,确定所述预设补丁模板中第一修复操作的类型为第一新增操作、所述第一新增操作对应的位置为CALL指令的上一指令以及所述第一新增操作对应指令为状态变量更新指令序列;
[0027] 根据所述字节码级关联信息,确定所述预设补丁模板中第二修复操作的类型为删除操作、所述删除操作对应的位置为CALL指令的下一指令以及所述删除操作对应指令为所述状态变量更新指令序列,以生成所述目标补丁。
[0028] 在本申请可能的一实施例中,所述获得所述漏洞的上下文逻辑关联信息,包括:
[0029] 确定所述目标基本块在所述控制流图中的执行顺序信息;
[0030] 根据所述运行数据,对数据的存储过程进行模拟,获得任一所述数据关联的两个指令;
[0031] 根据所有所述数据关联的两个指令,确定指令间的依赖关系,以得到所述指令执行序列的字节码级关联信息。
[0032] 在本申请可能的一实施例中,所述根据所述漏洞的类型、所述字节码级关联信息和预设补丁模板,生成目标补丁,包括:
[0033] 若所述漏洞的类型为整数溢出漏洞,则根据所述字节码级关联信息,确定所述预设补丁模板中修复操作为第二新增操作,所述第二新增操作对应的位置为运算指令的上一指令以及所述第二新增操作对应指令为预设判断指令和修复序列,以生成所述目标补丁。
[0034] 在本申请可能的一实施例中,所述获得所述漏洞的上下文逻辑关联信息,包括:
[0035] 若监测到所述运行数据中包括PUSH和AND指令,则确定整数类型为无符号整数;
[0036] 若监测到所述运行数据中包括SIGNEXTEND指令,则确定所述整数类型为有符号整数。
[0037] 第二方面,本申请还提供了一种智能合约漏洞修复设备,包括:处理器,存储器以及存储在所述存储器中的智能合约漏洞修复程序,所述智能合约漏洞修复程序被所述处理器运行时实现如上所述智能合约漏洞修复方法的步骤。
[0038] 第三方面,本申请还提供了一种计算机可读存储介质,所述计算机可读存储介质上存储有智能合约漏洞修复程序,所述数据缓存程序被处理器执行时实现如上所述的智能合约漏洞修复方法。
[0039] 本申请实施例提出的一种智能合约漏洞修复方法,所述方法包括:获取以太坊虚拟机运行智能合约时的运行数据,所述运行数据包括区块信息、交易信息和指令信息;根据所述运行数据,检测出所述智能合约的漏洞,并确定所述漏洞对应的指令执行序列;根据所述运行数据,从所述智能合约的控制流图中确定出所述指令执行序列所在的目标基本块,并获得所述漏洞的上下文逻辑关联信息,所述上下文逻辑关联信息包括所述目标基本块在所述控制流图中的执行顺序信息以及所述指令执行序列的字节码级关联信息;根据所述漏洞的类型、所述字节码级关联信息和预设补丁模板,生成目标补丁;根据所述目标补丁和所述执行顺序信息,对所述智能合约的原程序代码进行修复,得到漏洞修复后的智能合约。
[0040] 由此,本申请基于以太坊虚拟机运行智能合约时的运行数据,可以在检测出漏洞时,获得到触发漏洞的类型以及指令执行序列,并从运行数据中获取更多与漏洞代码段有关的上下文逻辑关联信息,即所述目标基本块在所述控制流图中的执行顺序信息以及所述指令执行序列的字节码级关联信息,从而可以依赖于预设补丁模板自动定制修复漏洞的补丁,并依赖于执行顺序信息以及所述指令执行序列的字节码级关联信息进行代码的修复,从而在修复后不改变智能合约的运行逻辑,进而实现智能合约的自动修复。

附图说明

[0041] 图1为本申请智能合约漏洞修复设备一实施例的结构示意图;
[0042] 图2为本申请的智能合约漏洞修复方法第一实施例的流程示意图;
[0043] 图3为本申请的智能合约漏洞修复方法第二实施例的流程示意图;
[0044] 图4为本申请的预设补丁模板的示意图;
[0045] 图5为本申请智能合约漏洞修复方法的蹦床构思的示意图。
[0046] 本申请目的的实现、功能特点及优点将结合实施例,参照附图做进一步说明。

具体实施方式

[0047] 应当理解,此处所描述的具体实施例仅仅用以解释本申请,并不用于限定本申请。
[0048] 相关技术中,智能合约的出现拓宽了区块链的应用场景,使得区块链使用场景不再局限于货币支付领域,更是拓展到了金融、医疗保健、物联网等领域。由于智能合约具有一经部署便无法修改的特点,其面临的安全问题也比传统应用软件更为棘手。目前智能合约安全问题的研究主要集中于智能合约的漏洞检测,但是仅仅进行检测漏洞的工作还远远不够,更重要的对智能合约漏洞进行修补。目前自动化的漏洞修复仍主要采用人工进行修补的方式耗时耗力,且容易出错。
[0049] 本申请提供一种解决方案,通过基于以太坊虚拟机运行智能合约时的运行数据,可以在检测出漏洞时,获得到触发漏洞的类型以及指令执行序列,并从运行数据中获取更多与漏洞代码段有关的上下文逻辑关联信息,从而可以依赖于预设补丁模板自动定制修复漏洞的补丁,并依赖于执行顺序信息以及所述指令执行序列的字节码级关联信息进行代码的修复,从而在修复后不改变智能合约的运行逻辑,进而实现智能合约的自动修复。
[0050] 下面结合一些具体实施例进一步阐述本申请的发明构思。
[0051] 参照图1,图1为本申请实施例方案涉及的硬件运行环境的智能合约漏洞修复设备的结构示意图。
[0052] 如图1所示,该智能合约漏洞修复设备可以包括:处理器1001,例如中央处理器(Central Processing Unit,CPU),通信总线1002、用户接口1003,网络接口1004,存储器1005。其中,通信总线1002用于实现这些组件之间的连接通信。用户接口1003可以包括显示屏(Display)、输入单元比如键盘(Keyboard),可选用户接口1003还可以包括标准的有线接口、无线接口。网络接口1004可选的可以包括标准的有线接口、无线接口(如无线保真(WIreless‑FIdelity,WI‑FI)接口)。存储器1005可以是高速的随机存取存储器(Random Access Memory,RAM)存储器,也可以是稳定的非易失性存储器(Non‑Volatile Memory,NVM),例如磁盘存储器。存储器1005可选的还可以是独立于前述处理器1001的存储装置。
[0053] 本领域技术人员可以理解,图1中示出的结构并不构成对智能合约漏洞修复设备的限定,可以包括比图示更多或更少的部件,或者组合某些部件,或者不同的部件布置。
[0054] 如图1所示,作为一种存储介质的存储器1005中可以包括操作系统、数据存储模块、网络通信模块、用户接口模块以及智能合约漏洞修复程序。
[0055] 在图1所示的数据缓存设备中,网络接口1004主要用于与网络服务器进行数据通信;用户接口1003主要用于与用户进行数据交互;本申请智能合约漏洞修复设备中的处理器1001、存储器1005可以设置在智能合约漏洞修复设备中,数据缓存设备通过处理器1001调用存储器1005中存储的智能合约漏洞修复程序,并执行本申请实施例提供的智能合约漏洞修复方法。
[0056] 基于上述硬件结构但不限于上述结构,提出本申请一种智能合约漏洞修复方法。参阅图2,图2为本申请一种智能合约漏洞修复方法第一实施例。
[0057] 本实施例中,方法包括:
[0058] 步骤S100、获取以太坊虚拟机运行智能合约时的运行数据,所述运行数据包括区块信息、交易信息和指令信息;
[0059] 具体而言,为了对漏洞进行有效修补,首先需要获取漏洞的精确位置、漏洞的执行路径以及漏洞相关的信息,在本实施例中,这些信息可通过基于运行信息获得。
[0060] 其中,具体的运行信息可通过在以太坊虚拟机中添加信息采集器完成。信息采集器来记录以太坊虚拟机运行时每个交易和每个以太坊虚拟机指令执行产生的结果来获得所有的运行信息。在本实施例中,基于发明人对go‑ethereum源代码的研究,根据信息的种类,将运行信息分为区块信息、交易信息以及指令信息三部分。本实施例在以下将具体说明:
[0061] 第一、区块信息的采集。可以理解的,在以太坊中,区块由区块头和区块主体构成,区块头包含区块编号、区块开采难度、开采区块的用户、开采奖励、开采区块的时间戳等。而区块主体则存储交易信息。值得一提的是,有些区块可能没有存储交易,此时区块主体为空。在一具体实施方式中,区块信息可通过在以太坊虚拟机中的core/state_processor.go中采集区块头中包含的信息。
[0062] 第二、交易信息的采集。以太坊的交易根据发起者的地址(账户)类型可分为外部交易和内部交易。更通俗的理解,外部交易是由外部账户发起的智能合约调用请求,这类交易会被区块链记录下来,而内部交易是智能合约间的相互调用,这类交易是在以太坊虚拟机执行期间进行的,执行过程并不会被记录,但是其执行结果的一部分,如转账记录等会被记录在区块链上。外部交易和内部交易执行逻辑相似,因此可以共用相同的信息采集算法实现。其中,外部交易信息的采集可通过部署在以太坊虚拟机中的applyTransaction函数中进行,而内部交易信息的采集可通过对可能产生内部交易的指令代码的解释程序中添加采集函数完成采集。
[0063] 第三,指令信息的采集。可以理解的,以太坊虚拟机可支持140多条指令,本实施例可通过在所有以太坊虚拟机指令的解释程序中添加采集函数完成指令的执行信息收集,以记录所有已执行的以太坊虚拟机指令的运行信息。值得一提的是,由于后续的合约修补需要较为详细的执行路径等信息,以准确进行字节码级的分析推测,为了避免遗漏任何可能有用的信息,这里可以记录每条指令的名称、参数、指令执行产生的结果以及指令执行的顺序。其中,指令执行的顺序可通过程序计数器PC得到。
[0064] 步骤S200、根据所述运行数据,检测出所述智能合约的漏洞,并确定所述漏洞对应的指令执行序列。
[0065] 可以理解的,智能合约的漏洞检测为现有技术,因此,此处不在赘述如何实施智能合约漏洞的检测过程。
[0066] 而在检出漏洞后,即可根据运行信息中的数据流(如区块信息和交易信息)和指令信息,特别是指令信息中的每条指令的名称、参数、指令执行产生的结果以及指令执行的顺序,从而可以确定出执行恶意交易的指令执行序列。
[0067] 可以理解的,漏洞对应的指令执行序列包括但不限于至少一条指令。
[0068] 步骤S300、根据所述运行数据,从所述智能合约的控制流图中确定出所述指令执行序列所在的目标基本块,并获得所述漏洞的上下文逻辑关联信息,所述上下文逻辑关联信息包括所述目标基本块在所述控制流图中的执行顺序信息以及所述指令执行序列的字节码级关联信息。
[0069] 具体而言,控制流图(CFG)中的节点就是基本块,控制流图通过在两个节点间添加有向边的方式来表示它们的执行顺序。而每个基本块都对应一系列的指令构成,有一个入口和一个出口,入口就是第一个指令,出口就是最后一个指令。从而可以通过采集到的执行的指令信息来构造CFG的每个节点,当遇到指令 STOP、RETURN、REVERT、INVALID或SUICIDE3时,说明这是基本块的边界了,则停止当前节点的构造,并以原程序代码中下一条指令作为新节点的开始。
[0070] 此外,当遇到指令JUMP和JUMPI时,也标志着基本块的边界,停止当前节点的构造,但是这两个指令是跳转指令,不能按照顺序取原程序代码中下一条指令作为新节点的开始。对于JUMP指令,该指令是无条件跳转指令,因此以目标地址(即跳转地址)处的指令作为新节点的开始,对于JUMPI指令,该指令是条件跳转指令,因此这里需要构建两个执行序列,一个分支按照原来的执行顺序(未满足跳转情况)构建,一个分支从目标地址开始构建。
[0071] 在得到运行信息(如指令信息中的名称、参数、指令执行产生的结果以及指令执行的顺序等),通过和控制流图进行比对,即可确定出漏洞对应的指令执行序列所在的目标基本块,也即是需要进行代码修改的基本块。
[0072] 可以理解的,根据控制流图可明显看出目标基本块和其他基本块之间存在着相应的指向关系,即执行完该目标基本块对应的指令后,继续向下指向哪一个基本块对应的指令。因此,为了避免在字节码级修复漏洞后,智能合约的运行逻辑受到破坏,因此需要提前根据所述运行数据,获得所述目标基本块在所述控制流图中的执行顺序信息。
[0073] 此外,由于字节码级的漏洞修复一般为通过新增指令以修复漏洞,或者删除相应的错误指令,此时目标基本块对应的指令执行序列中的各条指令对数据的处理也会发生变化,如修改字节码后需要对数据引用地址的调整。因此,为了使得在字节码级修复漏洞后,该目标基本块对应的多条指令可以正常运行,还需要得到指令执行序列的字节码级关联信息。
[0074] 其中,字节码级关联信息可以是指令和数据之间的依赖关系,如指令A对数据B处理后,后续为指令C对数据B进行处理,此时即可认为指令B的数据和指令A之间存在依赖关系。或者,字节码级关联信息还可以包括数据的写入地址。
[0075] 步骤S400、根据所述漏洞的类型、所述字节码级关联信息和预设补丁模板,生成目标补丁。
[0076] 具体而言,预设补丁模板包括operation操作类型、pos操作执行的位置和content修复需要执行的指令。操作类型可以是“新增add”,即新增指令,或者“删除DEL”,即删除指令。操作执行的位置为修复操作相对于漏洞位置,如“之前before”或者“之后after”。可以理解的,由于本实施例为智能合约的自动修复,因此,content修复需要执行的指令包括多段根据漏洞的类型提前预置的指令。如预设补丁模板可以包括一指令库,指令库内预存有多个专注于修改某一特定漏洞的预置content指令。且还预存有漏洞类型和预置content指令之间的映射关系。从而在检测出漏洞以后,即可根据漏洞类型,直接调用相应的预置content指令。
[0077] 然后基于所述字节码级关联信息,确定预置content指令对应的pos操作执行的位置,从而即可得到目标补丁。
[0078] 步骤S500、根据所述目标补丁和所述执行顺序信息,对所述智能合约的原程序代码进行修复,得到漏洞修复后的智能合约。
[0079] 具体而言,在得到目标补丁后,为了避免修复后破坏智能合约的运行逻辑,还需要依赖于执行顺序信息,结合目标补丁一同对所述智能合约的原程序代码进行修复,得到漏洞修复后的智能合约。
[0080] 可见,本实施例中,基于以太坊虚拟机运行智能合约时的运行数据,可以在检测出漏洞时,获得到触发漏洞的类型以及指令执行序列,并从运行数据中获取更多与漏洞代码段有关的上下文逻辑关联信息,即所述目标基本块在所述控制流图中的执行顺序信息以及所述指令执行序列的字节码级关联信息,从而可以依赖于预设补丁模板自动定制修复漏洞的补丁,并依赖于执行顺序信息以及所述指令执行序列的字节码级关联信息进行代码的修复,从而在修复后不改变智能合约的运行逻辑,进而实现智能合约的自动修复。
[0081] 基于上述第一实施例,提出本申请智能合约漏洞修复方法第二实施例。参阅图3,图3为智能合约漏洞修复方法第二实施例的流程示意图。
[0082] 具体而言,本实施例中,步骤S500具体包括:
[0083] 步骤S501、从所述原程序代码中确定出所述目标基本块对应的目标代码段。
[0084] 步骤S502、在所述原程序代码的末尾处创建所述目标代码段的复制副本。
[0085] 步骤S503、根据所述目标补丁对所述复制副本进行更改,得到修复后代码段。
[0086] 步骤S504、利用第一预设跳转指令替换所述目标代码段中的入口指令,所述第一预设跳转指令指向所述修复后代码段的入口指令。
[0087] 步骤S505、利用预设无效指令替换所述目标代码段中除所述入口指令之外的剩余指令。
[0088] 步骤S506、根据所述执行顺序信息,将所述修复后代码段与目标基本块的后续基本块相关联,得到漏洞修复后的智能合约。
[0089] 具体而言,为了避免修复智能合约字节码时对原有内存结构的调整需要进行准确的控制流图恢复和数据流分析工作,本实施例基于蹦床构思,让修复在基本块级别上工作。
[0090] 当修补时需要更改某一基本块时,在所述原程序代码的末尾创建该目标代码段的复制副本,然后在复制副本上执行字节码的更改,从而得到修复后代码段。在创建得到复制副本后,为了在智能合约运行过程中,可以正常运行该修复后代码段,此时,可以将利用指向所述修复后代码段的入口指令的第一预设跳转指令替换所述目标代码段中的入口指令。且为了避免原来的目标代码段影响修复后代码段的运行,则原目标代码段使用INVALID替换。其中,INVALID是以太坊提供的一个无效指令。
[0091] 具体的,参阅图5,如需要在0xAB开始的字节码段中插入新的字节码时,将这一段字节码复制原程序代码的末尾0xFFB处,将0xAB处原有的指令更改为跳转到0xFFB处的指令,并用无效的指令填充剩下的部分。在0xFFB中进行字节码的修复。
[0092] 同样的,在执行完修复后代码段后,为了使得智能合约的运行回归到原有执行顺序上,还需要将所述修复后代码段与目标基本块的后续基本块相关联,得到漏洞修复后的智能合约。
[0093] 本实施例中,采用蹦床的修复思路,即复制到末尾处创建复制副本避免了修改字节码后需要对数据引用地址的调整,但它引入了额外的跳转指令,有可能破坏原石合约中基本块的执行顺序,因此,作为本实施例的一种选择,步骤S506包括:
[0094] 步骤S5061、根据所述执行顺序信息,判断所述目标基本块是否存在待跳转的所述后续基本块.
[0095] 步骤S5062、若存在,则在所述修复后代码段后新增第二预设跳转指令,得到漏洞修复后的智能合约;其中,所述第二预设跳转代码指向所述后续基本块中的入口指令。
[0096] 步骤S5063、若不存在,则根据所述执行顺序信息,判断所述目标基本块的下一基本块的入口指令是否为预设跳转地址指令;
[0097] 步骤S5064、若所述目标基本块的下一基本块的入口指令为所述预设跳转地址指令,则在所述修复后代码段后新增第二预设跳转指令,得到漏洞修复后的智能合约;其中,所述第二预设跳转代码指向所述预设跳转地址指令;
[0098] 步骤S5065、若所述目标基本块的下一基本块的入口指令不为所述预设跳转地址指令,则在所述修复后代码段之后新增所述下一基本块的复制代码段,得到漏洞修复后的智能合约。
[0099] 具体而言,对于智能合约字节码,基本块的执行顺序存在三种情况,[0100] (1)条件跳转。以太坊虚拟机中负责条件跳转的指令是JUMPI,它会从栈中读取2个值,分别代表跳转的条件和程序计数器pc(programmer counter)值,pc值即为需要跳转到的指令位置,即预设跳转地址指令JUMPDEST。若满足跳转条件,则跳转到后续基本块, 在执行完后续基本块中所有指令后会跳转回来继续执行下一个基本块。若不满足条件,则直接执行下一个基本块。
[0101] (2)以显示控制流指令终止,如JUMP、RETURN、REVERT。其中RETURN和REVERT属于结束指令,所以这里只对JUMP指令进行讨论。JUMP指令触发以太坊虚拟机中的非条件跳转,每次执行到JUMP指令时,都会从栈中读出1个值,pc值即为需要跳转到的指令位置,即预设跳转地址指令JUMPDEST,表示要跳转的后续基本块的入口。JUMP指令与JUMPI指令类似,执行完跳转块后,也会继续向下执行。
[0102] (3)fall through。以太坊虚拟机的某些基本块没有跳转指令也没有结束指令,对于这些指令,执行完当前基本块最后一个指令后会继续执行下一个基本块的指令。条件跳转中若不满跳转条件也会存在fall through情况。
[0103] 因此,为了确保修复后智能合约的正确执行,仍然需要通过控制流图获取被修补基本块和其后续修补块的执行顺序来修复基本块间的边界,保证它们的执行逻辑不会改变。因此基于上述内容,判断所述目标基本块是否存在待跳转的所述后续基本块,即判断是否存在相应的JUMPI指令和JUMP指令。若存在,则在所述修复后代码段后新增第二预设跳转指令;其中,所述第二预设跳转代码指向所述后续基本块中的入口指令。即后续基本块的预设跳转地址指令JUMPDEST。
[0104] 如,参阅图5,如需要在0xAB开始的字节码段中插入新的字节码时,将这一段字节码复制原程序代码的末尾0xFFB处,将0xAB处原有的指令更改为跳转到0xFFB处的指令,并用无效指令填充剩下的部分。并在最后添加到0xCD跳转的指令,以确保在地址0xCD处的原始合约代码可以继续执行。
[0105] 但是并非所有基本块都有明确的跳转目标,当目标基本块存在着fall through情况。如果通过fall through到达的基本块以JUMPDEST指令为入口,那么只需要在修复后代码段后的末尾也添加一个第二预设跳转指令跳转到原基本块结束的位置即可。
[0106] 如果通过fall through到达的基本块不是以JUMPDEST指令为入口,则以太坊虚拟机会禁止任何显示跳转到该地址的操作。此时,本实施例会将fall through到达的基本块的代码段也复制到修复后代码段后,以确保基本块的执行顺序。
[0107] 可见,本实施例中,通过上述跳转指令的应用,避免了破坏原智能合约中基本块的执行顺序,保证基本块的执行逻辑不会发生改变。
[0108] 基于上述实施例,提出本申请智能合约漏洞修复方法第三实施例。
[0109] 本实施例中,方法包括:
[0110] 步骤S301、获取以太坊虚拟机运行智能合约时的运行数据,所述运行数据包括区块信息、交易信息和指令信息;
[0111] 步骤S302、根据所述运行数据,检测出所述智能合约的漏洞,并确定所述漏洞对应的指令执行序列.
[0112] 具体的,对于重入漏洞。重入漏洞其本质是由于函数执行过程中交易信息中的余额的状态变量更新落后于指令信息中外部调用进行转账的操作,而智能合约在接收token时会触发fallback函数的执行,fallback函数是以太坊提供的一种特殊机制,这种机制会导致函数执行转账操作后中再次进入函数本身,重复进行转账操作。
[0113] 本实施例中,重入漏洞的检测周期从外部交易执行时开始。外部交易的指令执行时,会触发重入漏洞检测算法的初始化部分,如设置调用根节点、开辟调用树所需空间等。重入漏洞检测算法在交易执行过程中进行调用树的更新,在外部交易结束时进行漏洞的检测。在每次调用交易执行函数前,前述部署的信息采集器会将此次交易的信息发送给重入漏洞检测算法,该动作将触发检测算法中调用树更新的操作,重入漏洞检测算法获取此次交易双方的地址并更新调用树。而在外部交易结束前,将进入漏洞检测截断,此时,重入漏洞检测算法中已经通过构建调用树的方式保存了本次交易过程中的所有调用信息,此时从外部交易的第一个地址开始通过迭代的方式后序遍历调用树,遍历过程中检查是否存在调用了当前节点已调用过节点的情况,若存在,则说明形成了环,并继续往下寻找有没有相同的环。当环数超过2时即认为发生了重入攻击。即检测出了重入漏洞。
[0114] 步骤S303、根据所述运行数据,从所述智能合约的控制流图中确定出所述指令执行序列所在的目标基本块,并获得所述漏洞的上下文逻辑关联信息,所述上下文逻辑关联信息包括所述目标基本块在所述控制流图中的执行顺序信息以及所述指令执行序列的字节码级关联信息;
[0115] 具体的,所述获得所述漏洞的上下文逻辑关联信息,包括:
[0116] 步骤S3031、确定所述目标基本块在所述控制流图中的执行顺序信息;
[0117] 步骤S3032、根据所述运行数据,对数据的存储过程进行模拟,获得任一所述数据关联的两个指令;
[0118] 步骤S3033、根据所有所述数据关联的两个指令,确定指令间的依赖关系,以得到所述指令执行序列的字节码级关联信息。
[0119] 具体的,重入漏洞需要将指令执行顺序进行调换。在指令调换过程中,为了首先确认指令之间的依赖关系,以避免指令跳转后,数据处理出现错误。但是,由于以太坊虚拟机是基于栈的虚拟机,仅从静态的合约字节码层面进行分析得到的信息可能不完整。因此,得到CFG后,还需要通过对以太坊虚拟机字节码的执行结果进行分析获取数据依赖关系。以太坊虚拟机中涉及到数据流的地方共三个,栈、内存和存储,因为存储的结果是从栈上获得,因此本实施例只需分析栈和内存间的数据流即可。
[0120] 具体的,通过模拟栈与内存的操作,即对数据的存储过程进行模拟,并在模拟过程中对数据进行标记以获取数据流的依赖关系。如对于栈,若指令a将参数1压入栈中,则标记参数1是通过指令a获得,若后续指令b对栈中的参数1进行操作时,则说明指令b的数据依赖于指令a。
[0121] 对于内存,同样的,若指令a向内存写入数据1,则将写入内存的addr位置(地址)标记为由指令a写入,若后续指令b对内存的addr位置的数据进行操作时,则说明指令b的数据依赖于指令a。
[0122] 值得一提的是,并不是所有读取或写入的内存地址都是确定的,有些地址是根据输入数据计算得来的,针对这种情况,本实施例可通过从运行数据中采集得到的漏洞字节码执行序列来获取写入地址。
[0123] 步骤S304、根据所述漏洞的类型、所述字节码级关联信息和预设补丁模板,生成目标补丁。
[0124] 具体的,本实施例中步骤S304包括:
[0125] 步骤S3041、根据所述字节码级关联信息,确定所述预设补丁模板中第一修复操作的类型为第一新增操作、所述第一新增操作对应的位置为CALL指令的上一指令以及所述第一新增操作对应指令为状态变量更新指令序列;
[0126] 步骤S3042、根据所述字节码级关联信息,确定所述预设补丁模板中第二修复操作的类型为删除操作、所述删除操作对应的位置为CALL指令的下一指令以及所述删除操作对应指令为所述状态变量更新指令序列,以生成所述目标补丁。
[0127] 具体的,参阅图4,针对重入漏洞,本实施例提供的预设补丁模板。即需要将指令执行顺序进行调换,因此需要对原基本块进行两处修改:
[0128] 一是在CALL指令执行前添加状态变量更新的操作,即预设补丁模板中第一修复操作的类型为第一新增操作、所述第一新增操作对应的位置为CALL指令的上一指令以及所述第一新增操作对应指令为状态变量更新指令序列。
[0129] 二是删除CALL指令执行后进行状态变量更新的语句。即预设补丁模板中第一修复操作的类型为第一新增操作、所述第一新增操作对应的位置为CALL指令的上一指令以及所述第一新增操作对应指令为状态变量更新指令序列。
[0130] 此时,预设补丁模板中的预置content指令为具体的状态变量更新指令序列。
[0131] 步骤S305、根据所述目标补丁和所述执行顺序信息,对所述智能合约的原程序代码进行修复,得到漏洞修复后的智能合约。
[0132] 可见,本实施例中,基于蹦床的策略,针对重入漏洞,通过对数据依赖关系进行分析,调换指令执行顺序完成了修复,对重入漏洞进行了有效修复。且修补后智能合约运行产生的额外gas消耗较小。
[0133] 基于上述实施例,提出本申请智能合约漏洞修复方法第四实施例。
[0134] 本实施例中,方法包括:
[0135] 步骤S401、获取以太坊虚拟机运行智能合约时的运行数据,所述运行数据包括区块信息、交易信息和指令信息;
[0136] 步骤S402、根据所述运行数据,检测出所述智能合约的漏洞,并确定所述漏洞对应的指令执行序列.
[0137] 具体的,对于整数漏洞。由于以太坊虚拟机被设计成256位的虚拟机,只能在256位的数值上运行,在执行计算时参数早已被转换成256位大小,数据宽度和符号信息均会在编译过程中丢失,此时不能简单的对当前参数的运算结果进行溢出检测。因此,进行整数溢出检测时,我们需要首先知道整数的类型信息,即宽度(例如,类型uint32表示一个32位大小的数)和符号(例如(类型int为有符号数,类型uint为无符号数),宽度和符号信息是正确检查算数运算所必不可少的信息。也即是在获取到整数的类型信息和符号信息才进行整数溢出的判断操作。
[0138] 而具体的获取整数的类型信息和符号信息的方式可通过如下方式:
[0139] 对于无符号整数,编译器会引入了AND操作码作为位掩码,以此屏蔽不在256宽度范围内的位。假如有一个uint32的整数,编译器在处理时首先会添加一条PUSH指令,该指令会将数据0xffffffff推入堆栈,作为AND指令的参数之一。通过运行数据中的PUSH和AND指令可以推断这是一个无符号整数,从运行数据中的位掩码0xffffffff可以推断它的宽度是32位。对于有符号整数,以太坊虚拟机都是采用补码进行表示,编译器通过引入SIGNEXTEND指令来对整数的宽度进行扩展(在保留整数的符号和值的同时增加二进制数的位数)。假如有一个int32的变量,可以通过运行数据中的SIGNEXTEND的指令判断其为有符号整数,通过该指令的第一个参数3来判断其宽度为32(y = 8 * (x + 1))。
[0140] 根据以上思路,可通过污点分析来对整数类型信息进行推断,我们选择在PUSH 0xF..F、AND及SIGNEXTEND指令执行时引入污点,并通过记录每一次栈顶数据以及内存与存储的当前结构来模拟之后的指令执行时对栈、内存和存储的影响。以无符号整数为例,当PUSH指令推入栈中的0xF..F参数作为AND指令的第二参数时,就可以知道当前整数是无符号整数。
[0141] 具体的,步骤S403、根据所述运行数据,从所述智能合约的控制流图中确定出所述指令执行序列所在的目标基本块,并获得所述漏洞的上下文逻辑关联信息,所述上下文逻辑关联信息包括所述目标基本块在所述控制流图中的执行顺序信息以及所述指令执行序列的字节码级关联信息;
[0142] 具体的,基于上述对整数漏洞的分析,所述获得所述漏洞的上下文逻辑关联信息,包括:
[0143] 步骤S4031、若监测到所述运行数据中包括PUSH和AND指令,则确定整数类型为无符号整数;
[0144] 步骤S4032、若监测到所述运行数据中包括SIGNEXTEND指令,则确定整数类型为有符号整数。
[0145] 步骤S404、根据所述漏洞的类型、所述字节码级关联信息和预设补丁模板,生成目标补丁。
[0146] 具体的,本实施例中步骤S404包括:
[0147] 步骤S405、根据所述目标补丁和所述执行顺序信息,对所述智能合约的原程序代码进行修复,得到漏洞修复后的智能合约。
[0148] 若所述漏洞的类型为整数溢出漏洞,则步骤S405具体为:
[0149] 根据所述字节码级关联信息,确定所述预设补丁模板中修复操作为第二新增操作,所述第二新增操作对应的位置为运算指令的上一指令以及所述第二新增操作对应指令为预设判断指令和修复序列,以生成所述目标补丁。
[0150] 具体的,参阅图4,针对整数溢出漏洞,需要进行的修复操作和操作执行位置是一样的,都是在整数运算前添加预设判断指令和修复序列以判断是否存在整数溢出操作。也即是,虽然整数溢出需要分成加(减)法整数上溢、乘法造成的整数上溢以及整数下溢三种情况。但是,这三种情况,都是需要首先进行是否存在整数溢出的判断步骤,从而在存在整数溢出时可以进行有效修补。只不过具体的预设修复序列,也即是预置content指令随溢出情况的变化而进行调整。
[0151] 为了方便预设补丁模板的使用,在预置content指令需要根据实际情况更改的值用抽象语句表示。在实际修补中,需要对content中的这些抽象语句进行替换,其中PUSH_Dest表示往栈中推入跳转地址Dest,修补过程中替换成JUMPI需要跳转到的地址,Boundary用于标记判断整数溢出时的边界(MAX_VALUE,0等)。
[0152] 可见,本实施例中,基于蹦床的策略,针对整数溢出漏洞,通过污点分析获取整数的类型与宽度后再进行整数溢出的判断操作和对应的修复操作,可以针对非uint256型整数造成的溢出进行有效修补,弥补了现有研究只能针对256位数据进行修补的不足,可以更全面的防止漏洞被恶意利用带来的经济损失。
[0153] 本实施例中,结合了基于运行时信息的漏洞检测,可以获取到触发漏洞的指令执行序列,能够在修补时获取更多与漏洞代码段有关的上下文信息,并通过从合约字节码中获取更加完善的上下文信息,将基于模板的补丁与语义补丁相结合,提高更全面有效的对漏洞进行修补。由此,本实施例在修补过程中不需要针对特定合约漏洞手动定制补丁,是一种可扩展的自动智能合约修复方法。
[0154] 此外,本申请实施例还提出一种计算机存储介质,存储介质上存储有智能合约漏洞修复程序,智能合约漏洞修复程序被处理器执行时实现如上文的智能合约漏洞修复方法的步骤。因此,这里将不再进行赘述。另外,对采用相同方法的有益效果描述,也不再进行赘述。对于本申请所涉及的计算机可读存储介质实施例中未披露的技术细节,请参照本申请方法实施例的描述。确定为示例,程序指令可被部署为在一个计算设备上执行,或者在位于一个地点的多个计算设备上执行,又或者,在分布在多个地点且通过通信网络互连的多个计算设备上执行。
[0155] 本领域普通技术人员可以理解实现上述实施例方法中的全部或部分流程,是可以通过计算机程序来指令相关的硬件来完成,上述的程序可存储于一计算机可读取存储介质中,该程序在执行时,可包括如上述各方法的实施例的流程。其中,上述的存储介质可为磁碟、光盘、只读存储记忆体(Read‑Only Memory,ROM)或随机存储记忆体(Random AccessMemory,RAM)等。
[0156] 另外需说明的是,以上所描述的装置实施例仅仅是示意性的,其中作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部模块来实现本实施例方案的目的。另外,本申请提供的装置实施例附图中,模块之间的连接关系表示它们之间具有通信连接,具体可以实现为一条或多条通信总线或信号线。本领域普通技术人员在不付出创造性劳动的情况下,即可以理解并实施。
[0157] 通过以上的实施方式的描述,所属领域的技术人员可以清楚地了解到本申请可借助软件加必需的通用硬件的方式来实现,当然也可以通过专用硬件包括专用集成电路、专用CPU、专用存储器、专用元器件等来实现。一般情况下,凡由计算机程序完成的功能都可以很容易地用相应的硬件来实现,而且,用来实现同一功能的具体硬件结构也可以是多种多样的,例如模拟电路、数字电路或专用电路等。但是,对本申请而言更多情况下软件程序实现是更佳的实施方式。基于这样的理解,本申请的技术方案本质上或者说对现有技术做出贡献的部分可以以软件产品的形式体现出来,该计算机软件产品存储在可读取的存储介质中,如计算机的软盘、U盘、移动硬盘、只读存储器(ROM,Read‑OnlyMemory)、随机存取存储器(RAM,RandomAccessMemory)、磁碟或者光盘等,包括若干指令用以使得一台计算机设备(可以是个人计算机,服务器,或者网络设备等)执行本申请各个实施例的方法。
[0158] 以上仅为本申请的优选实施例,并非因此限制本申请的专利范围,凡是利用本申请说明书及附图内容所作的等效结构或等效流程变换,或直接或间接运用在其他相关的技术领域,均同理包括在本申请的专利保护范围内。