您好, 访客   登录/注册

代码混淆技术研究综述

来源:用户上传      作者:

  摘  要: 代码混淆技术是一种语义保留的代码变换技术,是衡量代码相似度检测方法的重要指标之一。本文主要对现有的代码混淆手段的研究现状和发展进行了综述。首先阐述了代码混淆的相关定义,然后介绍了现有的几种代码混淆手段,对代码混淆手段进行了系统的分类,分别介绍了每种代码混淆手段。最后对代码混淆手段进行了总结与评价。
  关键词: 代码混淆;反编译;代码转换
  中图分类号: TP309.2    文献标识码: A    DOI:10.3969/j.issn.1003-6970.2020.02.013
  【Abstract】: Code obfuscation is a code transformation technique with semantic reservation, and it is one of the important indicators to measure source code similarity. This paper mainly reviews existing works of code obfuscation. Firstly, the definition of code obfuscation is described. Then, several existing methods of code obfuscation are introduced, and they are classified systematically. Finally, the paper summarizes and evaluates the methods of code obfuscation.
  【Key words】: Code obfuscation; Decompile; Code transcoding
  0  引言
  代码混淆是一种变换代码的流程结构及数据关系的技术,其不会改变原代码的语法和语义规则。最先提出代码混淆技术的主要目的是保护软件代码的安全[1]。由于各种语言的程序会很容易的被反编译或者恶意逆向工程攻击,因此,通过对程序进行混淆,使得程序源代码变得更加难以理解,不易被反编译工具破解,从而达到知识产权和保密信息不被窃取的目的[2-5]。
  另外,代码混淆技术也被抄袭者用来达到掩盖自己抄袭代码的目的[6]。随着现代计算机和网络的不断进步,获取源代码的途径越来越多,代码抄袭的难度也逐渐变低。代码抄袭是一种为了达到目的去完全拷贝使用或修改后使用他人代码的行为。据
  统计,在国外大约有85%的学生承认曾抄袭过别人的代码作业[7]。对編程作业研究分析发现,有1%- 10%代码为抄袭代码,且这个比例正在逐年增长[8],可见代码抄袭现象非常普遍。为了达到抄袭代码且不被发现的目的,出现了各种代码混淆技术。
  为了全面分析和对比当前已有的代码混淆技术,本文对已有的代码混淆技术进行分类和总结,然后根据已有的常见代码混淆手段对其进行了解释和举例说明。
  1  代码混淆概述
  代码混淆指使用一定的代码转换手段把一个代码转换成另一个代码的技术, 并且这两个代码在可观测行为上能够保持语义等价[9]。代码混淆的目的是隐藏程序的逻辑,以达到抄袭目的或者使混淆后的代码更加难以理解和分析[10]。
  一般可在源代码、字节码或者机器码上进行代码混淆。代码混淆可以人工进行混淆,也可使用代码混淆工具进行自动混淆,常见的代码混淆工具有Sandmark、DexGuard、Upx、ProGuard等[11]。
  代码混淆技术一般从代码布局、语法变换[12]以及语义变换三个方面来分类。目前常见的代码混淆技术主要为代码布局和语法变换两类,很少涉及到语义信息的变换。语义信息变换的代码混淆付出的代价比较大,且容易出现错误,所以较少有涉及语义信息的代码抄袭。此外,涉及语义信息变换的混淆代码,也是目前已有的代码相似度检测工具无法检测出来的。
  2  代码混淆技术的发展与分类
  2.1  代码混淆手段的发展
  代码混淆技术等相关概念最先是由Collberg[13]提出,并进行性能评估和分类,提出代码混淆技术分为预防混淆技术、外形混淆技术、控制流混淆技术以及数据混淆技术。其中控制流混淆技术和数据混淆技术是当前比较流行的混淆技术,两者抗反编译和恶意逆向工程攻击能力较强。
  Faidhi[14]在论文中提出,根据代码抄袭所付出的代价不断增加,可以把代码抄袭手段分为以下7种:(1)完全不更改;(2)只修改注释;(3)更换标识符;(4)更改变量的位置;(5)过程组合;     (6)更换代码语句的顺序;(7)等价控制结构变换。
  Joy[15]提出代码混淆方法可以分为词法变化和结构变化两类,前者包括代码格式、行数、注释以及变量名的变化;后者主要包括控制结构语句和操作符的替换、在不更改程序结果的前提下调整语句的顺序。Whale[16]在论文中另外提出了等价语句和数据类型的变换,添加冗余代码等代码混淆手段。
  Jones[17]总结了10种常见的代码抄袭手段,除以上几种另外还提出更改代码块顺序,并根据抄袭所付出的努力从易到难进行了一个系统的排序。文献[18]在进行代码相似度检测时提出了常量替换和表达式拆分两种代码混淆手段。文献[19]新提出了生成新函数这种较复杂的代码混淆手段。
  Myles[20]在进行软件相似度检测时也提出生成新函数这种代码混淆手段,另外还提到了循环展开代码混淆手段,循环展开是指通过复制循环体来减少循环的次数。文献[21]首次提出了不透明谓词这种代码混淆手段,不透明谓词是一种控制流混淆技术,指在不改变程序结果的基础上在原程序中加入了大量的不可达路径或者是不可达分支,属于增加冗余代码的一种。   2.2  代码混淆手段总结分类
  本文根据代码抄袭时常用的几种抄袭手段,进行了总结和完善。常见的代码抄袭手段从易到难主要分为以下14种,如图1所示:(1)完全拷贝;    (2)修改注释;(3)重新排版;(4)标识符重命名;(5)更改代码块排序;(6)调整代码块内语句的顺序;(7)常量替换;(8)改变表达式中操作符或操作数顺序;(9)改变数据类型;(10)增加冗余代码;(11)表达式拆分;(12)控制结构等价变换;    (13)循环展开;(14)函数生成和合并。为了更准确的统计现有的代码混淆手段,本论文对这14种手段的一些混淆手段进行了细化。下面为14种代码混淆手段的详细介绍以及举例说明。
  (1)完全拷贝
  完全拷贝是指拷贝代码的一部分或者一个完整的程序,且不做任何的修改。
  (2)修改注释
  修改注释是指完全拷贝代码,对代码不做任何修改,为了达到混淆的目的对代码中的注释进行  修改。
  (3)重新排版
  重新排版是指完全拷贝代码后,不修改代码,对代码进行空格或者空行,以调整代码的格式。
  (4)标识符重命名
  标识符重命名指统一更改代码中的变量名或函数名,属于词法变换。如图1所示,图1(1)为一段原代码,图1(2)为使用标识符重命名混淆手段更改后的代码。
  (5)更改代码块排序
  更改代码块排序是指在不改变代码运行顺序的前提下,以基本块为单位更换代码的顺序,以达到代码混淆的目的。基本块是指代码顺序执行的语句序列,且只有一个入口和一个出口,入口就是其第—个语句,出口是其最后一个语句,执行时只从其入口进入,从其出口退出。如图2所示,图2(1)有if分支和for循环两个基本块,图2(2)中两个基本块交换顺序进行混淆,但是并不影响程序的运行结果。
  (6)调整代码块内语句的顺序
  调整代码块内语句的顺序是对基本块中的语句进行调换顺序,且不影响程序执行结果。如图3所示,更改几个赋值语句的顺序。
  (7)常量替换
  常量是不随时间变化的某些量的固定信息,也可以是某一数值的字符或字符串,属于指令的一部分。如图4所示,把原代码中的常量100替换为101,且保证更改后不影响程序结果。
  (8)改变表达式中操作符或操作数顺序
  代码中表达式与数学中表达式的定义相似,且具有一定的值,用操作符把常数和变量连接起来的代数式。例如,m=2+3*4+5为一个表达式,为了混淆代码,可以把这个表达式更改为m=3*4+5+2,程序的运行结果不变,但是表达式中的操作符和操作数的顺序改变了。
  (9)改变数据类型
  改变数据类型指在不改变代码运行结果的前提下更改部分变量的数据类型,以达到混淆代码的目的。如图5所示,原代码中的变量为int类型,更改后为String类型,代码运行结果不改变。
  (10)增加冗余代码
  增加冗余代码指在代码中加入不必要的、对程序没有影响的代码段。增加冗余代码分为增加有数据依赖的冗余代码和增加无数据依赖的冗余代码,后者较前者更容易操作。有数据依赖的冗余代码和无数据依赖的冗余代码又都包含增加顺序语句、增加可达分支和不透明谓词。增加顺序语句是指在代码中加入可以运行但不影响结果的顺序执行的代码;增加可达分支是指在不改变结果的前提下加入冗余的可执行的分支语句;不透明谓词是指在不改变程序结果的基础上在原程序中加入了大量的不可达路径或不可达分支。如图6所示,为不透明谓词代码混淆示例,在图6(2)中加入一个if分支,不运行且不影响程序的运行结果。
  (11)表达式拆分
  表达式拆分指为了混淆代码将一个复杂的表达式拆分成多个简单的表達式。例如可以把表达式a=4*(b+3)拆分成c=b+3和a=4*c两个简单的表达式,以达到混淆代码的目的。
  (12)控制结构等价变换
  控制结构等价变换指在不影响程序运行结果的前提下,用相同功能的控制结构替换代码中的控制结构,以进行代码混淆。如图7所示,用while循环结构替换原代码中的for循环结构,且代码语义不变。
  (13)循环展开
  循环展开可以分为部分展开和全部展开。循环部分展开是通过复制部分循环体减少循环的次数以达到混淆代码的目的,代码结构不变;循环全部展开是通过复制循环体来代替整个循环结构,代码结构发生变化。如图8所示,(1)为原代码,(2)中把原代码中的循环结构进行了部分展开,代码结构不变;(3)把原代码中的循环结构通过复制循环体的形式,全部展开,循环结构变成了多个赋值语句,但是程序运行结果并没有改变。
  (14)函数生成和合并
  函数生成指将代码中特定功能的代码块封装为一个新的函数,用以调用。函数合并指将方法的调用语句替换为方法的具体实现语句。如图9所示,把原代码中的if分支代码块作为一个新的函数方法,进行调用,以达到混淆代码的目的,代码结构发生变化,但是不影响代码运行结果。
  3  结束语
  针对代码混淆技术,本文首先阐述了代码混淆手段的发展进程,然后详细介绍了当前常用的代码混淆手段,并对其中一些混淆手段进行了细化,然后通过举例明确解释了每种代码混淆手段。
  代码混淆是软件工程领域一项实用的技术,软件技术的发展会催生出更多复杂的代码混淆手段,使得代码混淆技术的研究也面临新的问题和挑战,需要学术界和企业界们对代码混淆问题进行更深一步的研究。
  参考文献
  Collberg C, Thomborson C, Low D. Manufacturing cheap, resilient, and stealthy opaque constructs[C]//Proceedings of the 25th ACM SIGPLAN-SIGACT symposium on Principles of programming languages. ACM, 1998: 184-196.   印杰, 李千目. 软件代码漏洞的电子取证技术综述[J]. 软件, 2015, 36(12): 49-59.
  耿达. 基于物联网楼房照明系统设计和实现[J]. 软件, 2018, 39(12): 222-225.
  丁小盼, 周浩, 贺珊, 等. 基于OpenStack 的云测试平台及其性能分析研究[J]. 软件, 2015, 36(1): 6-11.
  金昱东. 一种基于ReactNative 的代码压缩与动态加载的实现方法[J]. 软件, 2016, 37(02): 81-84.
  熊浩, 晏海华, 郭涛, 等。代码相似性检测技术: 研究综述[J]. 计算机科学, 2010, 37(8): 9-14.
  Chuda D, Navrat P, Kovacova B, et al. The issue of (software) plagiarism: A student view[J]. IEEE Transactions on Education, 2011, 55(1): 22-28.
  Georgina C, Mike J. Source-code plagiarism: A UK academic perspective[R]. Research Report RR-422, Department of Computer Science, University of Warwick, 2006.
  Wu Z, Gianvecchio S, Xie M, et al. Mimimorphism: A new approach to binary code obfuscation[C]//Proceedings of the 17th ACM conference on Computer and communications security. ACM, 2010: 536-546.
  Collberg C, Thomborson C, Low D. A taxonomy of obfuscating transformations[R]. Department of Computer Science, The University of Auckland, New Zealand, 1997.
  田振洲, 劉烃, 郑庆华, 等.软件抄袭检测研究综述[J]. 信息安全学报, 2016, 1(3): 52-76.
  马培, 翟高寿. 面向硬件瞬时故障的Linux 设备驱动敏感代码的自动分析与检测[J]. 软件, 2015, 36(12): 09-15.
  Collberg C, Thomborson C, Low D. A taxonomy of obfuscating transformations[R]. Department of Computer Science, The University of Auckland, New Zealand, 1997.
  Faidhi J A W, Robinson S K. An empirical approach for detecting program similarity and plagiarism within a university programming environment[J]. Computers & Education, 1987, 11(1): 11-19.
  Joy M, Luck M. Plagiarism in programming assignments[J]. IEEE Transactions on education, 1999, 42(2): 129-133.
  Whale G. Detection of plagiarism in student programs[C]// Proceedings of the 9th Australian Computer Science Conference. Australian Computer Society, 1986: 231-241.
  Jones E L. Metrics based plagiarism monitoring[J]. Proceedings of the 6th Annual CCSC Northeastern Conferene on the Journal of Computing in Small Colleges, 2001, 16(4): 253-261.
  赵长海, 晏海华, 金茂忠. 基于编译和反汇编的程序相似性检测方法[J]. 北京航空航天大学学报, 2008, 34(6).
  Ji J H, Woo G, Cho H G. A source code linearization technique for detecting plagiarized programs[C]//ACM SIGCSE Bulletin. ACM, 2007, 39(3): 73-77.
  Myles G, Collberg C. Detecting software theft via whole program path birthmarks[C]//International Conference on Information Security. Springer, Berlin, Heidelberg, 2004: 404-415.
  Hada S. Zero-knowledge and code obfuscation[C]//International Conference on the Theory and Application of Cryptology and Information Security. Springer, Berlin, Heidelberg, 2000: 443-457.
  Roundy K A, Miller B P. Binary-code obfuscations in prevalent packer tools[J]. ACM Computing Surveys (CSUR), 2013, 46(1): 4.
转载注明来源:https://www.xzbu.com/8/view-15233565.htm