• 标 题:浅谈多态变形技术结合人工智能算法在软件保护中的应用
  • 作 者:virtualspace
  • 时 间:2004-1-05 周一, 上午6:16
  • 链 接:http://bbs.pediy.com

注:本文仅从个人对有关软件保护技术的浅显认识,试图面向那些对此领域感兴趣的初学者,带来一些启发性的参考思路。谬误之处在所难免,还望大家批评指正,非常感谢!

前言

对于一个软件产品进行技术保护的目的,就是要给那些尝试破解,逆向分析被保护软件产品的研究者带来最大限度技术性阻碍,利益损失。以使它们的破解,逆向行为变得需要消耗大量时间,精力等代价,得不偿失。

就作者本人以往的经验,总体来看,一般软件保护技术的进步总是逊色于相关破解技术的发展。现有公认的具有一定强度的软件保护技术,大都直接涉及一定的数学理论,并且基于许多数学上的难题,形成一定强度的加密算法。研制一套好的软件保护系统,不是一件轻而易举的工作。一般的软件制作者是很难同时具有良好的数学基础和软件开发经验的。况且,目前许多大型软件(例如winxp采用了椭圆算法)依然在较短的时间内被攻破。

网络聚合了人类的集体智慧,随着并行处理技术的不断成熟,计算网络几何级数的增长,不断复杂化,精确化,快速化,促进了人们的交流更加直接,快速,使得那些被认为安全性很高的加密算法(特别是依据数学难题的那些算法)可能被攻破的时间远远小于被预计的期限。目前,是我们应该对软件保护技术进行更多的思考和尝试的时候了。

建立一个软件保护系统不但要要有可靠的理论基础,而且需要耗费繁杂的资源(时间,精力,资金,技术,人才等等),而任何一个具有一定数学基础,编程能力的破解者都有可能找到这个系统的漏洞而摧毁它。防御远比进攻代价要大。

在此,本文作者尝试探讨如何利用当前较新的软件保护理论,结合我们自己的特长,所能掌握的资源,尽最大可能使我们自己开发的软件产品得到一定程度的安全保障。




一.  多态变形技术
多态变形技术的发展和形成,最早在计算机病毒中得到体现。病毒程序的设计者为了使病毒代码躲避扫描程序的监察,不断对自身的执行代码进行变换,尽量隐藏扫描程序依据的病毒特征代码,从而使得扫描程序无法正确侦测和清除该病毒。正是不断动态的变化特性,使得病毒程序具有更高的存活性,可发展性,危害性。对于任何不断变化的事物,采用单一的对抗措施都是徒劳和效率底下的。我们应该重视变化特性的软件保护技术中的应用。

二.  人工智能技术
游戏软件大都不同程度的设计各种人工智能算法,那些大型复杂的游戏,可以对玩家体现出很强的对抗性,正是这种智能特性的发展才推动了游戏产业的发展。我们可以在一定程度上结合简单的智能算法作为软件保护步骤中的一个环节,来对抗破解者的攻击。

三.  软件保护方案的设计思路

设计一套结合智能特性和多态变形理论的软件保护系统,首先,我们需要考虑准备一个知识库(或者更简单的说,是一个数据仓库),它应该具有一定程度的自学习功能,也就是数据的不断更新变化的特性。缺少这样一个数据库,也就失去了我们设计基础。人正是通过不断学习,积累知识,思考,创造,才会进步的。如何让我们的程序学会思考?这个问题我回答不了,但是我们可以利用已经掌握的技术,进行各种组合尝试,集合数据库概念,研究一套可行的具有一定强度的软件保护系统。

针对软件保护的不同形式,我们先来看看在线注册,名称/列号保护方式。

3.1 序列号保护的策略
首先,在软件产品拥有者的服务器上装有一个用于产生合法注册号的信息库。任何试用本软件并且愿意购买的人,将他个人的资料,以及依赖他安装此软件的计算机自动产生的识别码发送到软件发行者的注册服务器。经确认成功,系统将发回一个注册文件,使用者可以合法使用该软件。

3.2 序列号保护的安全性保障:

首先,软件开发者应该定期不断的更新软件,所提供试用的软件的Key算法或程序片断已经被简化或者尚未提供。如此,一个试用者在尚未得到一个正式版本时,对软件的破解失去了意义。正式注册者,可以得到一个注册文件,其中包括那些被提取或简化的代码片断,当然,这些关键代码依然是被加密的,相关的解密过程在程序执行时动态进行。

实际上,这个注册文件是一个小型的数据库,其中包括:
1.  依据注册时提交的注册信息机本机特征字形成的针对需要被解密程序片断的算法库(比如至少有20个)
2.  解密过程中需要调用的反跟踪程序(程序运行过程中使用的多线程监视程序)
3.  各种不同的智能处理程序,用于形成有效解密数据
4.  用于不同解密程序的数据信息(针对不同解密算法,针对不同需解密的程序片断)
5.  被加密的关键程序片断
6.  联机更新程序(可链接主机,更新程序)

3.3 外壳加密程序
外壳加密程序应该提供一个可靠的加密库。其中包括,各种不同加密算法库,反跟踪库,智能算法库,以及相关数据库。必须保证,被外壳加密程序保护的软件产品,任何一个都具有互不相同的加密子库,并且可以随时获得在线的更新,保证变化性,智能性。

3.4 外壳加密的安全性
外科加密程序生成的被保护软件,应该需要在实现安装,才可以真正运行。安装过程,既是要使得被加密软件的运行,不能脱离安装它的宿主计算机,如此才可以保证被保护软件不至于因一个版本被破解形成通用的破解补丁。

四.  关于保护中反逆向工程的技术探讨

逆向工程大都是通过对执行程序采取静态,动态分析的结果推测程序实现功能的步骤和方法。其中对于逆向工程来说,最大的障碍不是利用某些特别的系统特性而设计的反跟踪技术性陷阱,而是不可理解的大量的程序代码。那么,我们如何为破解者准备这些他们必须看要分析又难以看懂的代码呢?我们应该使用比较复杂的程序控制流程,代码序列已经加密算法。

任何人通过执行程序内含的代码和数据,对于一个较复杂算法的分析都是十分困难的。人的生物特性,毕竟不适合从事长期单一性,如此艰巨而繁琐枯燥的分析研究工作。如此,我们可以尝试利用有关人工智能的算法,作为软件保护系统的主程序序列流控制部分,如此,破解者对于我们的保护程序的执行流分析就会成为意见十分艰巨的任务,足以让任何尝试分析它的人望而生畏,如果分析类似的人工智能算法的C, JAVA, PASCAL语言写代码都很困难,那何况是汇编语言呢?

只有复杂的算法还不够,我们的数据仓库呢?它正好为我们构造可变性的程序控制流序列和不同的加密算法提供了足够的原料,呵呵。

我们可以尝试简单设计一些不否步骤:

第一步,我们可以在程序运行的开始,自动生成一个大型的迷宫。其实很简单,生成一棵大的二叉树就可以了,因为你可以想见,把这个二叉树围拢起来,再随意在树干上来一斧头,那它不是肯定有一条通路吗?我们可以在树干上,树枝上都多来几刀,形成一个有多条通路和出口的迷宫。然后随机采用一种路径搜索算法,从一个随机的入口走到另一个随机设定的出口(需要具有一定的深度)。这个过程计算机执行是很快的,然而,如果破解者想单步分析跟踪出来我们的算法和迷宫,那在他事先不知道我们的设计时,还是有些困难的。

如果我们设计9层这样的迷宫(Diablo里是几层来着?),每个迷宫特定的步骤都生成进入下一个迷宫的跳转代码,而且行进到某些步骤时定期检测是否有跟踪程序,或者其它条件的状况,或者生成某些关键数据。每次我们的程序执行时,这些动态的步骤是基本可以对跟踪者起到一定的迷惑作用的,并且初步避免了通用补丁程序。

关于注册信息的识别,关键数据的加密与大数据库应用

加密部分程序片断,我们不必使用什么特别复杂的方法,你可以存储一本电子版的圣经,然后根据注册信息,计算出应该选择某一页,某几段的圣经内容对目标进行简单的xor加密,在未知加密数据的前提下,密文几乎是不可破译的,如此的加密强度完全可以媲美任何复杂的加密算法。

智能算法程序的应用

我们可以在软件保护程序的控制代码序列中采用一套中国象棋算法(或其它任何博弈算法),在我们的大数据库中保存1万个棋局,我们的算法可以根据加密程序的要求和具体设置选择部分棋局,每次程序执行时动态调入几组棋局,当用户输入了正确的注册码或者合法用户的信息后,通过算法转换这些信息给博弈算法(我们的人工智能算法),它通过象棋的规则,应用人机对弈得到一个结果(可能是胜负的判断,或者优劣形势的判断),然后根据这个棋盘上的结果生成一些用于解密的数据,解密程序的后续部分以及关键数据,致使程序正常执行。如此,可以避免一套被安装在某个计算机上的程序被破解后,形成该软件的某个通用破解补丁。由于每次程序执行时都可能调用某个博弈算法,代码序列和流向不可预知,而是动态地依据当时运行环境的计算结果,解密后续部分,使得程序的跟踪更加难以进行。

五.  总结

总之,软件保护技术一定会具有更多动态变化的智能特性,仿生学不正是科学借鉴大自然的巧妙安排来改进我们人类技术的吗?我相信,有一天,我们不再需要去编写一行一行的代码来实现我们的软件保护系统。随着科技进步的加快,高级的人工智能必将最终取代这个任务。

六.  后记

我感到不安的,不是我们将来可以高枕无忧,尽享安逸,而正如许多科学家预言的那样,人类的未来,必将使人造的科技最终控制和消灭人类。

如果这就是人类的宿命和必然的未来,就如今天我们在主宰者这个星球上的其他生物,也许这是一种轮回,你还依然期待看到那一天的到来吗?也许那是再一次的奴隶社会体验的开始。人类可以摧毁matrix 安排的世界吗?revolution会有一个结局吗?我们的兄弟是否又会重新拾起木棍,胸前挂着cpu的碎片,在废墟和丛林中,为了争夺一只野兔而相互厮杀?

故事还没有完,我想起一部老电影里的话:这,是个 有钱人的 世界。
那些有钱人,设计了未来。。。。。。。

附:有关多态加密方法的介绍(译自CyProtect AG)
一种有关新的对称加密系统的方法是自编译机器码解决长密钥的速度问题。密码系统的执行时间仅仅依据密钥长度线性增加。 这种设计思路是要随机化算法自身,所以我们称之为‘多态方法’。假设数据和实际采用的算法在初始时是未定义的。一个计划对你的密钥进行攻击的人会感到缺少必要的信息,当它进行分析时,这个变化的过程很快复杂化起来,使其困惑难解。 一般我们都知道,密码使用一个密钥(也就是一个变量)。一个含有两个变量的数学等式是无法求解的。对于密码系统,这当然是一个解决方案,唯一得到正确密钥的方法,只有搜索全部的密钥空间。问题就在于,对于一般的密码需要一个一维搜索空间,对于多态密码,需要二维搜索空间。
多态方法属于目前最具强度的加密算法,它大概应该算是最强的了。这个方法具有通过简单地获得随机产生的机器码产生足够安全的特性来对抗任何种类的攻击行为的优势。它甚至能够对抗对程序指令流的分析研究,因为这些指令流自身是可变的! 对于破解密码系统来说,掌握被应用的加密算法的细节,对于推导密钥是非常重要的事情,但是对于采用多态方法的加密系统来说,所采用的算法具有本质上的不可知性。
多态方法的基本法则

两个不同的密钥(或者一个密钥的两个部分)是由随机数发生器产生的。其中一个随机数发生器(左发生器)产生一个用于汇编的机器指令代码字节流。在运行期间,内置的编译器简单地依照标准建立程序块(片段),调整那些地址和入口,以及退出点,去产生相应的机器码,这些机器码,将在运行期间影响Key数据数组。这个数据数组由另一个随机数发生器(右发生器)参照正确的口令字。
在这些机器码被执行后,Key数据数组能够被用于加密明文(通过xor操作)。Key数据数组应该采用优先选择采用简单快速的密码算法。经此处理,整个加密系统的复杂性得到增强,使得Key数据数组的内容难以被分析,有关密钥的线索无法被获取。
这个方法的动态和变形特性,有时甚至可以迷惑分析者重新编译指令序列。
多态加密方法内置的编译器以同样的方式使用处理器的寄存器编译可替代的代码片断。每一个建立的程序块可被同样功能的其它块替代。除非数据是由一个块到另一个块,实际的代码长度可以依据复杂性进行改变。 一个数据数组(可以被看作是一个长变量)是参照一个密钥(口令字)被初始化的。它代替了常规加密算法中的密钥。CPU 针对这个安全盒(S-box)进行有关的工作,例如置换,mod运算,替换或其它非线性操作。
对多态加密方法安全性的攻击
每个建立的块至少影响32位数据并且频繁的改变密钥(key)。
假设只有4密码指令块和16个这样的块能够被无序的相继组合,那么存在4^16 = 4294967296种不同的实际加密算法!如果128指令块被组合,将会有4^128 = 1,158*1077 组合结果 (标准128 位加密产生3,403*1038)。

有一个重要的地方要注意,这个方法不会影响运行时间。因为要产生一个被很好混淆(加密)的Key数据数组,常规的算法同样需要作出如此的保证-不能影响运行时间。
多态方法实际上较之常规方法有更好的抗攻击性。为了计算攻击安全性总量,大量的代码组合必须被大量的密钥可能性相乘。密钥尺寸(Key size)可以是16字节 = 128 位; 那么存储在key数据数组中的key组合是2^128 = 3,403*1038 。在多态方法种,两个Key空间相乘产生1,158*1077 * 3,403*1038 = 3,913*10115种可能的Key组合。
为了比较常规的传统加密方法与多态方法,总Key空间必须被比较。在假定两者同样工作在128位数据Key的情况下,这种比较是合情合理的。由此,多态方法明显优于任何的常规传统方法: 3,913*10115 / 3,403*1038 = 1,150*1077 (!). 这个数字比我们星球上的原子还要多!

无间道III之《终极无间》引用《地藏菩萨本愿经》,说“如是等辈,当堕无间地狱”。是谁?
If you wanna be somebody else, just change your mind