一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

Solidity语言源代码混淆方法、系统、设备及存储介质

2022-06-11 13:01:14 来源:中国专利 TAG:

solidity语言源代码混淆方法、系统、设备及存储介质
技术领域
1.本发明涉及一种solidity语言源代码混淆方法、系统、设备及存储介质,针对以太坊智能合约,属于区块链安全领域。


背景技术:

2.以太坊(ethereum)是一个开源的有智能合约功能的公共区块链平台,它解决了比特币网络拓展性不足的问题。智能合约是在区块链平台上运行的自主程序。它们通常用solidity语言开发,然后编译生成二进制文件。将智能合约部署到相应区块链中后,任何人都可以公开查阅该智能合约的二进制文件的内容,通过调用的方式执行智能合约,但是无法修改智能合约。因此,如何保证部署后的智能合约有着足够的复杂度,从而很好地抵制逆向破解是一件很值得关注的问题。
3.solidity语言是专门面向智能合约开发的静态强类型、编译型,支持继承、支持各种库和用户自定义类型的高级语言。非常适合用来开发类似于投票,众筹,拍卖,多重签名钱包等各种功能。因为solidity是编译型语言,编译后的二进制文件存在着丰富的源代码信息,二进制文件中使用的字符串和符号信息,都可以为逆向工程师破解程序提供帮助。
4.与其他语言对比,比如解释型语言python、javascript、php、shell、matlab等,它们编写的程序在一边执行一边转换的过程,存在着中间字节码转换。针对这些语言使用的混淆相关技术是对中间字节码进行混淆,而solidity作为编译型语言并不存在中间字节码部分,混淆失去了作用。而对于其他编译型语言包括c、c 、go等语言来说,它们的语法结构与solidity语言截然不同,并没有诸如合约,转账等特殊结构,因此对于c、c 、go等语言的混淆技术无法应用在solidity语言上。


技术实现要素:

5.发明目的:针对上述现有技术的不足,本发明目的是提供一种solidity语言源代码混淆方法,通过使代码难以阅读、修改智能合约的数据字段和隐藏智能合约的内部逻辑等相关技术达到生成混淆后智能合约的目的,提升智能合约抵制逆向破解的能力。
6.技术方案:为实现上述发明目的,本发明所述的一种solidity语言源代码混淆方法,包括如下步骤:
7.步骤1:读取源代码,构建所述源代码的抽象语法树和控制流图;
8.步骤2:替换源代码中的变量名、扰乱源代码布局并删除辅助信息;
9.步骤3:转换源代码中变量状态,将常量转换为函数调用或算术表达式,以修改智能合约中的数据字段;
10.步骤4:将全局代码控制流控制流、函数体内控制流以及循环或分支基本块通过switch-case的方式扁平化,并在循环或分支语句基于结合chebyshev和pwlcm(分段线性混沌映射)的一维混沌映射(chebyshev-pwlcm map,cpm)生成并引入混沌永真不透明谓词,以隐藏原始程序的内部逻辑;
11.步骤5:判断智能合约混淆前后功能是否一致,在功能一致的前提下,完成solidity语言的源代码混淆。
12.作为优选,所述步骤2进一步包括:
13.步骤21:寻找源代码中每个变量的名字和对应位置,使用加密算法生成对应的加密值后进行替换;
14.步骤22:使用正则表达式,将换行、空格字符替换为
‘’
,并且将连续空白替换为单个空白;
15.步骤23:使用正则表达式,将源代码中的单行注释和多行注释全都替换为
‘’
,删除源代码中的辅助信息。
16.作为优选,所述步骤3进一步包括:
17.步骤31:寻找源代码中的所有被声明的本地变量,用新声明的全局变量替换找到的本地变量。
18.步骤32:寻找源代码中的所有类型常量的位置和数值,根据常量值声明数组,然后将常量替换为对应的函数调用,实现静态数据转为动态生成;
19.步骤33:寻找源代码中的所有布尔变量,若布尔变量为真,使用“或”运算符与后续表达式相连接;若布尔变量为假,使用“与”运算符与后续表达式相连接;所述后续表达式是一个布尔运算表达式或是一个算术表达式,或其组合。
20.步骤34:寻找源代码中所有状态变量,将它们集中在一个结构体中,通过结构体成员变量的方式调用它们,从而将标量转为向量。
21.作为优选,所述步骤4中全局代码控制流扁平化和函数体内控制流扁平化的代码实现是一样的,都是通过switch-case的方式进行扁平化操作,只是函数体内控制流扁平化多了函数外壳抽取的步骤。循环或分支基本块扁平化则是更进一步需要解析循环或者分支语句中的表达式,根据表达式的的真值状态进行扁平化,若表达式的真值为真,则生成一个switch-case分支,若表达式的真值为假,则生成另一个swith-case分支。
22.为了让不透明谓词插入到智能合约中达到良好的混淆效果,挑选合适的混沌系统这一过程更多地是注重混沌系统的敏感性、随机性和时效性。
23.生成不透明谓词的方法是:结合了chebyshev和pwlcm混沌映射,提出了一种改进的一维混沌映射(chebyshev-pwlcm map,cpm)。cpm的主要设计方向是保留chebyshev和pwlcm混沌映射良好的敏感性和不确定性,同时尽可能削弱和去除chebyshev混沌映射混沌范围较小和pwlcm混沌映射存在断点的问题,增加了改进后混沌映射的安全性、连续性和分布均匀性。改进后混沌映射的定义如下:
[0024][0025]
其中,给定一个初始值x0,根据x0迭代出x1,随之得出xn,xn∈[-1,1],由xn生成x
n 1
;μ,p均为该混沌映射的控制参数,μ∈z
*
,p∈(0,0.5);f为该一维混沌映射的迭代公式,当0.5≤xn<1时,函数中的变量xn=1-xn,其余参数μ,p不变;当μ≥2,p∈(0,0.5)时,cpm混沌
映射处于混沌状态;m属于该混沌映射中密钥的部分组成,是该混沌映射的扰动参数。cpm混沌映射在保留chebyshev和pwlcm混沌映射良好的初值敏感性和随机性的同时,也去除了pwlcm的零点问题,扩大了混沌范围,增加了混沌映射的安全性和连续性。除此之外,cpm更进一步地将混沌轨迹地更加均匀地混合,提高了混沌映射的性能。
[0026]
引入不透明谓词的方法是:先选定不透明谓词将要插入的表达式exp,观察其结构并且按照规则进行分解,然后根据分解结果生成若干数目不透明谓词p,将生成的不透明谓词和分解结果进行合并,若生成为永真不透明谓词则为exp&p,若生成为永假不透明谓词则为exp||p并且平移,生成新的表达式,增加了混淆过程的复杂度。
[0027]
作为优选,所述步骤2至4中如果存在失败,则跳过失败部分,进行下一步混淆,返回错误报告并且生成相应solidity源代码。如果上述功能中不存在失败,返回成功信息并且生成相应solidity源代码。
[0028]
基于相同的发明构思,本发明提供一种solidity语言源代码混淆系统,包括以下部分:
[0029]
目标构建单元,用于读取源代码,构建所述源代码的抽象语法树和控制流图;
[0030]
第一处理单元,用于替换源代码中的变量名、扰乱源代码布局并删除辅助信息;
[0031]
第二处理单元,用于转换源代码中变量状态、将常量转换为函数调用或算术表达式以修改智能合约中的数据字段;
[0032]
第三处理单元,用于将全局代码控制流控制流、函数体内控制流以及循环或分支基本块通过switch-case的方式扁平化,并在循环或分支语句基于结合chebyshev和pwlcm的一维混沌映射cpm生成并引入混沌永真不透明谓词,以隐藏原始程序的内部逻辑;
[0033]
目标生成单元,用于判断智能合约混淆前后功能是否一致,在功能一致的前提下,完成solidity语言的源代码混淆。
[0034]
基于相同的发明构思,本发明提供一种电子设备,包括存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序,所述计算机程序被加载至处理器时实现所述的solidity语言源代码混淆方法。
[0035]
基于相同的发明构思,本发明提供一种计算机可读存储介质,所述计算机可读存储介质存储有计算机程序,所述计算机程序被处理器执行时实现所述的solidity语言源代码混淆方法。
[0036]
有益效果:本发明提供了一种solidity语言源代码混淆方法,针对使用solidity语言开发的以太坊智能合约,本方法的输入为使用solidity语言开发的以太坊智能合约。利用源代码中的变量名替换、扰乱源代码布局和删除辅助信息技术让攻击者更加难以阅读和理解代码;利用转换源代码中变量状态、类型技术从而修改智能合约中的数据字段;利用代码扁平化和改进的不透明谓词生成与引入技术隐藏了原始程序的内部逻辑;利用难以阅读的代码、修改智能合约的数据字段和隐藏智能合约的内部逻辑,在智能合约混淆前后功能一致的前提下,实现solidity语言的源代码混淆。本发明极大地增加了solidity语言开发的以太坊智能合约的复杂度,有效地增强了智能合约抵制逆向破解的能力,提高了智能合约的安全性,避免不必要的财产损失。
附图说明
[0037]
图1为本发明实施例的整体步骤流程图。
[0038]
图2为本发明具体示例的方法流程图。
[0039]
图3是本发明一个实施例的系统的示意性框图。
具体实施方式
[0040]
下面结合具体实施例,进一步阐明本发明,应理解这些实施例仅用于说明本发明而不用于限制本发明的范围,在阅读了本发明之后,本领域技术人员对本发明的各种等价形式的修改均落于本技术所附权利要求所限定的范围。
[0041]
考虑区块链上的数据具有不可修改的特性以及以太坊智能合约大多涉及到金钱交易,所以智能合约被逆向破解成功而造成的损失相较于其他领域要严重得多。本发明实施例提供一种solidity语言源代码混淆方法,如图1所示,主要包括5个步骤:
[0042]
步骤1:读取源代码,构建所述源代码的抽象语法树和控制流图;
[0043]
步骤2:替换源代码中的变量名、扰乱源代码布局并删除辅助信息;
[0044]
步骤3:转换源代码中变量状态,将常量转换为函数调用或算术表达式,以修改智能合约中的数据字段;
[0045]
步骤4:将全局代码控制流控制流、函数体内控制流以及循环或分支基本块通过switch-case的方式扁平化,并在循环或分支语句基于改进一维混沌映射cpm生成并引入混沌永真不透明谓词,以隐藏原始程序的内部逻辑;
[0046]
步骤5:判断智能合约混淆前后功能是否一致,在功能一致的前提下,完成solidity语言的源代码混淆。
[0047]
如图2所示,本发明实施例以从以太坊浏览器上任意一份公开的、以solidity语言编写的以太坊智能合约为例,说明本发明实施例公开的一种solidity语言源代码混淆方法的详细步骤,具体如下:
[0048]
所述步骤1中的以太坊智能合约源代码需要是使用以太坊智能合约高级编程语言solidity编写的,在本步骤中对读取源代码,构建所述源代码的抽象语法树和控制流图,所述步骤1进一步叙述为:
[0049]
步骤11:从以太坊浏览器官网(https://etherscan.io/verifiedcontracts/)选择任意一份使用solidity语言编写的以太坊智能合约,复制合约的源代码,将其保存到本地,保存为.sol格式的文件。
[0050]
步骤12:利用solidity命令行编译器,即solc对源代码进行读取,使用solc-o outputdirectory
‑‑
ast sourcefile.sol命令解析源代码,如果源代码存在错误则返回错误信息;如果对于源代码的解析成功,返回抽象语法树的结构,以文件形式返回,所述抽象语法树结构包含包的详细信息、在当前编译环境中的详细路径、每个语法节点的结构信息。
[0051]
步骤13:逐行读入生成的抽象语法树文件,将抽象语法树的内容存储于一个字符串数组中。逐行遍历数组,为了尽可能地复用抽象语法树中的内容创建基本块对象,将一个基本块中的所有抽象语法树节点收集到数组中,比如说将抽象语法树中的“name”为“block”进行定位并且记录作为基本块组成,并且记录控制流图的入边和出边,比如使用抽象语法树中的“functiondefinition”和“functioncall”产生函数的调用关系,“ifstatement”,“whilestatement”等作为分支和循环语句关键词圈定循环体的范围;创建控制流图边对象表示控制流图的边,用于连接源和目标基本块,并且记录下跳转目标的条件,比如使用“binaryoperation”确定条件的范围,“operator”确定运算符,在条件范围上下的“attributes”中找到左右的操作数;创建数据流对象记录变量的赋值,每个数据流对象只记录一个变量的一次赋值。
[0052]
步骤14:综合基本块对象、控制流图边对象和数据流对象,从而生成一个完整的控制流图,使用图形绘图工具graphviz,以基本块为节点和相应的控制流图边生成相应的控制流图,命名规则为“原文件名_controlflow.dot”。
[0053]
所述步骤2利用源代码中的变量名替换、扰乱源代码布局和删除辅助信息技术让攻击者更加难以阅读和理解代码,所述步骤2进一步叙述为:
[0054]
步骤21:寻找源代码中每个变量的名字和对应位置,使用加密算法生成对应的加密值后进行替换。
[0055]
步骤22:使用正则表达式“\\s*|\t|\r|\n”,将换行、空格字符替换为
‘’
,并且将连续空白替换为单个空白,达到扰乱源代码布局的作用;
[0056]
步骤23:使用正则表达式“//[^\\n]*|/\\*([^\\*^/]*|[\\*^/*]*|[^\\**/]*)*\\* /”,将源代码中的单行注释和多行注释全都替换为
‘’
,删除源代码中的辅助信息。
[0057]
在步骤3中,我们使用步骤2后完成信息扰乱,通过解析抽象语法树来转换源代码中变量状态、类型技术从而修改智能合约中的数据字段,步骤3可进一步分为:
[0058]
步骤31:寻找源代码中的所有被声明的本地变量,然后处理可能存在的同名本地变量。记录本地变量出现在源代码中的位置,用新声明的全局变量逐个替换找到的本地变量。比如通过解析抽象语法树文件,确定“variabledeclaration”,“referenceddeclaration”等元素位置,根据它们的“src”中的作用域,确立替换范围。将本地变量重新声明并且替换。
[0059]
步骤32:solidity中存在四种常量——整型、布尔型、字符串型和十六进制字符串型,即“attributes”中的“type”的类型。通过解析抽象语法树文件,获取前三种类型常量的存在位置和对应值(最后一种类型无法获取其值)。然后根据常量的值声明数组,将常量值声明在数组中。然后插入函数,用于返回不同数组的不同索引对应元素。最后,将常量替换为对应的函数调用。
[0060]
此外,对于整型常量也可替换为表达式。寻找源代码中的所有整型常量,即“attributes”中的“type=uint256或其他位数”。根据它们的“src”中的作用域,记录该常量存在位置。将其转换为较为复杂的算术表达式,该算术表达式可以生成原值。受限于solidity语言不支持浮点数,生成的算术表达式中不包含浮点数也不使用除法。
[0061]
步骤33:寻找源代码中的所有布尔变量,即“attributes”中的“type=bool”。根据它们的“src”中的作用域,记录该常量存在位置。若布尔变量为真,使用“或”运算符与后续表达式相连接。若布尔变量为假,使用“与”运算符与后续表达式相连接。后续表达式可能是一个布尔运算表达式,也可能是一个算术表达式。比如说,对于布尔变量b,若该变量为真,则拆分b=b||q;若该变量为假,则拆分b=b&&q,其中q可能是布尔表达式,也可能是一个算术表达式。
[0062]
步骤34:寻找源代码中所有状态变量即“attributes”中的“statevariable”,将它们集中在一个结构体中,通过结构体成员变量的方式调用它们,即“attributes”中的“memberaccess”,调用的位置由它们的“src”中的作用域所确立。从而将标量转为向量。
[0063]
在步骤4中,我们使用步骤3后完成数据修改,利用代码扁平化和不透明谓词技术隐藏了原始程序的内部逻辑,步骤4可进一步分为:
[0064]
步骤41:源代码的控制流图信息首先被输入,然后判断输入参数的完整性。如果参数丢失,下面的混淆步骤就不能进行。下面的混淆步骤不能执行。如果参数形式是正确的,则生成和插入不透明的谓词以及控制流的扁平化。不透明的谓词的生成和插入以及控制流的扁平化将被执行。
[0065]
步骤42:根据构建的控制流图,寻找代码中循环语句、分支语句和顺序语句。因为基本块在运行中都是顺序执行的,因此可以将控制流的扁平化分为三类:全局代码控制流扁平化、函数体内控制流扁平化和循环或分支基本块扁平化。具体扁平化如下代码所示:
[0066][0067]
其中全局代码控制流扁平化和函数体内控制流扁平化的代码实现是一样的,都是通过switch-case的方式进行扁平化操作,只是函数体内控制流扁平化多了函数外壳抽取的步骤。循环或分支基本块扁平化则是更进一步需要解析循环或者分支语句中的表达式,根据表达式的真值状态进行扁平化,若表达式的真值为真,则生成一个switch-case分支,若表达式的真值为假,则生成另一个swith-case分支,
[0068]
步骤43:生成不透明谓词的方法是:结合了chebyshev和pwlcm混沌映射,提出了一种改进的一维混沌映射(chebyshev-pwlcm map,cpm)。cpm的主要设计方向是保留chebyshev和pwlcm混沌映射良好的敏感性和不确定性,同时尽可能削弱和去除chebyshev混沌映射混沌范围较小和pwlcm混沌映射存在断点的问题,增加了改进后混沌映射的安全性、连续性和分布均匀性。改进后混沌映射的定义如下:
[0069][0070]
其中,给定一个初始值x0,根据x0迭代出x1,随之得出xn,xn∈[-1,1],由xn生成x
n 1
;μ,p均为该混沌映射的控制参数,μ∈z
*
,p∈(0,0.5);f为该一维混沌映射的迭代公式,当0.5≤xn<1时,函数中的变量xn=1-xn,其余参数μ,p不变;当μ≥2,p∈(0,0.5)时,cpm混沌映射处于混沌状态;m属于该混沌映射中密钥的部分组成,是该混沌映射的扰动参数。cpm混沌映射在保留chebyshev和pwlcm混沌映射良好的初值敏感性和随机性的同时,也去除了pwlcm的零点问题,扩大了混沌范围,增加了混沌映射的安全性和连续性。除此之外,cpm更进一步地将混沌轨迹地更加均匀地混合,提高了混沌映射的性能。
[0071]
步骤44:插入不透明谓词方法:第一步:定位将要插入不透明谓词的表达式exp并且分解,分解规则为:若exp中存在逻辑运算符lp,以lp为界进行分解为exp_1、lp、exp_2;若不存在,则进行第二步;第二步:若存在逻辑运算符lp,对每个子表达式单独分解,以exp_1为例,设比较运算符op为界,分解为exp_11、op、exp_12,若不存在逻辑运算符lp,则将表达式exp认为子表达式exp_1,进行上述操作;第三步:统计子表达式的个数n,生成不透明谓词p。生成基于cpm混沌映射永真不透明谓词的个数为2n,永假不透明谓词的个数为n,如p_1和p_2为永真不透明谓词,p_3为永假不透明谓词;第四步:结合不透明谓词p与分解的表达式exp,构造新的谓词,若生成为永真不透明谓词则为exp&p,若生成为永假不透明谓词则为exp||p,并且将谓词平移。
[0072]
因为p_1和p_2为永真不透明谓词,p_3为永假不透明谓词,新谓词的真值完全依赖于exp的输入值,因此,其真值表和exp的真值表完全相同,表达式地复杂化,一方面逆向工程中难以定位不透明谓词的插入位置,另一方面也增加了破解不透明谓词的难度,得到了更好的混淆效果,增加逆向工程的成本。
[0073]
所述步骤5利用难以阅读的代码、修改智能合约的数据字段和隐藏智能合约的内部逻辑,在智能合约混淆前后功能一致的前提下,实现solidity语言的源代码混淆。如果步骤2-4中存在失败,则跳过失败部分,进行下一步混淆,返回错误报告并且生成相应solidity源代码。如果上述功能中不存在失败,返回成功信息并且生成相应solidity源代码。
[0074]
为了验证本发明方法的有效性,可以使用本发明方法生成混淆后的以太坊智能合约。首先,将原始的智能合约与混淆后的智能合约进行审查,确保混淆前后智能合约的功能并没有改变;其次,使用智能合约逆向工具对混淆前后的智能合约进行反编译,对比混淆前后的智能合约抵制逆向破解的能力,评估本发明方法的混淆效果。
[0075]
混淆后的智能合约可以为智能合约的开发者提供有着一定复杂度的含有漏洞的智能合约测试用例,使其开发的工具面对复杂智能合约时候有着良好的表现,并且很好地补充了智能合约测试数据集内的数据数量。
[0076]
基于相同的发明构思,本发明实施例提供一种solidity语言源代码混淆系统,包括:目标构建单元,用于读取源代码,构建所述源代码的抽象语法树和控制流图;第一处理
单元,用于替换源代码中的变量名、扰乱源代码布局并删除辅助信息;第二处理单元,用于转换源代码中变量状态、将常量转换为函数调用或算术表达式以修改智能合约中的数据字段;第三处理单元,用于将全局代码控制流控制流、函数体内控制流以及循环或分支基本块通过switch-case的方式扁平化,并在循环或分支语句基于改进一维混沌映射cpm生成并引入混沌永真不透明谓词,以隐藏原始程序的内部逻辑;以及,目标生成单元,用于判断智能合约混淆前后功能是否一致,在功能一致的前提下,完成solidity语言的源代码混淆。
[0077]
本领域技术人员可以清楚地了解到,为描述的方便和简洁,上述描述的各单元的具体工作过程,可以参考前述方法实施例中的对应过程,在此不再赘述。所述单元的划分仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元可以结合或者可以集成到另一个系统。
[0078]
基于相同的发明构思,本发明实施例提供一种电子设备,包括存储器、处理器及存储在存储器上并可在处理器上运行的计算机程序,所述计算机程序被加载至处理器时实现所述的solidity语言源代码混淆方法。
[0079]
本领域技术人员可以理解的是,本发明的技术方案本质上或者说对现有技术做出贡献的部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质中,包括若干指令用以使得一台电子设备(可以是个人计算机,服务器,或者网络设备等)执行本发明实施例所述方法的全部或部分步骤。存储介质包括:u盘、移动硬盘、只读存储器rom、随机存取存储器ram、磁碟或者光盘等各种可以存储计算机程序的介质。
[0080]
基于相同的发明构思,本发明实施例还提供一种计算机可读存储介质,其中,该计算机可读存储介质可存储有程序,该程序执行时可包括本发明提供的各实施例中的部分或全部步骤。
再多了解一些

本文用于企业家、创业者技术爱好者查询,结果仅供参考。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献