WIN32 汇编写Virus感染PE文件 下载本文

内容发布更新时间 : 2024/5/6 13:29:42星期一 下面是文章的全部内容请认真阅读。

WIN32 汇编写病毒感染PE文件 作者:PSH

日期:2007/3/26

近来没事学习了下病毒技术,看到网上好多年青人对这个比较感兴趣,那就写出来大家分享下吧。 1前提知识

a.熟练WIN32 ASM 语言,不会ASM就难得写出感染PE的病毒。比如“熊猫”,就不是ASM 写的,他感染PE就是个捆绑机。

b.熟悉PE文件的格式,不了解PE怎么写病毒,病毒就是修改PE文件。具体怎么改,下面再说。

c.熟悉WINDOWS编程,最好是用VC写过程序。对进程,多线程,文件操作都很熟,也就是熟悉SDK编程。

d.会基本的软件调试工具,比如W32DASM,OD。不会调试,恐怕难得写个感染PE的病毒。

e.有耐心和细心,对,就是一颗好奇并且喜欢搞恶作剧的心。

f.SEH异常的学习,病毒程序容易崩溃,程序异常处理很有必要。罗云彬的书有介绍。

上面是基本的知识。学到后面恐怕难免要学习驱动技术。 2写病毒的工具 a.语言编译器

我用的MASM,这个可以在罗云彬的网站上下载。也有很多人用TASM,不过,我觉得都差不多。 b.调试器

我开始用的是win32dasm,后来也用OD.原因是他们简单好用。 c.介绍PE格式的书籍和参考书

本人推荐 罗云彬的大作 上面有PE格式。

计算机病毒与反病毒技术——重点大学计算机专业系列教材 这个也不错,上面有个感染PE的爱虫病毒。 3病毒的编译

一般来说,病毒只有一个节,就是.CODE节。这个节是可写,可读,可执行的。我们知道,正常文件都有很多个节,有的节不可写,有的节不可读。但是病毒一般就一个,这是因为病毒感染其他正常PE文件时,病毒的代码要插入被感染程序的代码段中,无论数据,代码,甚至是API函数 都是自己带入附带的。 看下面的介绍:

--------------------------------------------------------------------- .code start:

xor eax ,eax xchg eax ,cout ret

cout dd 00001234h end start

---------------------------------------------------------------------

这样的代码你可以编译,可以连接,但就是不能运行。调试 错误说出了一个“不允许的写操作”

这是因为EXE文件的代码段是不可写的。这就是有些人拿网上的病毒代码连接但总是无法运行的原因。 解决的方法有两个:

<1> . 单独定义一个段 如

--------------------------------------------------------------------- .code

haha segment para use32 start:

xor eax ,eax xchg eax ,cout ret

cout dd 00001234h ;这样定义在 .code 内的变量就可以写了。 haha ends end start

程序就可以正常的运行。

--------------------------------------------------------------------- <2>.连接时候用 section 属性来定义代码段可写

link /subsystem:windows /section:.text,w XXXX.obj

这样就可以把变量定义在代码段内,很多病毒就是这样来搞的。 这就是病毒的编译法子。我用的法2,不过爱虫病毒用的好像是法1.

4 病毒感染PE技术 A 重定位

为什么要重定位,相信有写病毒能力的人应该都心中有数。重定位的技术在罗云彬的进程隐藏和PE文件中讲的很详细。具体的来龙去脉我不多讲,不懂的先要恶补了。代码如下::

++++++++++++++++++++++++++++++++++++ call @base @base: pop ebx

sub ebx ,offset @base

++++++++++++++++++++++++++++++++++++ 那么EBX中间就是代码的偏移差了。

以后调用 全局变量的时候都要这样 [ebx + offset XXXX] 如lea ecx , [ebx + offset szGetProcAddress]

有的人喜欢把其他寄存器作为偏移差,这样不好。老罗的书中说了,用EBX比较好,原因是其他程序用的少,病毒执行快。 B 病毒调用API函数的问题

请严格看罗云彬的大作里面的介绍。另外 “无花果”的网站里面也有相关的介绍。 严格说,病毒的代码是流动的,不是一个完整的程序框架。病毒调用的API都要自己到导入库中加载函数的导入地址。

要获取函数地址必须使用LoadLibrary,GetProcAddress和GetModuleHandle函

数,但这些函数地址又从哪里得到呢(这就好像一个“先有鸡,还是先有蛋”的问题),幸亏这些函数都存在于Kernel32库中,Kernel32.dll库文件和User32.dll,Gdi32.dll一样,都是最常用的库,在不同的进程中,系统会将它们装入到同样的地址中,所以对于它们来说,在本地进程中获取的地址可以用在远程线程中。

各个程序的要导入的系统内库(DLL,如KER32)在系统的内存空间都是独立的,因而在程序中加载的地址也是不同的。幸好的是, ker32dll在整个系统中的地址是不变的,有点像程序内存共享的味道。我们首先要做的是自己找到 ker32dll的基地址。进而从这个基地址开始 找到GetProcAddress的函数地址。有了这个函数以后,我们就可以加载其他API函数的入口地址了。系统内存中的KER32DLL是什么呢,注意不要忘了,它不过也是一个PE文件,它的内部结构和PE文件是没有任何差别的。(提醒大家一下。有人问我,它拿人家的程序,不知道指向KER32 的ESP 现在的地址在那里了,答案就在这里。)

++++++++++++++++++++++++++++++++++++++++++++++++++++ 找到ker32dll的基地址

_getbase proc uses esi edi, besp local @re mov @re ,0 mov eax ,besp

and eax ,0fffff000h mov esi ,eax @@:

sub esi,1000h

cmp word ptr [esi] ,'ZM' jnz short @b

movzx edi ,word ptr [esi + 003ch] add edi ,esi

cmp word ptr [edi] ,'EP' jnz short @b mov @re ,esi mov eax ,@re ret

_getbase endp

看到上面函数有一个参数 在病毒开始是这样调用 push [esp] call _getbase

原因是程序开始的时候ESP里面的地址是在KER32DLL里面的。记住,KER32DLL是个PE文件,品味一下这话的含义。

这里不多说,详细的细节参考罗云彬的大作。(但老罗没教你写病毒喔) ++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++ ;下面这个函数找API函数的入口地址,了解PE结构对着看 _getpro proc uses esi ebx ,hmod , lpapi