掌桥专利:专业的专利平台
掌桥专利
首页

Go语言源代码混淆方法、系统、终端及存储介质

文献发布时间:2023-06-19 13:26:15


Go语言源代码混淆方法、系统、终端及存储介质

技术领域

本发明涉及软件开发技术领域,具体涉及一种Go语言源代码混淆方法、系统、终端及存储介质。

背景技术

Go语言是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。Go被誉为云计算开发语言,因为它能够一次编译到处运行,由于编译后的二进制程序只有一个可执行文件,不存在依赖库,Go语言能够做到语言级别的跨平台支持。

但是也由于Go语言原生的跨平台特性,编译后的二进制文件中包含大量的源代码信息,逆向工程师可在二进制文件中轻易找到源代码编译时依赖的包,使用的字符串和符号信息,这些能够帮助逆向工程师更加容易地破解程序。

与其他跨平台语言对比,比如Python,Lua,Java等等,它们是解释型语言,用他们编写的程序运行时,需要借助中间字节码进行差异性处理,以达到跨平台的目的。针对此种解释型语言使用的混淆技术是对字节码进行的混淆,不是二进制的。Go语言是静态型语言,编译时直接生成机器代码,不存在中间字节码转换。因此,解释型语言的混淆技术不适用于Go语言,不能达到在二进制层次混淆的目的,只能混淆字节码,但是在逆向时,操作的文件是二进制的,不是字节码的,混淆就失去了作用。

编译型的语言包括C,C++,它们的语法结构与Go语言截然不同,不存在包结构,因此,对于C和C++混淆的技术不能应用在Go语言上。

为了弥补Go语言源代码开发的程序容易被逆向破解的问题,本发明提供一种Go语言源代码混淆方法、系统、终端及存储介质。

发明内容

针对现有技术存在的由于Go语言源代码没有适用的混淆方法导致基于Go语言源代码的程序容易被逆向破解,本发明提供一种Go语言源代码混淆方法、系统、终端及存储介质,以解决上述技术问题。

第一方面,本发明提供一种Go语言源代码混淆方法,包括:

读取源代码,构建所述源代码的抽象语法树;

利用第一加密函数将抽象语法树的包名加密;

利用二进制运算技术将抽象语法树中的字符串混淆为字节码;

利用第二加密函数对抽象语法树中的符号的类型定义、函数定义和相对路径进行加密;

利用Go编译工具对经加密混淆处理后的抽象语法树进行编译得到混淆的二进制程序。

进一步的,读取源代码,构建所述源代码的抽象语法树,包括:

利用Go语音标准库中的构建抽象语法树的工具对源代码进行解析,如果源代码存在错误则返回错误信息;如果解析通过,返回抽象语法树结构,所述抽象语法树结构包含包的详细信息、在当前编译环境中的详细路径、每个语法节点的结构信息。

进一步的,利用加密函数将抽象语法树的包名加密,包括:

确定源代码的根目录,并遍历所述根目录下的所有包目录,采集包目录的相对路径;

利用第一加密函数对包目录的相对路径进行加密,并将得到的加密路径作为包名;

根据包名按照原目录架构创建目录,得到加密后的目录结构;

将抽象语法树的初始包名更新为加密后的目录结构的对应包名。

进一步的,利用二进制运算技术将抽象语法树中的字符串混淆为字节码,包括:

在抽象语法树中通过节点类型查找字符串;

如果字符串为常量,则将字符串转换为保留字格式。

进一步的,将字符串转换为保留字格式,包括:

利用随机数生成函数生成与字符串同等字符数量的字节码;

依次将每个字符串和对应位置的随机字节码进行异或运算,生成中间字符串;

依次将每个字节码与对应位置的中间字符串进行异或运算,生成一串混淆字节码。

进一步的,利用加密函数对抽象语法树中的符号的类型定义、函数定义和相对路径进行加密,包括:

获取源代码的类型定义结构,采集类型定义结构的绝对路径,在绝对路径下的文件中读取函数定义;

遍历源代码,获取函数定义的接收类型,根据接收类型定位相对路径;

利用第二加密函数对抽象结构树中对应的类型定义结构、函数定义和相对路径进行加密。

进一步的,所述第一加密函数和第二加密函数均为客制化函数,客制化函数包括但不限于哈希函数、编码转换函数、组合函数中的任一种。

第二方面,本发明提供一种Go语言源代码混淆系统,包括:

目标构建单元,用于读取源代码,构建所述源代码的抽象语法树;

包名加密单元,用于利用第一加密函数将抽象语法树的包名加密;

字符混淆单元,用于利用二进制运算技术将抽象语法树中的字符串混淆为字节码;

符号加密单元,用于利用第二加密函数对抽象语法树中的符号的类型定义、函数定义和相对路径进行加密;

目标编译单元,用于利用Go编译工具对经加密混淆处理后的抽象语法树进行编译得到混淆的二进制程序。

进一步的,目标构建单元用于:

利用Go语音标准库中的构建抽象语法树的工具对源代码进行解析,如果源代码存在错误则返回错误信息;如果解析通过,返回抽象语法树结构,所述抽象语法树结构包含包的详细信息、在当前编译环境中的详细路径、每个语法节点的结构信息。

进一步的,包名加密单元用于:

确定源代码的根目录,并遍历所述根目录下的所有包目录,采集包目录的相对路径;

利用第一加密函数对包目录的相对路径进行加密,并将得到的加密路径作为包名;

根据包名按照原目录架构创建目录,得到加密后的目录结构;

将抽象语法树的初始包名更新为加密后的目录结构的对应包名。

进一步的,字符混淆单元用于:

在抽象语法树中通过节点类型查找字符串;

如果字符串为常量,则将字符串转换为保留字格式。

进一步的,字符混淆单元用于:

利用随机数生成函数生成与字符串同等字符数量的字节码;

依次将每个字符串和对应位置的随机字节码进行异或运算,生成中间字符串;

依次将每个字节码与对应位置的中间字符串进行异或运算,生成一串混淆字节码。

进一步的,符号加密单元用于:

获取源代码的类型定义结构,采集类型定义结构的绝对路径,在绝对路径下的文件中读取函数定义;

遍历源代码,获取函数定义的接收类型,根据接收类型定位相对路径;

利用第二加密函数对抽象结构树中对应的类型定义结构、函数定义和相对路径进行加密。

进一步的,所述第一加密函数和第二加密函数均为客制化函数,客制化函数包括但不限于哈希函数、编码转换函数、组合函数中的任一种。

第三方面,提供一种终端,包括:

处理器、存储器,其中,

该存储器用于存储计算机程序,

该处理器用于从存储器中调用并运行该计算机程序,使得终端执行上述的终端的方法。

第四方面,提供了一种计算机存储介质,所述计算机可读存储介质中存储有指令,当其在计算机上运行时,使得计算机执行上述各方面所述的方法。

本发明的有益效果在于,

本发明提供的Go语言源代码混淆方法、系统、终端及存储介质,通过构建Go语言源代码的抽象语法树,然后对抽象语法树的包名、字符串和符号进行加密混淆,利用Co编译工具对经过加密混淆处理的抽象语法树进行编译,即可得到经加密混淆的Go语言程序。本发明不只是对字符串进行了混淆,还对类型以及包名进行混淆,极大地增加了程序的复杂度,填补了Go语言的混淆技术的空白,可以有效防止静态的逆向分析,提高产品的安全性,可以有效防止程序产品被逆向破解,避免不必要的财产损失。

此外,本发明设计原理可靠,结构简单,具有非常广泛的应用前景。

附图说明

为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,对于本领域普通技术人员而言,在不付出创造性劳动的前提下,还可以根据这些附图获得其他的附图。

图1是本发明一个实施例的方法的示意性流程图。

图2是本发明一个实施例的系统的示意性框图。

图3为本发明实施例提供的一种终端的结构示意图。

具体实施方式

为了使本技术领域的人员更好地理解本发明中的技术方案,下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都应当属于本发明保护的范围。

下面对本发明中出现的关键术语进行解释。

抽象语法树(abstract syntax code,AST)是源代码的抽象语法结构的树状表示,树上的每个节点都表示源代码中的一种结构,这所以说是抽象的,是因为抽象语法树并不会表示出真实语法出现的每一个细节,比如说,嵌套括号被隐含在树的结构中,并没有以节点的形式呈现。抽象语法树并不依赖于源语言的语法,也就是说语法分析阶段所采用的上下文无文文法,因为在写文法时,经常会对文法进行等价的转换(消除左递归,回溯,二义性等),这样会给文法分析引入一些多余的成分,对后续阶段造成不利影响,甚至会使合个阶段变得混乱。因些,很多编译器经常要独立地构造语法分析树,为前端,后端建立一个清晰的接口。抽象语法树在很多领域有广泛的应用,比如浏览器,智能编辑器,编译器。当在源程序语法分析工作时,是在相应程序设计语言的语法规则指导下进行的。语法规则描述了该语言的各种语法成分的组成结构,通常可以用所谓的前后文无关文法或与之等价的Backus-Naur范式(BNF)将一个程序设计语言的语法规则确切的描述出来。前后文无关文法有分为这么几类:LL(1),LR(0),LR(1),LR(k),LALR(1)等。每一种文法都有不同的要求,如LL(1)要求文法无二义性和不存在左递归。当把一个文法改为LL(1)文法时,需要引入一些隔外的文法符号与产生式。

计算机语言中的var:Pascal:var在Pascal作为程序的保留字,用于定义变量。如:var a:integer;(定义变量a,类型为整数)var u:array[1..100]of integer;(定义数组u,下标由1至100,数组单元类型为整数)。

异或,英文为exclusive OR,缩写成eor,异或(eor)是一个数学运算符。它应用于逻辑运算。异或的数学符号为“⊕”,计算机符号为“eor”。其运算法则为:

Go语言编译后的代码虽然是二进制的,但是包名,字符串和符号依然清晰可见,与源代码中一致,造成信息泄露,逆向工程师可以提取出这些原生数据,分析后还原代码的逻辑,造成程序被破解。

为了弥补以上的不足,本发明提出一种对Go语言中包名、字符串和符号进行混淆的算法,经过处理后,生成的二进制文件中的相关信息变的混乱不可读,极大地提高了逆向工程破解的难度。

图1是本发明一个实施例的方法的示意性流程图。其中,图1执行主体可以为一种Go语言源代码混淆系统。

如图1所示,该方法包括:

步骤110,读取源代码,构建所述源代码的抽象语法树;

步骤120,利用第一加密函数将抽象语法树的包名加密;

步骤130,利用二进制运算技术将抽象语法树中的字符串混淆为字节码;

步骤140,利用第二加密函数对抽象语法树中的符号的类型定义、函数定义和相对路径进行加密;

步骤150,利用Go编译工具对经加密混淆处理后的抽象语法树进行编译得到混淆的二进制程序。

为了便于对本发明的理解,下面以本发明Go语言源代码混淆方法的原理,结合实施例中对Go语言源代码进行混淆的过程,对本发明提供的Go语言源代码混淆方法做进一步的描述。

具体的,所述Go语言源代码混淆方法包括:

S1、读取源代码,构建所述源代码的抽象语法树。

Go语言标准库提供了构建抽象语法树的包AST,可以对源代码进行解析,如果存在语法错误,会报错,解析通过后,返回抽象语法树的结构,注意在此结构中,包含包的详细信息,比如包名,在当前编译环境中的详细路径,每个语法节点的结构信息(类型、值和元数据等)。

S2、利用第一加密函数将抽象语法树的包名加密。

确定源代码的根目录,并遍历所述根目录下的所有包目录,采集包目录的相对路径;利用第一加密函数对包目录的相对路径进行加密,并将得到的加密路径作为包名;根据包名按照原目录架构创建目录,得到加密后的目录结构;将抽象语法树的初始包名更新为加密后的目录结构的对应包名。

Go语言以目录为依据进行包的区分,比如目录结构为a/b/c,则包的名称为a.b.c。所以,可以通过更改目录名称的方式进行包名称的混淆。过程如下:

(1)确定源代码的根目录,比如说为“D:\\mygo”。

(2)迭代遍历该目录下的所有文件和目录,得到目录的相对路径,比如说“mygo”目录下有“animal”和“tree”两个目录,则拿到“.\\animal”和“.\\tree”两个值,这两个值为包的名称。

(3)使用HASH函数,比如SHA256,对包名取哈希值,此处也可以使用多种加密方式,比如BASE64等等,我们命名此函数为ENC,拿到两个值:a=ENC(“animal”)和b=ENC(“tree”),在与“animal”和“tree”同级目录下,新建两个目录,取名为a和b。

(4)将“animal”和“tree”目录下的文件(非目录)拷贝到a和b下。

(5)若“animal”和“tree”目录下还有目录,则在获取到加密后的目录名后,在第三步新建的目录中新建目录,取名为加密后的值,以此类推。迭代处理源代码目录结构中包名称,得到完整的加密后的目录结构。

(6)迭代处理源代码文件,找到package节点,更改对应的明文包名“p”为“ENC(p)”。

经过以上步骤后,源代码中的包名称已替换成加密后的字符串,并对应修改了源代码中引用部分的包名称。

S3、利用二进制运算技术将抽象语法树中的字符串混淆为字节码。

在抽象语法树中通过节点类型查找字符串;如果字符串为常量,则将字符串转换为保留字格式。将字符串转换为保留字格式的方法,包括:利用随机数生成函数生成与字符串同等字符数量的字节码;依次将每个字符串和对应位置的随机字节码进行异或运算,生成中间字符串;依次将每个字节码与对应位置的中间字符串进行异或运算,生成一串混淆字节码。

源代码文件中的字符串可以通过子序列生成的方式进行混淆,以下为具体过程:

(1)在抽象语法树中通过节点类型找到字符串s。

(2)如果找到的s为const,需要修改成var,这样就可以通过动态生成的方式生成字符串,而不需要硬编码了。

具体的,找到s后,将s替换为以下子序列:

此子序列通过随机生成与字符串同样数量的字节码(0到255),顺序地将每个字符串和对应位置的随机字节码进行XOR操作(二进制运算),生成一个中间字符串,然后再从头开始,顺序地将每个字节码与对应位置的中间字符串值进行XOR操作,生成一串字节码,然后获取字节码代表的字符串。该字符串与原始字符串是一致的,保证了程序混淆前后的逻辑不变。

(3)遍历抽象语法树,将找到的字符串替换为上面的混淆字节码。

在经过上述步骤后,可以把源代码中的字符串替换为了子序列,不再是明显的字符串。生成的二进制文件中将不再有明显的字符串,而是一段代码。

S4、利用第二加密函数对抽象语法树中的符号的类型定义、函数定义和相对路径进行加密。

获取源代码的类型定义结构,采集类型定义结构的绝对路径,在绝对路径下的文件中读取函数定义;遍历源代码,获取函数定义的接收类型,根据接收类型定位相对路径;利用第二加密函数对抽象结构树中对应的类型定义结构、函数定义和相对路径进行加密。

符号就是类型,Go语言是类型严格语言,在定义参数、函数、变量等时,需要明确类型。类型信息可以暴露内存信息,比如int类型的参数拥有4个字节(32位系统),逆向工程师可以根据类型信息查找到变量在内存中的位置,从而在运行过程中访问程序控制之外的内存。

本发明提出以下类型混淆算法,可以对源代码中的类型定义、变量声明、函数的receiver进行编译时混淆:

获取源代码中的类型定义结构t,拿到其绝对路径,如,在“animal”文件夹下有dog.go文件,文件中定义了eat函数和sheepdog类型,则其绝对路径为:animal/eat和animal/sheepdog。

遍历源代码,获取函数定义中的receiver类型,拿到其相对路径,比如sheepdog的定义为“func(*Animal)sheepdog()”,receiver为“*Animal”,则相对路径为“*animal/Animal”。

将类型定义、函数定义和receiver的相对路径进行加密混淆,如t_obfuscation=ENC(t_relative),其中ENC()表示加密函数,加密函数可由用户自行选择,本实施例采用哈希加密算法。

使用t_obfuscation替换掉抽象语法树中的t_relative。

经过以上步骤,可以将抽象语法树中的类型信息进行混淆。

S5、利用Go编译工具对经加密混淆处理后的抽象语法树进行编译得到混淆的二进制程序。

将混淆后的抽象语法树通过go编译工具进行编译,既可获得混淆后的二进制程序。

本实施例不只是对字符串进行了混淆,还对类型以及包名进行混淆,极大地增加了程序的复杂度,可以有效防止静态的逆向分析,提高产品的安全性。公司使用go语言开发的产品均可以使用本专利提出的算法进行混淆,可以有效防止逆向,避免不必要的财产损失。

如图2所示,该系统200包括:

目标构建单元210,用于读取源代码,构建所述源代码的抽象语法树;

包名加密单元220,用于利用第一加密函数将抽象语法树的包名加密;

字符混淆单元230,用于利用二进制运算技术将抽象语法树中的字符串混淆为字节码;

符号加密单元240,用于利用第二加密函数对抽象语法树中的符号的类型定义、函数定义和相对路径进行加密;

目标编译单元250,用于利用Go编译工具对经加密混淆处理后的抽象语法树进行编译得到混淆的二进制程序。

可选地,作为本发明一个实施例,目标构建单元用于:

利用Go语音标准库中的构建抽象语法树的工具对源代码进行解析,如果源代码存在错误则返回错误信息;如果解析通过,返回抽象语法树结构,所述抽象语法树结构包含包的详细信息、在当前编译环境中的详细路径、每个语法节点的结构信息。

可选地,作为本发明一个实施例,包名加密单元用于:

确定源代码的根目录,并遍历所述根目录下的所有包目录,采集包目录的相对路径;

利用第一加密函数对包目录的相对路径进行加密,并将得到的加密路径作为包名;

根据包名按照原目录架构创建目录,得到加密后的目录结构;

将抽象语法树的初始包名更新为加密后的目录结构的对应包名。

可选地,作为本发明一个实施例,字符混淆单元用于:

在抽象语法树中通过节点类型查找字符串;

如果字符串为常量,则将字符串转换为保留字格式。

可选地,作为本发明一个实施例,字符混淆单元用于:

利用随机数生成函数生成与字符串同等字符数量的字节码;

依次将每个字符串和对应位置的随机字节码进行异或运算,生成中间字符串;

依次将每个字节码与对应位置的中间字符串进行异或运算,生成一串混淆字节码。

可选地,作为本发明一个实施例,符号加密单元用于:

获取源代码的类型定义结构,采集类型定义结构的绝对路径,在绝对路径下的文件中读取函数定义;

遍历源代码,获取函数定义的接收类型,根据接收类型定位相对路径;

利用第二加密函数对抽象结构树中对应的类型定义结构、函数定义和相对路径进行加密。

可选地,作为本发明一个实施例,所述第一加密函数和第二加密函数均为客制化函数,客制化函数包括但不限于哈希函数、编码转换函数、组合函数中的任一种。

图3为本发明实施例提供的一种终端300的结构示意图,该终端300可以用于执行本发明实施例提供的Go语言源代码混淆方法。

其中,该终端300可以包括:处理器310、存储器320及通信单元330。这些组件通过一条或多条总线进行通信,本领域技术人员可以理解,图中示出的服务器的结构并不构成对本发明的限定,它既可以是总线形结构,也可以是星型结构,还可以包括比图示更多或更少的部件,或者组合某些部件,或者不同的部件布置。

其中,该存储器320可以用于存储处理器310的执行指令,存储器320可以由任何类型的易失性或非易失性存储终端或者它们的组合实现,如静态随机存取存储器(SRAM),电可擦除可编程只读存储器(EEPROM),可擦除可编程只读存储器(EPROM),可编程只读存储器(PROM),只读存储器(ROM),磁存储器,快闪存储器,磁盘或光盘。当存储器320中的执行指令由处理器310执行时,使得终端300能够执行以下上述方法实施例中的部分或全部步骤。

处理器310为存储终端的控制中心,利用各种接口和线路连接整个电子终端的各个部分,通过运行或执行存储在存储器320内的软件程序和/或模块,以及调用存储在存储器内的数据,以执行电子终端的各种功能和/或处理数据。所述处理器可以由集成电路(Integrated Circuit,简称IC)组成,例如可以由单颗封装的IC所组成,也可以由连接多颗相同功能或不同功能的封装IC而组成。举例来说,处理器310可以仅包括中央处理器(Central Processing Unit,简称CPU)。在本发明实施方式中,CPU可以是单运算核心,也可以包括多运算核心。

通信单元330,用于建立通信信道,从而使所述存储终端可以与其它终端进行通信。接收其他终端发送的用户数据或者向其他终端发送用户数据。

本发明还提供一种计算机存储介质,其中,该计算机存储介质可存储有程序,该程序执行时可包括本发明提供的各实施例中的部分或全部步骤。所述的存储介质可为磁碟、光盘、只读存储记忆体(英文:read-only memory,简称:ROM)或随机存储记忆体(英文:random access memory,简称:RAM)等。

因此,本发明通过构建Go语言源代码的抽象语法树,然后对抽象语法树的包名、字符串和符号进行加密混淆,利用Co编译工具对经过加密混淆处理的抽象语法树进行编译,即可得到经加密混淆的Go语言程序。本发明不只是对字符串进行了混淆,还对类型以及包名进行混淆,极大地增加了程序的复杂度,填补了Go语言的混淆技术的空白,可以有效防止静态的逆向分析,提高产品的安全性,可以有效防止程序产品被逆向破解,避免不必要的财产损失,本实施例所能达到的技术效果可以参见上文中的描述,此处不再赘述。

本领域的技术人员可以清楚地了解到本发明实施例中的技术可借助软件加必需的通用硬件平台的方式来实现。基于这样的理解,本发明实施例中的技术方案本质上或者说对现有技术做出贡献的部分可以以软件产品的形式体现出来,该计算机软件产品存储在一个存储介质中如U盘、移动硬盘、只读存储器(ROM,Read-Only Memory)、随机存取存储器(RAM,Random Access Memory)、磁碟或者光盘等各种可以存储程序代码的介质,包括若干指令用以使得一台计算机终端(可以是个人计算机,服务器,或者第二终端、网络终端等)执行本发明各个实施例所述方法的全部或部分步骤。

本说明书中各个实施例之间相同相似的部分互相参见即可。尤其,对于终端实施例而言,由于其基本相似于方法实施例,所以描述的比较简单,相关之处参见方法实施例中的说明即可。

在本发明所提供的几个实施例中,应该理解到,所揭露的系统和方法,可以通过其它的方式实现。例如,以上所描述的系统实施例仅仅是示意性的,例如,所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些接口,系统或单元的间接耦合或通信连接,可以是电性,机械或其它的形式。

所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部单元来实现本实施例方案的目的。

另外,在本发明各个实施例中的各功能单元可以集成在一个处理单元中,也可以是各个单元单独物理存在,也可以两个或两个以上单元集成在一个单元中。

尽管通过参考附图并结合优选实施例的方式对本发明进行了详细描述,但本发明并不限于此。在不脱离本发明的精神和实质的前提下,本领域普通技术人员可以对本发明的实施例进行各种等效的修改或替换,而这些修改或替换都应在本发明的涵盖范围内/任何熟悉本技术领域的技术人员在本发明揭露的技术范围内,可轻易想到变化或替换,都应涵盖在本发明的保护范围之内。因此,本发明的保护范围应所述以权利要求的保护范围为准。

相关技术
  • Go语言源代码混淆方法、系统、终端及存储介质
  • 基于Go语言代码混淆的单元众包保护方法、装置及存储介质
技术分类

06120113678193