专利名称:对计算机程序代码的执行轨迹进行模糊化的制作方法
技术领域:
本发明涉及计算机程序代码的篡改保护,特别是通过对计算机程
序代码的执行轨迹(execution trace )进行才莫糊化(obfuscate)。
背景技术:
软件篡改是一种攻击方式,其目的在于改变一件软件的运行方式以便为攻击者带来违法利益。篡改的目标可以是避开/禁用复制保护或安全机制以提取秘密或受版权保护的材料,或者引入诸如计算机病毒之类的恶意代码。
在许多情况下,违法利益会为软件生产者带来实质性的财务损失。因此,攻击者和软件供应商预期会分别努力破坏和改进针对软件篡改的保护机制。在移动电话的背景下,SIM锁定或诸如数字权利管理(DRM)之类的其它敏感软件组件的保护特别受到关注。此外,其它软件实体的篡改保护和/或出于其它目的和/或与之相结合使用会是
有益的。
为了修改软件组件,攻击者通常必须至少对软件组件如何工作有部分了解。通过使得反向工程更加困难,软件篡改会由此被延迟(如果没有被阻止的话)。使得软件更加难以分析的变换对于这一目的是有用的;这样的变换通常被称作模糊化(obfuscation)。
用于对软件进行反向工程的技术可大致分为两组技术静态(或"离线")代码分析和动态(或"在线(live),,)代码分析。当执行动态分析时,软件在其执行时被观察。相反,静态分析通常限于程
的一种技术是执行轨迹的比较。'、^'一、^ 一 "
令的^储器地址的序列:一 由此可通过运行程;来收集执行轨:,;列如
通过使用特定硬件支持(所谓的轨迹緩冲器)或通过基于软件的地址记录。使用程序的执行轨迹和可执行代码,能够据此重建所执行指令的实际序列。
5通过提供两个激励集合并且对所产生的执行轨迹中的差异进行比较,攻击者能够获得对软件组件的了解。特别地,执行轨迹的比较
可以识别程序的关键决策点。在移动设备的SIM锁定和DRM解决方案的背景下,关键决策点的示例是用于校正签名或校验和的测试。例如,攻击者可以通过比较两个不同移动设备(例如,运营商锁定设备和未被运营商锁定的设备)所运行的软件的执行轨迹,以便获得有关程序的哪些部分与SIM锁定功能相关的信息。
之前使通过动态分析进行反向工程更为困难的尝试包括尝试限制攻击者在软件执行时对其进行观察的机会。然而,这样的对抗措施
这种对抗措施的 一 个示例包括对可执行代码进行加密以及使用将代码的解密和执行相结合的特定硬件。即使适当实施的基于硬件的解密技术能够提供良好的保护,但是这种保护也是以额外的特定硬件
为代价来实现的。
被称为反调试器(anti-debugger)技术的另 一种方法的目的在于使得观察特定调试器中的程序执行的过程复杂化。在一些平台上,执行代码能够向操作系统查询附于该过程的可能调试器,并且例如如果是这种情况就终止。另 一种选择是对调试器所使用的技术进行干扰,例如通过篡改断点的设置。然而,反调试器技术专用于特定调制器而且并不提供通用的篡改保护技术。此外,在调试嵌入式系统时通常使用指令集激励器和硬件支持的调试器,由此降低了反调试器技术的实际有用性。此外,使用完全以硬件实施的轨迹缓沖器仍然可以收集执行轨迹。
模糊化是一种用来使代码复杂化的技术。模糊化使得代码在其被反编译时更加难以被理解,但是其通常对于代码的功能没有影响。能够使用程序的模糊化通过使得程序更加难以进行反向工程来对它们进行保护。
已经提出了多种模糊化技术。由Tatsuya Toyofuku等人在TEnokido等(Eds ) : EUC Workshops 2005. LNCS 3823,第916-925页发表的文章"Program Obfuscation Scheme Using Random Numbers toComplicate Control Flow"提出了一种这样的模糊化机制。然而,该方法被报告为易于受到动态分析的攻击。WOO 1/69355公开了一种用于通过在程序中插入附加例程以及多个随机建立的附加控制流来向计算机程序中嵌入水印的方法,由此产生具有相应控制流的程序的特定(即带有水印的)版本。
美国专利6,668,325 ,口 Christian S. Collberg和Clark 丁homborson的文章 "Watermarking, Tamper-proofing, and Obfuscation - Tools forSoftware protection" , IEEE Transactions on Software engineering, 28:6(2002年6月)描述了多种模糊化变换。在这样的变换上引入冗余的if语句。所述if语句的条件是所谓的不透明谓词(opaque predicate ),其具有在程序被模糊化但是难以通过代码的静态分析来识别时已知的某种属性。例如永远评估为例如TRUE (真)的不透明谓词可以用在这样的if语句中。结果,在模糊化时知道仅有if语句的一个分支将会被执行。因此,在模糊化期间,可以将待执行的代码插入该分支,而决不会执行的其它分支可包括某种任意的"虚设(dummy)"代码。以上现有技术文档进一步描述了使用其结果可以是TRUE或FALSE(假)的不透明谓词以便选择给定计算任务的两种可替换实例之一 。然而,即使这种技术使得代码的静态分析更为困难,但是其并未有效增加试图识别关键决策点的动态分析的难度。
美国专利6,668,325中所公开的 一种特定变换被称作有序变换(ordering transformation)并且包括对源代码项目(表达式内的项目、基本块内的语句等)的随机化放置,从而防止代码的反向工程。对源代码项目的重排序基于依赖性分析来执行,所述依赖性分析被执行以确定哪些重排序在技术上是有效的。因此,该现有技术的变换过程生成待执行的源代码的 一种技术上可能的重排序。结果所产生的可执行代码将表示该所生成的排序。
然而,其仍然存在以下一般问题,4是供了一种有效的方法,用于对程序代码进行模糊化以便使得更加难以通过分析程序的执行轨迹来获得有用信息,例如以便识别感兴趣的决策点和/或其它关键点。
发明内容
通过一种计算机实现的生成篡改保护的计算机程序代码的方法来解决以上和其它问题,所述方法包括
-获得计算机程序代码的表示,所述计算机程序代码适于使得数据处理系统以第 一 执行次序执行多个计算任务,每个计算任务在所述
计算机程序代码的表示中由至少 一个程序语句来表示; -获得所述计算任务的多个可替换执行次序; -生成程序代码的可执行表示,其适于使得数据处理系统从所述
执行;1序执行计算任务。、 "、、'''
这里所描述的方法实施例提供了软件组件的程序代码(例如源代
码)到经修改代码的变换,当所述代码被执行时,这产生经有效地模
糊化的执行轨迹。
特别地,经变换的代码使得执行结果代码的计算机在多个排序中
选择一种排序,即在运行时选择多种可能排序之一,而不是在变换和
代码生成过程期间事先确定为一种特定排序。因此,由于排序可以因 执行而异,所以在利用不同输入来执行代码时难以获得有用信息(如 果不是不可能的话),因此由于在使用不同输入执行软件时执行轨迹 中的差异而防止了关键决策点可被轻易检测到。
因此,这里所描述的方法实施例以这样的方式对软件组件的输入 表示进行变换增加比较执行轨迹所需的努力。相关差异被隐藏在大 量表面上随机的差异之中。因此,使得以获得软件组件的知识为目的 的包括比较执行轨迹的篡改攻击的初始阶段明显更为困难。因此,这 里所描述的方法针对基于动态分析的攻击提供了对程序代码的有效 保护。
程序代码的表示可以包括适当的输入表示,其中可以识别不同计 算任务。典型地,程序代码的表示包括计算任务的表示,所述计算任 务可作为诸如编译器、链接器、解释器等之类的一个或多个代码生成 或代码解释工具的输入。因此,程序代码的表示可以由数据处理系统 例如利用代码解释器而被直接执行,或者其可以例如利用编译器和/ 或链接器而被转换成可执行的形式。适当的输入表示的示例包括适当 编程语言、对象代码等的源代码。
根据这里所描述的方法的变换可以被视为计算任务的临时执行 次序的模糊化,而不是现有技术的模糊化技术所使用的源代码构造的 空间重排序。因此,这里所描述的方法实施例为若干甚至所有安装提 供了相同(或者至少基本上相同,原因在于随机种子(seed)会因安装而异)代码映像的变化的临时执行次序。
这里所使用的术语"程序语句"意在包括构造编程语言的单元, 尤其是这种构造的最小单元。程序语句示例的类型示例包括定义、声 明、指定、条件语句、循环和函数/过程调用。条件程序语句通常使得 程序有选择地执行一组可替换程序分支之一。每个分支可包括一个或
多个程序语句。条件程序语句的示例包括if语句、case语句等。
将会意识到的是,执行计算任务的第一执行次序可依赖于输入表 示和/或可执行程序代码指令生成期间的 一 个或多个处理步骤(例如, 编译步骤)。例如,输入表示可包括程序语句序列,并且该序列可确
定执行的顺序次序(sequential order)。第一执行次序还可依赖于在 程序执行期间接收的程序输入和/或其它任务的输出(例如,在条件程 序语句的情况下)。执行次序可以是计算任务的顺序次序。另一方面, 在一些实施例中, 一些计算任务可以同时执行或者甚至彼此同步执 行,例如作为多线程程序执行的两个或更多线程。将会意识到的是, 可以在不改变程序的总体行为的情况下改变至少一些计算任务的执 行次序。然而,还会意识到的是,在不改变程序行为的情况下可能无 法交换一些任务的相对次序。
这里所使用的术语"计算任务"意在包括可由一个或多个计算机 指令表示的计算步骤的集合。连带地,软件组件的计算任务构成软件 组件所执行的全部计算/操作。出于本说明书的目的,每个计算任务可 以是细粒度的(fine-grained),例如源代码语言的单个程序语句,或 者是粗粒度的(coarse-grained),例如包括若干语句的函数/过程/子 例程,或者甚至是若干函数/过程/子例程。
获得多个可替换执行次序可以包括通过程序分析工具对程序代 码的输入表示进行处理,从而识别多个计算任务以及它们彼此的相依 性。例如,该过程可以由自动程序分析工具来执行,或者其可以至少 部分基于用户输入来执行。将要意识到的是,存在如函数语言和数据 流语言之类的源语言,其尤其适于自动或半自动地识别计算任务和可 替换执行次序,原因在于用于重排序的机会特别容易识别。在一些实 施例中,分析工具可以提供适当的用户接口 ,允许用户识别计算任务 以及可能的可替换执行次序。将会意识到的是,可替换执行次序的集 合可包括第一执行次序。
9在一些实施例中,当所述程序代码由所述数据处理系统执行时, 每个可替换执行次序适于使得数据处理系统产生与第一执行次序相 同的程序输出。因此,程序代码的变换是保留语义的
(semantic-preserving),即对计算机程序所创建的程序输出没有影响。 不应当被保留语义的变换直接或间接影响的程序语句也被称作提供 程序的关键效果(critical effect)。与程序环境进行交互的所有程序语 句都可以被视为对程序输出有所贡献。
这里所使用的术语"程序输出"意在包括程序执行期间的任意可 观察行为,例如,能被所使用的编程语言所指定并且能被用户、另一 计算机程序、另一设备等所观察/注意到的任意程序行为。程序输出的 示例包括可经由任意适当的输出设备通过数据接口等而输出的数值 输出、文本输出、二进制输出、输出信号、可视(例如图形)输出、 可听输出等,所述输出设备如计算机屏幕、打印机、存储介质、通信 接口等。
因此,提供了一种有效的方法,其确保了经模糊化的代码具有与 输入代码相同的效果/产生与输入代码相同的输出。 在一个实施例中,所述方法包4舌
-以预定的顺序次序接收指示多个程序语句的输入表示; -对所述程序语句进行分组以获得多个计算任务; -识别多个可替换执行次序。
可替换执行次序可以通过用于表示依赖性关系的任意适当的数 据结构来表示,所述依赖性关系指定保证语义等同所需的对执行次序 的约束。所述依赖性关系可以通过用于依赖性分析的任意适当方法来确定。
对执行次序的约束可以有效地通过指示前趋图(precedence graph)的数据结构来表示,所述前趋图包括指示计算任务的节点以及 指示计算任务的前趋(precedence)的次序的边。所述前趋图可以是 有向图,例如有向非循环图。因此,所述前趋图是可以根据其来选择 有效执行次序的前趋约束的高效表示。
在一些实施例中,生成程序代码的可执行表示进一 步包括将计算 机可执行指令包含在程序代码的可执行表示中,当程序代码由数据处 理系统所执行时,其适于使得所述数据处理系统执行以下任务a) 执行计算任务中的一个初始任务;
b) 从前驱图中的所执行计算任务的可替换后继(successor)集合 中选择后续计算任务,该前驱图指示对计算任务的执行次序所施加的 前趋约束集合;
c) 执行所选择的计算任务;
d) 重复步骤b)和c)直至已经执行了所有计算任务。
在 一 些实施例中,生成程序代码的可执行表示进一 步包括将计算 机可执行指令包含在程序代码的可执行表示中,其适于使得数据处理 系统保持(maintain )执行状态,所述执行状态由留待执行的计算任 务的子集以及留待执行并且其在前趋图中的前导(predecessor)都已 经被执行的计算任务的子集中的至少一个来定义。因此,为程序代码 提供了有效的机制以使得数据处理系统在给定前趋约束下以随机化 次序执行任务。
可以根据随枳4t据项序列来确定随才几化冲丸行次序。如本领域中已 知的,随机化数据项序列可以由伪随机数生成器来确定,所述伪随机 数生成器即使用算术来生成近似随机数属性的数序列的算法,或者可 以由本领域中已知的用于生成向观察者表现出随机性的数据项序列 的任意其它适当机制来确定。
例如,当通过诸如伪随机数生成器之类的用于生成随机化数据项 序列的函数来确定随机化数据项序列时,执行状态可进一步包括用于 初始化所述用于生成随机化数据项序列的函数的种子数据项。
作为选择,随机化次序可由硬件随机数生成器来生成,所述硬件 随机数生成器即用于例如基于诸如热噪声、光电效应或其它量子现象 之类的适当微观机理而从适当物理过程生成随机数的设备、装置或电 路。
在一些实施例中,所述方法包括将可执行指令插入每个计算任务 中以用于执行选择后续计算任务的步骤。因此,通过把对计算任务进 行排序并且更新程序状态的控制逻辑集成到单独任务中,该功能得以 被分布而不是作为集中函数而提供,由此使得对手更加难以对负责选 择执行次序并且以所选择次序调用任务的程序代码部分进行反向工 程。
例如,每个任务可以被实现为编程语言的函数/过程/子例程或者其它适当结构单元,其中每个函数/过程/子例程在给定的前趋约束下 调用后继函数/过程/子例程。在可替换实施例中,所述方法包括在程 序代码由数据处理系统执行时将编程语言的至少 一 个单独函数/过程/ 子例程或者其它适当结构实体插入到适于执行计算任务排序的程序 代码中。因此,在这样的可替换实施例中,任务的排序由作为软件组 件的实际任务的辅助的单独函数来执行。
在一些实施例中,所述方法进一步包括生成计算任务的多个实例
的可执行指令;并且选择计算任务包括选择计算任务的多个实例之
一。以这种方式,不仅是执行次序,而且从其执行代码的地址也会在 软件组件的执行之间发生变化,由此进一步使得执行轨迹的比较复杂 化。该方法可以进一步包括对所述多个实例中的至少一个执行一个或 多个模糊化变换。从而,通过将不同的保留语义的变换应用于各种实
例,实现了额外的多样性(diversity)。结果,不仅地址有所变化, 而且从这些地址取出的指令也有所变化,这进一步使得执行轨迹的比 较复杂化。
在一些实施例中,例如通过以不同种子数据项发起的或者硬件随 机数生成器所生成的各自随机化次序执行计算任务而对给定安装软 件组件的每次执行都会产生执行轨迹,其是唯一的(至少概率很高)。
在可替换实施例中,生成程序代码的可执行表示包括生成包括
代码在内的程序代码的可执行表示。因此,可以使得软件组件的每次
装而变化r特别地,可以使得所述执:轨迹:于特定:装或安装组是 唯一的。
个可执行表示,程序代码的每个可执行表示包括指示相应安装的各自 种子数据项。特别地,如果可能的执行次序的数目相对有限,则生成 对于软件组件的每次安装唯一的固定轨迹具有防止通过多次执行相 同安装来对变化特性进行分析的优势。作为代替,对于某一分析而言 将需要大量的安装并且因此需要付出大得多的努力。
这里所使用的术语软件组件的安装是指例如以 一个或多个可执
12行文件、安装包等的形式安装在或至少可安装在数据处理系统上的软 件的可执行表示的单独副本。例如,安装可被实现为计算机可读介质,
诸如其上存储有软件组件的副本的CDROM,或者存储在服务器计算 机上的可下载文件。
在一些实施例中,所述方法包括生成程序代码的多个可执行表 示,每个可执行表示包括用于使得数据处理系统选择不同的随机化执 行次序的程序代码。因此,可以生成每个所安装的软件组件以便具有 唯一的执行轨迹。在这种情况下,相同安装的重复执行产生相同的执 行轨迹,这与任意其它安装的轨迹都有所不同。特别地,将会意识到 的是,这可被用来使得运营商锁定的移动电话和未锁定移动电话的执 行轨迹不相似,而两个安装的重复执行并不提供执行轨迹的变化特性 的额外知识。
注意到以上和以下所描述的方法的特征可以以软件来实施,并且 在数据处理设备或者通过执行诸如计算机可执行指令之类的程序代 码装置所引起的其它处理装置上执行。这里和此后,术语处理装置包 括适于执行以上功能的任意电路和/或设备。特别地,以上术语包括通 用或专用的可编程微处理器、数字信号处理器(DSP)、专用集成电 路(ASIC)、可编程序逻辑阵列(PLA)、现场可编程门阵列(FPGA)、 专用电路等或者其组合。
例如,程序代码装置可以从存储介质或经由计算机网络从另 一计 算机加载到诸如RAM (随机存取存储器)之类的存储器中。作为选 择,所描述的特征可通过硬连线电路而不是软件来实施,或者通过硬 件电路与软件的组合来实施。
本发明涉及包括以上和以下所描述的方法、相应设备和计算才几程 序在内的不同方面,它们均提供结合以上所提到的方法所描述的 一 个 或多个好处和优势,并且均具有与结合以上所提到的方法所描述的实 施例相对应的一个或多个实施例。
特别地,根据一个方面, 一种数据处理系统被适当地配置为执行 以上和以下所描述的方法的步骤。
根据另一方面,一种计算机程序产品包括计算机可执行指令,当 在数据处理系统上执行时,其适于使得所述数据处理系统执行以上和 以下所描述的方法。在一些实施例中,所述计算机程序产品被实现为
13其上存储有计算机可执行指令的计算机可读介质。例如,所述计算机 可读介质可以是其上存储有计算机可执行指令的紧致盘(CD)、光盘、 磁盘、磁存储介质、记忆棒等。例如,所述计算机可读介质可以在其 上存储用于对程序代码进行篡改保护的软件应用程序。在其它实施例 中,所述计算机程序产品被实现为数据信号,例如适当调制的载波信 号。例如,所述计算机可执行指令可以被提供以用于经由计算机网络 从服务器计算机进行下载。
在 一 些实施例中,所述计算机程序产品可实现为源代码到源代码 的变换器,即接收一个或多个输入源代码模块并生成一个或多个可由 传统编译器进行编译的输出源代码模块的计算机程序。在 一 些实施例 中,所述计算机程序产品可集成到编译器中,即其可以被实现为软件 编译器,所述软件编译器包括适于使得数据处理系统将以上和以下所
描述的方法作为编译器所执行的许多趟编译(a number of compilation pass)之一来执行的功能。因此,提供了用于篡改保护和编译的集成 软件工具。此外,由于这里所描述的篡改保护的实施例包括一些如传
用相应的软件功能,由此提供高效的软件实施方式。
出于本说明书的目的,术语存储装置/设备和计算机可读介质意在 包括任意的适当存储介质、设备或电路,例如只读存储器(ROM)、 随机存取存储器(RAM )、闪存、可擦除可编程只读存储器(EPROM )、 易失性或非易失性存储器、光存储设备、磁存储设备、磁盘、CD、硬 盘等。
根据以下参考附图所描述的实施例,以上和其它方面将是显而易 见的并且通过所述实施例而被阐明,其中
图1示出了用于对程序代码进行篡改保护的过程的示意性框图。 图2示意性图示了前趋图的示例。
图3示意性图示了产生包括集中任务选择和分派(dispatch)函数 的经变换源代码的源代码变换的示例。
图4示意性图示了产生包括分布式任务选择和分派函数的经变换 源代码的源代码变换的示例。图5示意性图示了产生包括计算任务的多个实例的经变换源代码 的源代码变换的另 一 示例。
图6示出了用于对程序代码进行篡改保护的系统的示意性框图。
具体实施例方式
图1示出了用于对程序代码进行篡改保护的过程的示意性框图。
该过程接收源代码101。典型地,源代码101采用程序员已在其 中典型地以诸如C、 C++、 Java等之类的正式编程语言编写了计算机 程序的形式。所述源代码能够由编译器自动编译为目标代码或机器代 码或者由解释器来执行。源代码101可以被表示为一个或多个文本文 档或者任意其它适当的数字表示。即使可以使用以任意适当编程语言 所编写的源代码作为输入,但是将会意识到的是, 一些源代码语言尤 其适于识别重排序的机会,例如函数语言和数据流语言。
函数语言通常遵循将计算视为数学函数的评估(evaluation)并且 避免状态和易变数据的编程范例。与强调状态改变的命令式编程风格 相比,其强调函数的应用。函数语言的示例包括APL、Erlang、 Haskell 、 Lisp、 ML和Scheme 。
数据流语言是实施数据流原则和体系结构的编程语言,并且将程 序(不是在物理上就是在概念上)模型化为在操作之间流动的数据的 有向图。数据流语言共享函数语言的一些特征,并且通常被研发以便 为更适于数字处理的语言带来一些函数概念。在数据流语言中,操作 典型地被视为具有输入和输出的"黑盒",其全部都总是明确定义的。 凄t才居流i吾言的示例包4舌Lustre 、 Ptolemy/CAL 、 LabView和Simulink 。
作为选择,篡改保护过程可接收不同类型的输入表示,其中能够 识别计算任务及其相依性,例如,目标代码。
源代码101被馈入代码分析模块103中。所述代码分析模块对源 代码进行解析并且识别一组计算任务以及它们彼此的相依性,尤其是 在计算任务的执行次序上所施加的前趋约束。代码分析模块103将前 趋约束表示为前趋图,其示例如图2所示。
图2图示了前趋图的示例。前趋图包括表示各个计算任务的节点 以及表示任务之间的前趋约束的边。在图2的示例中, 一般指定为200 的前趋图是包括标记为从A至F的节点的有向非循环图,每个节点表示相应的计算任务。将会意识到的是,所述前趋图可包括与给定软件组件中所识别的计算任务的数量相对应的任意数量的节点。节点A-F
通过单向边201而连接,其中每条边连接两个节点并且标识所述两个
节点之间的前趋约束,即计算任务之一 必须在其它计算任务可以执行之前被执行。由此每条边从前导节点指向有效的后继节点。例如,在
图2所示的示例中,任务E的执行要求前导任务B和D已经被执行。因此,任务A-F的以下执行次序是满足前趋图200所施加的前趋约束的扭J于4九迹的示例
执行轨迹弁1:
A, B, C, D, E, F
执行轨迹弁2:
A, D, B, E, C, F
执行轨迹#3:
A, D, F, B, E, C
例如,代码分析模块103可以提供允许用户识别计算任务及其有效排序的用户接口。可替换地或除此之外(例如,基于作为开始点的用户定义的任务),代码分析模块103可以自动或者至少半自动地识别有效的任务排序(即,前趋图),例如通过生成对任务的初始划分并且通过生成相应前趋图,并且任选地通过提供允许用户对计算任务和/或有效排序的选择进行修改的用户接口 。
代码分析模块103可以使用本领域中已知的任意适当的用于对源代码进行解析的技术,例如传统编译器在解析源代码以便识别相应编程语言(如函数、条件、循环等)的结构组件时所使用的技术的子集。所述代码分析模块可以处理全部输入代码或者仅处理其子集。
特别地,代码分析模块103可以采用程序分析领域中已知的任意适当的用于依赖性分析并且产生前趋图或者指定对执行次序的约束的所识别依赖性关系的另 一 种适当表示的技术,所述约束可以是保证语义等同性所要求的。这样的4支术示例例如在Ken Kennedy & RandyAllen ( 2001 ) , Morgan Kaufmann的"Optimizing Compilers for ModernArchitectures: A Dependence-based Approach" 中有所描述。
通常,依赖性分析产生语句和/或指令之间的执行次序约束。例如,如果语句SI必须在语句S2之前执行,就可以说语句S2依赖于语句说明书第13/19页Sl。
函数语言中缺少状态会显著促进依赖性分析。在纯函数程序中,
不存在侧放作用(side effect),即函数仅依赖于其变元。例如,假设A至F为纯函数,则以下程序产生如图2所示的前趋图
a=A(x)
b=B(a)
c=C(b)
d=D(a)
e=E(b, d)
f=F(d)
如以上所提到的,可以对程度不同的细粒度任务执行依赖性分析。这些方法中的一些可以完全自动执行,而其它则需要一定程度的用户输入。
例如,对于诸如C、 C+十和Java之类的命令式语言而言,存在若干公知的依赖性分析方法和细粒度前趋图,例如以便与指令调度以及循环的矢量化或并行化结合使用。
术。识别无侧放作用的(、"純")函数可被认为》是这种分析的特殊情况。
代码分析模块103将与所识别的计算任务相关的信息104(例如,以指向其各自在代码中的位置的指针的形式)和所生成的前趋图200转发到代码变换模块105。
特别地,变换模块105在前趋图;OO所卩艮定的前趋约束下;将程序代码插入到执行计算任务的选择和调用过程的源代码中。所述变换模块可以进 一 步修改与各个任务相对应的源代码,例如通过插入用于返回i 'J单独代码选择和分派函数的代码或者通过插入用于选择和调用后继任务的代码。此外,所述变换模块可以将与各个计算任务相对应的代码翻译成相应编程语言的预定结构实体。例如,所述变换才莫块可以为每个计算任务生成各自的函数/过程/子例程。
随后可以对经变换的源代码109进行进一步处理,例如编i爭、链接、压缩、编码等。用于对任务进行排序的代码可作为单独的选择和分派函数/过程/子例程被插入,其作为对软件组件的实际任务的辅助,如图3所示。
图3示出了输入源代码模块101、相应源代码模块104 (其中被标记为T1,T2,…,TN的多个计算任务例如已经被代码分析模块103识别)、以及例如由变换模块105所生成的经变换的源代码模块109的示例。所述输入源代码模块包括适于使得数据处理系统执行多个计算任务的源代码301。经变换的源代码模块包括经变换的计算任务Tl',T2',…,TN',以及选择和分派函数310。
所插入的选择和分派函数310可简单地通过在遵循前趋图所限定的前趋约束的同时逐个选择计算任务来对它们进行排序。例如,所述前趋图可由适当初始化的数据结构来表示,或者所述约束可以在所插入的函数310中直接编码。对经变换的计算任务进行修改以使得它们在完成时向选4奪和分派函数310返回程序控制。
选择和分派函数310可以保持所执行程序的状态以便在选择任务的同时保持对前趋的追踪。在一个实施例中,给定程序执行的特定状态,选择和分派函数使用函数^来选择"下一个"任务t。此外,所述选择和分派函数使用函数《在选择了任务t之后更新状态。如果s。表示初始状态且N表示任务总数,则可如以下伪代码所示的那样对任务进行排序,所述伪代码说明了选择和分派函数的示例
S s0
for i=l,2,…,Ndot:= "s)execute task ts:=《(s)
od
因此,当前的状态变量S最初被初始化为初始程序状态s。。之后,循环被执行N次,其中每次迭代都通过执行函数AC (s)选择下 一 个任务
t。接着执行所选择的任务t,并且通过执行函数《来更新程序状态。
将会意识到的是,执行状态的集合以及函数K和《可以以多种方式来定义。在一个实施例中,从用来拓朴归类的标准方法得出它们的
定义(例如,参见Niklaus Wirth的"Algorithms + Data Structures =Programs",第182-189页,Prentice-Hall, Englewood Cliffs,新泽西,1975 ),其被适当修改以便提供对任务的随机化选择。为此,注意到所有有效执行次序与相应前趋图的拓朴排序相对应是有用的。
在一个实施例中,执行状态由三元组(T, Z, r)来表示,其中T表示留待排序的任务的集合(即,前趋图中的节点),Z表示没有前导有待排序的其余任务的集合,并且r表示(伪)随机种子。由此Z是T的子集,其包含用于在迭代过程的下一步骤中执行的候选任务。函数H吏用(伪)随机种子r选择Z中的一个候选。函数《例如以以下方式更新状态
《(T, Z, r) = (T', Z', r') where
T' = T\{t}
Z' = (Z\{t})u {u I uesucc(t), pgT' for all pepred(u)}r' = prng(r)
从任务集合T移除任务t产生留待调度的任务的更新的集合T'。还从用于在算法的下一步骤中执行的候选的集合Z移除任务t,从而产生更新的集合Z'。添加到候选集合中的是前趋图中t的后继u,其所有前导p都已经被执行,即不包括在T'中。通过函数prng更新(伪)随机种子r,所述函数prng实现用于伪随机数生成的合适算法,例如线性同余法(例如,参见D. E. Knuth. The Art of Computer Programming,Volume 2: Seminumerical Algorithms,第三版.Addison-Wesley, 1997,ISBN 0-201-89684-2, Section 3.2.1: The Linear Congr職tial Method,第10-26页)、Mersenne Twister算法(Makoto Matsumoto和TakujiNishimura: "Mersenne twister: a 623-dimensionally equidistributeduniform pseudo-random number generator", ACM Trans. Model. Comput.Simul., vol. 8, nr. 1, 1998,第3-30页,ACM出版社,纽约,NY,美国)或任意其它适当方法。作为选择,可以使用随机数生成硬件或者生成多个其它数据项的(伪)随机序列的任意其它适当方式。
进一步注意到,在以上实施例中,子集T和Z这二者都被保存,由此提供了高效的实施方式。然而将会意识到的是,在可替换实施例中,可以^又保存一个子集,原因在于T可以从Z得出,反之亦然。此外,将会意识到的是,可以使用其它表示,例如,已 被执行的任务集合及其在所执行任务的集合中没有后继的任务的子集。
不同于通过以上所描述的单独函数执行任务选择和调用,如图4 所示,每个任务可以计算其自己的后继。
图4示出了输入源代码模块101、相应源代码模块104 (其中被 标记为Tl, T2,.,.,TN的多个计算任务例如已经被代码分析模块103识 别)、以及例如由变换模块105所生成的经变换的源代码模块109的 示例。经变换的源代码模块包括经变换的计算任务T1', T2',.,.,TN',其 中每一个包括附加的一个或多个用于选择和调用后继任务的程序语 句410-1,410-2, ...,410-N。经变换的源代码模块可进一步包括用于初 始化例如包括随机序列的程序状态并且用于调用经变换的计算任务 中的一个初始任务的初始化例程411。
例如,这样的分布式任务排序可通过使用源到源变换器(例如, 代码变换模块10 5 )将函数k和《的评估集成到每个任务的源代码中来 实现。通过对初始状态应用k在初始化函数411中选择所要执行的第 一个任务,也就是说
execute task ti and provide the state sQ as a parameter
所述变换模块对与每个任务相对应的源代码进行变换,以使得任 务取当前状态s作为输入参数,使用《更新状态s并使用函数/r选择下 一个要执行的任务t。每个任务的源代码由此被补充以源代码410-1,
410-2, ...,410-N以用于在执行任务的正常计算之后^l行后面的步骤。<formula>formula see original document page 20</formula>
注意到,程序状态的更新(例如以上示例中《的评估)能够被专 用于(specialized)特定任务t的背景中,即可以向不同任务插入不同 的函数《。特别地,给定特定前趋图,给定任务的后继以及那些后继 的前导对于变换模块是已知的。因此,所述变换模块可以生成专用函 数《(s)。针对任务t提供专用函数《允许对前趋图的表示进行分布。
如现在将参见图5进行描述的,变换模块105和代码分析模块103可进一步对一个或多个任务的源代码进行复制。以这种方式,所述过 程可以生成相同任务的多个实例。
图5示意性地图示了产生包括计算任务的多个实例的经变换源代 码的源代码变换的另 一 示例。特别地,图5示出了输入源代码模块101、
相应源代码模块104 (其中被标记为Tl, T2,…,TN的多个计算任务例 如已经被代码分析模块103被识别)、以及例如由变换模块105所生 成的经变换的源代码模块109的示例。所述经变换的源代码模块与图 4的经变换的源代码模块类似,并且其包括经变换的计算任务,其中 每一个都包括用于选择和调用后继任务的附加程序语句。所述经转换 的源代码模块进一步包括用于对例如包括随机序列的程序语句进行 初始化并且用于调用经变换的计算任务中的一个初始任务的初始化 例程4U。在图5的示例中,变换模块105生成每个所识别计算任务 的两个实例,以使得来自任务的每个所生成实例与从其中生成该实例 的任务执行相同的计算任务。特别地,变换模块105从任务Tl生成 实例Tla和Tlb,从任务T2生成实例T2a和T2b,并且从任务TN生 成实例TN a和TNb 。即使图5的示例为每个计算任务示出了两个实例, 但是将会意识到的是,所述变换模块可以生成不同数目的实例,例如 三个、四个或者甚至更多的实例。将会进一步意识到的是,所述变换 模块可以为不同计算任务生成不同数目的实例,和/或仅为计算任务的 子集生成多个实例。
所述变换模块可以简单地通过复制原始计算任务的源代码来生 成多个实例。可以在所述变换模块向给定任务的一个或多个实例应用 保留语义的不同变换时实现额外的多样性。结果,不仅地址有所变化, 从这些地址取出的指令也有所变化。可在这种背景下使用的保留语义 的变换的适当示例例如在Alfred V. Aho、 Ravi Sethi和Jeffrey D. Ullman的"Compilers-Principles, Techniques and Tools" , Adison隱Wesley. Reading,美国,1986或者Christian S. Collberg和Clark Thomborson 的 "Watermarking, Tamper-proofing, and Obfuscation — Tools for Software protection" , IEEE Transactions on Software engineering, 28:6 (2002年6月)中有所公开。
所述变换模块可进一步将每个所生成的复制实例表示为前趋图 中的各个节点以获得经修改的前趋图。所插入的用于选择任务的代码
21以这种方式,不仅执行的次序有所变化,而且从其执行代码的存储器 地址也在软件组件的执行之间发生变化。在该示例中,所生成的计算 任务的实例被生成以便包括用于选择和调用根据所修改的前趋图所
选择的后继任务的各自附加的一个或多个程序语句510-la, 510-lb, 510-2a, 510匿2b, 510-Na, 510陽Nb。
将会意识到的是,计算任务的多个实例的生成也可以在具有中央 任务选择和分派函数的实施例中实施。
因此,在上文中已经描述了用于生成经变换的程序代码的过程的 不同实施例,其使得计算任务以随机化次序执行,例如如数字或其它 数据项的(伪)随机序列所定义的次序。如以上所提到的,可以针对
典型地Z:用初始::-^称;种子」作为输入对伪随机数生成 器进行初始化。因此,当伪随机序列由伪随机数生成器(PRNG)生 成时,可以通过利用不同软件安装中的不同种子对PRNG进行初始化 来生成不同的伪随枳4t序列。例如,可以乂人、唯一标识安装的序列号或 另一标识符得到种子。作为选择,PRNG的种子可以被选择为指示安 装的预定组,例如提供给给定顾客的安装、软件组件的不同语言版本 等。
因此,初始状态s。可包括伪随机种子,其对于软件组件的特定安
给定包括例如出现诸如网络响应之类的输入的时间的相同激励,使用 确定性的伪随机数生成器,在执行轨迹在相同安装的不同执行之间并 不发生变化的意义上产生可能对于安装是唯一的执行轨迹。
作为选择,可以选择初始状态以使得因执行而异(至少概率很
高),例如通过选择种子作为日期和时间、实时时钟和/或其它变化信
息的函数。在一些实施例中,随机化序列可以由硬件随机数生成器来
生成,从而相同安装的每次执行可能产生不同轨迹。
因此,在这里所描述的过程的一个实施例中,代码生成过程 -将用于对计算任务进行排序的代码集成在计算任务自身之内,
并且针对每个任务对状态更新进行专用化,
-生成任务的至少一个子集中的每一个的若干实例,并且对每个实例应用保留语义的不同变换,
-生成使得执行轨迹对于软件组件的特定安装为固定,但是在不 同安装之间有所不同的代码。
使用关键代码的多个实例,在原始任务中集成选择函数并且对实 例应用保留语义的变换产生额外的多样性,这进 一 步使得分析复杂 化。
图6示出了用于对程序代码进行篡改保护的系统的示意性框图。 所述系统包括数据处理系统600,例如诸如PC之类的计算机。所述 数据处理系统包括处理单元621,例如诸如计算机的CPU之类的微处 理器。所述处理单元621连接到存储设备620,所述存储设备620诸 如硬盘、存储卡接口、光盘设备等。所述处理单元621被适当编程为 执行自动软件工具622,诸如源到源变换器。例如,自动软件工具622 可适于使得处理单元621从存储设备620加载程序代码的输入表示 (例如源代码),并且执行这里所描述的方法的步骤。处理单元621 可接着在存储设备620上存储经变换的源代码。作为选择,处理单元
口(例如编译器),^'/或经:另一适当接口输出结果。在又一种可替换 实施例中,所述自动软件工具可以直接处理(例如编译)经变换的源 代码。
虽然已经详细示出并描述了 一些实施例,但是本发明并不局限于 此,而是还可以以随后权利要求中所定义主题的范围内的其它方式来 实现。
这里所描述的方法、产品装置和设备能够利用包括若干不同部件 的硬件来实施,并且能够利用适当编程的微处理器来实施。在列举了 若干装置的设备权利要求中,这些装置中的一些能够由同一项硬件 (例如适当编程的微处理器)、 一个或多个数字信号处理器等来实现。 在不同从属权利要求中相互引用特定措施或者在不同实施例中描述 特定措施的这一事实并不表示不能有利地使用这些措施的组合。
应当强调的是,当在本说明书中使用时,术语"包括/包含"被认 为是指定所提到特征、整数、步骤或组件的存在,但是并不排除存在 或添加一个或多个其它特征、整数、步骤、组件或其组合。
权利要求
1.一种计算机实现的用于生成篡改保护的计算机程序代码的方法,所述方法包括-获得计算机程序代码的表示,所述计算机程序代码适于使得数据处理系统以第一执行次序执行多个计算任务,每个计算任务在所述计算机程序代码的表示中由至少一个程序语句来表示;-获得计算任务的多个可替换执行次序;-生成程序代码的可执行表示,其适于使得数据处理系统从所述多个可替换执行次序中选择随机化执行次序并且以所选择的随机化执行次序执行计算任务。
2. 如权利要求1所述的方法,其中当所述程序代码由所述数据 处理系统执行时,每个可替换执行次序适于使得数据处理系统产生与 第 一执行次序相同的程序输出。
3. 如权利要求1或2所述的方法,进一步包括将可替换执行次 序表示为前趋图。
4. 如权利要求1至3中任一项所述的方法,包括-以预定顺序次序接收指示多个程序语句的输入表示; -对程序语句进行分组以获得多个计算任务; -识别多个可替换执行次序。
5. 如权利要求1至4中任一项所述的方法,其中生成程序代码 的可执行表示进一步包括将计算机可执行指令包含在程序代码的可 执行表示中,所述计算机可执行指令适于使得数据处理系统从多个可序执行计算任务。
6. 如权利要求5所述的方法,其中生成程序代码的可执行表示表示中。
7. 如权利要求6所述的方法,其中所述多个可替换执行次序的 表示包括对计算任务的执行次序所施加的前趋约束集合的表示。
8. 如权利要求5至7中任一项所述的方法,其中所述计算机可 执行指令适于使得数据处理系统通过依据多个可替换执行次序针对 每个所执行的计算任务从所执行的计算任务的可替换后继集合中选择后续计算任务来选择随机化执行次序,并且执行所选择的后续计算 任务。
9. 如权利要求1至8中任一项所述的方法,其中生成程序代码 的可执行表示进一步包括将计算机可执行指令包含在程序代码的可 执行表示中,当程序代码映像由数据处理系统执行时,所述计算机可执行指令适于使得数据处理系统执行以下任务a) 执行计算任务中的一个初始任务;b) 基于对计算任务的执行次序所施加的前趋约束集合的表示从 所执行的计算任务的可替换后继集合中选择后续计算任务;c) 执行所选择的计算任务;d) 重复步骤b)和c)直至已经执行了所有计算任务。
10. 如权利要求9所述的方法,其中所述前趋约束集合的表示包 括前趋图的表示;并且其中生成程序代码的可执行表示进一步包括将 计算机可执行指令包含在计算机程序的可执行表示中,所述计算机可 执行指令适于使得数据处理系统保持执行状态,所述执行状态由留待 执行的计算任务的子集以及留待执行并且其在前趋图中的前导都已 经被执行的计算任务的子集中的至少 一 个来定义。
11. 如权利要求10所述的方法,其中执行状态的表示进一步包 括用于对生成随机化数据项序列的函数进行初始化的种子数据项。
12. 如权利要求11所述的方法,包括为程序代码的不同安装生 成程序代码的各个可执行表示,程序代码的每个可执行表示包括指示 相应安装的各自种子数据项。
13. 如权利要求8至12中任一项所述的方法,进一步包括将可 执行指令插入用于执行选择后续计算任务的步骤的每个计算任务中。
14. 如权利要求5至13中任一项所述的方法,进一步包括生成 计算任务的多个实例的可执行指令;并且其中选择计算任务包括选择 计算任务的多个实例之一。
15. 如权利要求14所述的方法,进一步包括对所述多个实例中 的至少 一个执行一个或多个模糊化变换。
16. 如权利要求1至15中任一项所述的方法,其中生成程序代 码的可执行表示包括生成包含用于使得数据处理系统在所生成的程 序代码的可执行表示的每次执行期间从多个可替换执行次序中选择相同的随机化执行次序的程序代码在内的程序代码的可执行表示。
17. 如权利要求1至16中任一项所述的方法,包括生成程序代码的多个可执行表示,其中每个可执行表示包括用于使得数据处理系 统选择不同的随机化执行次序的程序代码。
18. 如权利要求1至17中任一项所述的方法,其中程序代码的 输入表示包括至少一个输入源代码模块。
19. 如权利要求1至18中任一项所述的方法,包括生成至少一 个经变换的源代码模块。
20. —种被配置为执行如权利要求1至19中任一项所述的方法 的步骤的数据处理系统。
21. —种包括计算机可执行程序代码装置的计算机程序产品,当 所述程序代码装置由数据处理系统执行时,所述程序代码装置适于使 得所述数据处理系统执行如权利要求1至19中任一项所述的方法。
22. 如权利要求21所述的计算机程序产品,包括其上存储有程 序代码装置的计算机可读介质。
23. 如权利要求21或22所述的计算机程序产品,其中所述计算 机程序产品包括软件编译器,所述软件编译器包括适于使得数据处理 系统执行如权利要求1至19中任一项所述的方法作为所述软件编译 器所执行的多趟编译之一的功能。
全文摘要
一种计算机实现的生成篡改保护的计算机程序代码的方法。所述方法包括获得计算机程序代码的表示,所述计算机程序代码适于使得数据处理系统以第一执行次序执行多个计算任务,每个计算任务在所述计算机程序代码的表示中由至少一个程序语句来表示;获得所述计算任务的多个可替换执行次序;生成程序代码的可执行表示,其适于使得数据处理系统从所述多个可替换执行次序中选择随机化执行次序并且以所选择的随机化执行次序执行计算任务。
文档编号G06F21/52GK101689232SQ200880022773
公开日2010年3月31日 申请日期2008年6月25日 优先权日2007年6月29日
发明者B·约翰逊, C·冯普拉坦, J·埃克 申请人:艾利森电话股份有限公司