作者:ValleZ
翻译:pker / CVC翻译小组
我想在这里发表我的一些想法,
病毒的遗传编程病毒防范
。这些仅仅是想法... 这些想法非常美丽,然而这看起来更像是虚构的而非现实。
进化系统
--------
我们可以在自然界中找到一些可以对外界刺激产生反应的生物系统,它们可以从外界学习并
进行训练,... 仍然我们在自然系统中可以看到它们通过物种的进化而改善自身的能力。
进化以这样的方式进行:祖先产生它们的后代。这些后代和它们的祖先很相似,然而它们仍
有着一些不同。通过自然选择过程,只有能够适应这种环境的后代生存了下来。它们会有更
多的后代,然后它们同样面临着自然选择的过程。
这些特点(自然选择还有祖先不断地繁殖后代)足以产生强大的后代。
让我们来看一个类似的过程来更好地理解这个事实:
我们有这样一个环境,里面有山谷、高山和草原。我们有一些个体。如果一些个体所处的位
置比其他的个体位置高,我们就说这个个体更为强大。后代要继承两个个体,也就是他们的
祖先,的一些特征。后代的位置在其两祖先的连线中点处。如果这个中点的位置比两祖先的
位置高,那么我们说这个后代比祖先更强大。自然选择过程会减少个体的高度。通过进化,
我们的个体所处的位置会有所提高。比如用这样的方法我们就可以找到最强大的个体。
遗传编程
--------
遗传编程是建立在上面描述的基础上的。我们有一系列的操作(我们把代码元素看成单元)。
通过这些操作我们产生了第一代程序。我们使用一个选择进程去选择适应能力更强的程序。
我们找到能更好地解决我们问题的程序。为了是程序完成进化,我们对它输入一些训练数据,
我们从结果中可以看到哪个程序能得到了最好的进化。然后我们淘汰掉不好的程序。通过留
下来的程序,我们用两个进程产生新的后代,突变和交叉遗传。我们通过改变操作中的一部
分代码完成从祖先到后代的突变。交叉遗传更为有效。通过交叉遗传我们得到具有两祖先交
叉特征的后代:我们随机地选择一祖先的操作然后用另一祖先的随机选定的操作代替。通常,
交叉遗传的频率要比突变的频率高,二者兼而有之。
好了,你可以通过网络找到很多关于遗传编程的文章。我只是讲述了遗传编程是什么,
下面我将讲述遗传编程怎样运用到病毒世界中。
病毒
----
自从我读了一些关于遗传编程的文章后我就一直在想如何把它应用到病毒编程中。病毒和遗
传编程有一些相似性。当一个病毒感染了一个文件,它就产生了后代。然而后代和祖先是一
样的。是的,多态和变形病毒是与祖先不同,但是它们的行为与祖先是完全相同的。
如果要把遗传编程运用到病毒中,我们必须把病毒看成一个由操作组成的集合。这里说的操
作不是指的xor, call, jmp ...我说的是更高层次的操作。比如,我们的一个操作元素是搜
索文件夹而另一个操作元素是完成.exe、.hlp或者其他文件的感染。一个蠕虫元素。一个载
体元素,...。这些元素的代码必须可以在内存中的任何位置单独工作。一个程序由这些元素
组成。我们可以给这些元素块命名。我觉得这些块应该像29a #6中文章siilex中定义的块一
样。这些块可以组合在一起成为一个完整的程序。
比如,我们有一个可以改变当前路径的病毒块。我们还有一个病毒块,它可以通过自己和一
些被感染文件中的病毒块感染.exe文件。另外,我们还有一个反调试的病毒块和一个载体病
毒块。我们可以随机地组合这6个病毒块。我们可以有很多可能:
1. 改变路径-感染-改变路径-改变路径-感染-载体
2. 反调试-改变路径-感染-改变路径-感染-载体
...
n. 反调试-反调试-改变路径-改变路径-载体-改变路径
好了,用这些病毒块我们已经生成了n个程序。如果我们看一下前面的这些程序,很容易看出
程序2比程序1和n更有效。如果这三个程序在外界环境中,程序2会生存的时间更长。事实上,
程序n并不感染别的程序。n会第一个死掉,并且第二个会生存更时间。
我说过病毒与遗传编程有一些相似之处。在病毒世界中,是不是也存在选择过程呢?当然。
然而这个过程不是一个进化过程或其他类似过程。病毒必须生存下去。在病毒世界中,反病
毒软件、聪明的用户,... 就是一个选择过程。之前,我说很显然程序2比程序1和n要好。一
个VXer编写一个包含多态、入口模糊、每进程驻留等技术的病毒是因为他想他的病毒可以长
时间地生存下去。
现在对于病毒编程和遗传编程我们有两个共同点。病毒产生后代并且只有好的病毒可以生存
下去。
病毒的突变
----------
我不是在讲述多态和变形引擎。再一次,我们有了一组可选的病毒块。我们可以随机地生成
一系列程序,我们看看其中一个:
gen0 -> 改变路径-改变路径-感染-载体-感染-载体-改变路径-载体
我们可以编写一个可以改写当前代码的感染机。它可以通过其他病毒块改变自己的块或者改
变病毒块的顺序。比如,这个感染-变异器感染一个文件并调换了两个病毒块:
gen1 -> 改变路径-感染-改变路径-载体-感染-载体-改变路径-载体
gen1病毒的能力得到了提高因为现在它在一次执行时感染了两个目录的文件。现在gen1病毒
感染其他文件,但是这次它通过别的病毒块改变了一个块。
gen2 -> 改变路径-感染-改变路径-反调试-感染-载体-改变路径-载体
当然,病毒可能在感染文件时用了一个很糟糕的病毒块组合:
另一个gen2 -> 改变路径-载体-改变路径-载体-感染-载体-改变路径-载体
这个gen2很难有生存的可能。
注意并不一定在每次感染文件时都发生变异,因为如果我们有了一个优秀的个体而这个个体
在感染时改变了自己的代码,它就会变弱。病毒只能是在一些时候变异。
病毒的交叉遗传
--------------
我想这个是很有趣的,但是这也不太可能发生。关于如何发生交叉遗传我想了很多。为了发
生交叉遗传,我们需要两个祖先,然而我们不能得到所有感染文件的列表。另外,病毒的后
代还会感染其他文件,这样一直继续下去,我们无发得知哪些文件是被感染的。我想,交叉
遗传必须发生在一个病毒试图去感染一个已经被感染的文件时。如果一个病毒检测到它正要
感染一个已被感染的文件,它不会再次感染它,但是它会从这个文件中“学习”一个病毒块
(随机地)然后把这个病毒块用在下次感染时用。通过这种方式,在下一次感染时,被感染
的文件将成为那两个祖先的后代。
另外,如果一个在牙买加的VXer和一个在荷兰的VXer写了两个不同的病毒,但是这两个病毒
有着标准的可识别的病毒块,当来自牙买加的病毒发现一个被来自荷兰的病毒感染的文件时,
它会从这个病毒中“学习”一个病毒块。如果很多VXer在编写他们的病毒时都遵循一个标准,
他们的病毒就可以互相学习然后更强大的病毒会生存下来因为它们继承了所有病毒中最为优
秀的病毒块。我想这可能看起来不可能发生... 这看起来更像是电影而非现实生活,然而我
想这是一个不错的主意:-m
困难
----
当然,为了达到这个目的,我们需要一个标准的定义病毒块的格式、标识、感染模式等。如
果我编写一个等待和别的病毒交换病毒块的病毒,那么我的病毒就必须可以识别来自其他病
毒的病毒块。有会想到,如果我的病毒可以识别出一个来自别的病毒的病毒块,那么启发式
的反病毒软件也可以找到。是的:(
另外,反病毒软件公司可以开发出通过检测这些病毒块而不是整个病毒的软件。
比如,我们假设一个病毒组织使用了这样的方法。他们决定他们以后开发的所有病毒都使用
相同的感染标记(比如他们可以把文件头的某个位置设置成一个值)。通过这个标记,所有
的病毒可以识别被感染的文件(被它们或者同组的其他病毒感染的文件)然后它们就可以扫
描被感染的文件搜索病毒块来“学习”。然而,一旦一个AV知道了这个感染标记是由这个小组
的程序员做的,则所有的这些病毒都会被简单地被检测到。
概要
----
关于如何编写遗传病毒我写了一个概要。这仅仅是个概要,一个还需要很多改善以使它工作
得更好的例子。
病毒块的要点
------------
病毒块是可以在任何位置独立执行的基本元素,独立于任何其他块代码。一个病毒块使用在
代码中执行的函数,而且变量也要在其代码中。另外,一个病毒块必须要可以被识别。没有
必要知道一个块的功能是什么,但是一定要能识别这是一个块并可以被其他遗传病毒使用。
病毒块大小是固定的或者我们可以在块中留出空间来存放块的大小。我更喜欢第二种方法。
我认为块的格式应该尽可能的简单。一个块不能有一个很大的头来存放很多的块特征。
作为例子,我想一个病毒块应该是下面的样子:
-----------------
+ N字节初始化代码 +
-----------------
+ 4字节用来存放 +
+ 代码大小 +
-----------------
+ X字节块代码 +
-----------------
N对所有块来说是一个常量,
电脑资料
《病毒的遗传编程病毒防范》(http://meiwen.anslib.com)。在代码中可以是一段短小的解密代码或是简单地跳转到病毒块的代码处。
我们会有些问题,因为一些块(比如一个块要改变当前操作路径)要做一些在后面需要被撤
消的工作。
另外我们还没有考虑如何使病毒返回宿主。关于这个问题我有一些想法。一个完整病毒中的
所有病毒块结构可以是如下的格式:
dd N_BCKs (在所有病毒块前面有一个dd指示总块数)
----------
病毒块1 (在后面这就成为病毒块)
----------
病毒块2
----------
...
...
...
----------
病毒块n
----------
jmp host (最后是一个返回宿主的跳转)
----------
当一个感染块用当前病毒块感染一个文件时,它必须在每个块后面写上一个返回宿主的跳转。
是的,这在其他病毒中是很典型的。然而这个跳转有一个很重要的任务。这个跳转要用来撤
消所有由这个块所做的改变。开始时,在病毒执行前,那个jmp指向宿主的入口。当一个病毒
块需要撤消改变的时候,它会改变这个jmp到自己的完成撤消工作的代码处。它会保存刚才那
个jmp指向的地址然后当撤消工作结束后它就会跳到那个地址处。它挂钩了那个jmp。这个方
法可以被所有需要使用它的病毒块使用。如果一个病毒块挂钩了jmp然后又有另一个块挂钩这
个jmp,事情会按照下面的样子发生:
病毒块1挂钩jmp
--------------
病毒块1
撤消代码1: <-----------
|
... |
jmp 宿主入口 |
-------------- |
|
其他病毒块 |
|
-------------- |
jmp 撤消代码1 -----------
病毒块1挂钩jmp后病毒块n又挂钩jmp
--------------
病毒块1
撤消代码1: <---------------
|
... |
jmp 宿主入口 |
-------------- |
|
其他病毒块 |
|
-------------- |
|
病毒块n |
|
撤消代码n: <----------- |
| |
... | |
jmp 撤消代码1 ------------|----
-------------- |
|
其他病毒块 |
|
-------------- |
jmp 撤消代码n -----------
这样,所有的病毒块都可以完成撤消工作,并且第一个挂钩jmp的块可以在所有的块完成撤消
后返回宿主。
--- x --- x --- x --- x --- x --- x --- x --- x --- x --- x --- x --- x --- x ---
好了... 当我完成这篇关于遗传病毒的文章时Kernel32给了我这篇他写的文档。他没有看我
的文章而且我很棒因为他想的和我写的非常相似。他和我有着很相同的想法但我已经把我的
文章发给了29A,我觉得这不公平,所以我把他的文章也发出来,因为我觉得这样才对。
[KERNEL32]
--------------------------------------------------------------------------------
发明一项新技术
是否想过病毒可以像人类一样呢?
像病毒一样,我们都是生物,对么?
我们都有各自的DNA序列。病毒也一样。
我将解释我的想法,
“男性”病毒将给出完整的标记关于:
* 载体
* 他使用的多态引擎
* 不同的函数
* 等
“女性”病毒将接受这些DNA编码然后把它加入到自己代码中或替代自己的代码。
我们可以写一个“双性”病毒,它既提供DNA同时也接受它。
男性病毒像这样工作:
男性
-------------------------
- -
- 病毒主程序 -
-------------------------
- 标记 -
-------------------------
- 函数 -
-------------------------
女性
-------------------------
- -
- 病毒主程序 -
-------------------------
- 函数 -
-------------------------
我们先来做重要的事情,标记很重要,它应该包括:
* 感染什么类型的文件(exe,dll,ocx等)
* 这是一个什么样的病毒/蠕虫(驻留,文件搜索式等)
基本上女性需要的所有信息用来检测她是否与男性兼容。
如果你让一个女性使用了一个不兼容她的函数她会崩溃。
要包含很多类似载体、反调试、随机数生成等函数。
女性应该检查标记然后检测是否与男性兼容,如果兼容她就决定选择哪个函数来扩充自
身。同时男性要提供函数的大小以及开始/结束的位置。