病毒编程技术-2

限时加码!20+主流AI编程工具免费用 购周边加赠Coding Plan Lite,Claude Code、Cursor等即刻畅享,学习进阶更高效! 阅读详情

* Windows平台和PE文件格式

          Windows平台是当今最为流行的桌面系统,在服务器市场上,也占有相当的份额。其可执行文件(普通的用户程序、共享库以及NT系统的驱动文件)采用的是PE(Portable Executebale)文件格式。病毒要完成各种操作,在Windows系统上一般都是通过调用系统提供的API进行的,以保证在各种Windows版本上都能运行,因此读者应对基本的API比较熟悉。病毒要实现对宿主程序的感染,就不可避免地要修改PE文件,因此要求读者对PE文件格式有一定的了解,PE文件格式是一种复杂的文件格式,本文并不准备详细讲述PE文件格式,仅作在必要处简单的介绍,如必要可进一步参阅相关资料[1][2][3]。PE文件结构和头部部分主要域的格式如下图1所示。由图1可见,PE文件是由文件头、节表、包含各种代码和数据的节构成。文件头中定义了PE文件的引入函数表、引出函数表、节数目、文件版本、文件大小、所属子系统等相关的重要信息。节表则定义了实际数据节的大小、对齐、内存到文件如何进行映射等信息。后面的各个节则包含了实际的可执行代码或数据。

 

 

 

图1 PE文件结构及部分主要域的定义

 


* PE病毒技术剖析

        典型的PE病毒修改PE文件,将病毒体代码写入PE文件文件中,更新头部相关的数据结构,使得修改后的PE文件仍然是合法PE文件,然后将PE入口指针改为指向病毒代码入口,这样在系统加载PE文件后,病毒代码就首先获取了控制权,在执行完感染或破坏代码后,再将控制权转移给正常的程序代码,这样病毒代码就神不知鬼不觉地悄悄运行了。染毒后的PE文件运行过程一般图2所示:


图2 染毒后的程序执行流程

        这只是最常见的执行流程,事实上,随着反病毒技术的进展,更多的病毒并不是在程序的入口获取控制权,而是在程序运行中或退出时获取控制权,以逃避杀毒软件的初步扫描,这种技术又被称为EPO技术,将在本文后半部分进行介绍。病毒代码一般分成几个主要功能模块:解码模块、重定位模块、文件搜索模块、感染模块、破坏模块、加密变形模块等,不同的病毒包含模块不一定相同,比如解码、加密变形等就是可选的;但文件搜索和感染模块是几乎每个PE病毒都具备的,因为自我复制我传播是病毒的最基本的特征。有些病毒还可能实现了其他的模块,比如Email发送、网络扫描、内存感染等。一段典型的PE病毒代码执行流程大致如下图3所示:


图3 一段典型的病毒代码执行流程

        从原理上看病毒非常简单,但实现起来还有不少困难,其实如果解决了这些技术难点,一个五脏俱全的病毒也就形成了,本文后面将从一个病毒编写者的角度就各个难点分别予以介绍。病毒可采用的技术几乎涉及到Windows程序设计的所有方面,但限于篇幅,本文亦不可能全部介绍,本文将重点介绍Win32用户模式病毒所常用的一些技术。

* 编程语言
 
        任何语言只要表达能力足够强,都可用于编写PE病毒。但现存的绝大部分PE病毒都是直接用汇编编写的,一方面是因为汇编编译后的代码短小精悍,可以充分进行人工优化,以满足隐蔽性的要求;另外一方面之所以用汇编是因为其灵活和可控,病毒要同系统底层有时甚至是硬件打交道,由于编译器的特点不尽相同,用高级语言实现某些功能甚至会更加麻烦,比如用汇编很方便地就可以直接进行自身重定位、自身代码修改以及读写IO端口等操作,而用高级语言实现则相对烦琐。用汇编还可以充分利用底层硬件支持的各种特性,限制非常少。但是用汇编编写病毒的主要缺点就是编写效率低,加上使用各种优化手段使得代码阅读起来相当困难,不过作为一种极限编程技术,对病毒作者而言,这些似乎都已经不再重要。本文假设读者熟悉汇编语言,各种举例使用Intel格式的汇编代码,编译器可使用MASM或FASM进行编译,由于汇编语言表述算法较为不便,因此算法和原理性表述仍然采用C语言。在讲述各种技术时,部分代码直接取自病毒Elkern的源代码,该病毒在2002年曾经大规模流行,其代码被收录于著名病毒杂志29A第7期中,有兴趣的读者可参阅其完整代码。

* 重定位

        病毒自身的重定位是病毒代码在得以顺利运行前应解决的最基本问题。病毒代码在运行时同样也要引用一些数据,比如API函数的名字、杀毒软件的黑名单、系统相关的特殊数据等,由于病毒代码在宿主进程中运行时的内存地址是在编译汇编代码时无法预知的,而病毒在感染不同的宿主时其位于宿主中的准确位置同样也无法提前预知,因此病毒就要在运行时动态确定其引用数据的地址,否则,引用数据时几乎肯定会发生错误。对于普通的PE文件比如动态链接库而言,在被加载到不同地址处时由加载器根据PE中一个被称为重定位表的特殊结构动态修正引用数据指令的地址,而重定位表是由编译器在编译阶段生成的,因此动态链接库本身无需为此做任何额外处理。病毒代码则不同,必须自己动态确定需引用数据的地址。比如一段病毒代码被加载在0x400000处,地址0x401000处的一条语句及其引用的数据定义如下所示,相关地址是编译器在编译时计算得到的,这里假设编译时预设的基地址也是0x400000:
401000:   
    mov eax,dword ptr [402035]
    ......
402035:
    db "hello world!",0
  如果病毒代码在宿主中也加载到基地址0x400000,显然是能够正常执行的,但如果这段代码被加载在基地址0x500000运行时则出错,对病毒而言,这是大多数时候都会遇到的情况,因为指令中引用的仍然是0x402035这个地址。如果病毒代码不是在宿主进程中而是作为一个具有重定位表的独立PE文件运行,正常情况下由系统加载器根据重定位表表项将 mov eax,dword ptr [402035]中的0x402035修改为正确值0x502305,这样这句代码就变成了mov eax,dword ptr [5402035],程序也就能准确无误地运行了。不过很可惜,对在其它进程内运行病毒代码而言,必须采取额外的手段、付出额外的代价感染宿主PE文件时就及时加以解决,否则将导致宿主进程无法正常运行。

至少有两种方法可以解决重定位的问题:

A)第一种方法就是利用上述PE文件重定位表项的特殊作用构造相应的重定位表项。在感染目标PE文件时,将引用自身数据的需要被重定位的地址全部写入目标PE文件的重定位表中,如果目标PE无任何重定位表项(如用MS linker的/fixed)则创建重定位表节并插入新的重定位项;若已经存在重定位表项,则在修改已存在的重定位表节,在其中插入包含了这些地址的新表项。重定位的工作就完全由系统加载器在加载PE文件的时候自动进行了。重定位表项由PE文件头的DataDirectory数据中的第6个成员IMAGE_DIRECTORY_ENTRY_BASERELOC指向。该方法需要的代码稍多,实现起来也相对比较复杂,另外如果目标文件无重定位表项(为了减小代码体积,这种情况也不少见),处理起来就比较麻烦,只有用高级语言编写病毒才常用该种方法,在一般的PE病毒中很少使用。

B)利用Intel X86体系结构的特殊指令,call或fnstenv等指令动态获取当前指令的运行时地址,计算该地址与编译时预定义地址的差值(被称为delta offset),再将该差值加到原编译时预定的地址上,得到的就是运行时数据的正确地址。对于intel x86指令集而言,在书写代码时,通过将delta offset放在某个寄存器中,然后通过变址寻址引用数据就可以解决引用数据重定位的难题。还以上例说明,假如上述指令块被操作系统映射在0x500000处那么代码及其在内存中的地址将变为:
501000:   
    mov eax,dword ptr [402035] 
    ......
502035:
    db "hello world!",0

  显然,mov指令引用的操作数地址是不正确的,如果我们知道了mov指令运行时地址是0x501000,那么计算该地址和编译时该指令预设地址的差值:0x501000-0x401000 = 0x100000。很显然指令引用的实际数据地址应该为0x402035+0x100000 = 0x502035。从上例可以看出,只要能够在运行时确定某条指令动态运行时的地址,而其编译时地址已知,我们就能够通过将delta offset加到相应的地址上正确重定位任何代码或数据的运行时地址。原理如图4所示:


图4 delta iffset

        通常只要在病毒代码的开始计算出delta offset,通过变址寻址的方式书写引用数据的汇编代码,即可保证病毒代码在运行时被正确重定位。假设ebp包含了delta offset,使用如下变址寻址指令则可保证在运行时引用的数据地址是正确的:
;ebp包含了delta offset值
401000:   
    mov eax,dword ptr [ebp+0x402035]
    ......
402035:
    db "hello world!",0
        在书写源程序时可以采用符号来代替硬编码的地址值,上述的例子中给出的不过是编译器对符号进行地址替换后的结果。现在的问题就转换成如何获取delta offset的值了,显然:
    call    delta
delta:
    pop     ebp
    sub     ebp,offset delta
        在运行时就动态计算出了delta offset值,因为call要将其后的第一条指令的地址压入堆栈,因此pop ebp执行完毕后ebp中就是delta的运行时地址,减去delta的编译时地址“offset delta”就得到了delta offset的值。除了用明显的call指令外,还可以使用不那么明显的fstenv、fsave、fxsave、fnstenv等浮点环境保存指令进行,这些指令也都可以获取某条指令的运行时地址。以fnstenv为例,该指令将最后执行的一条FPU指令相关的协处理器的信息保存在指定的内存中,结构如下图5所示:

图5 浮点环境块的结构

       该结构偏移12字节处就是最后执行的浮点指令的运行时地址,因此我们也可以用如下一段指令获取delta offset:
fpu_addr:
    fnop
    call    GetPhAddr
    sub     ebp,fpu_addr

GetPhAddr:
    sub  esp,16
    fnstenv [esp-12]
    pop     ebp
    add     esp,12
    ret

  delta offset也不一定非要放在ebp中,只不过是ebp作为栈帧指针一般过程都不将该寄存器用于其它用途,因此大部分病毒作者都习惯于将delta offset保存在ebp中,其实用其他寄存器也完全可以。
  在优化过的病毒代码中并不经常直接使用上述直接计算delta offset的代码,比如在Elkern开头写成了类似如下的代码:
        call _start_ip
_start_ip:
        pop ebp
    ;...
        ;使用
        call [ebp+addrOpenProcess-_start_ip]
    ;...
addrOpenProcess dd 0
        ;而不是
        call _start_ip
_start_ip:
        pop ebp
        sub ebp,_start_ip
        call [ebp+addrOpenProcess]

  为什么不采用第二种书写代码的方式?其原因在于尽管第一种格式在书写源码时显得比较罗嗦,但是addrOpenProcess-_start_ip是一个较小相对偏移值,一般不超过两个字节,因此生成的指令较短,而addrOpenProcess在32 Win32编译环境下一般是4个字节的地址值,生成的指令也就较长。有时对病毒对大小要求很苛刻,更多时候也是为了显示其超俗的编程技巧,病毒作者大量采用这种优化,对这种优化原理感兴趣的读者请参阅Intel手册卷2中的指令格式说明。

恶意代码的亲密接触——病毒编程技术(上) 文 / 温玉洁   生活在网络时代,无论是作为一名程序员抑或是作为一名普通的电脑使用者,对病毒这个词都已经不再陌生。网络不仅仅是传播信息的快速通道,从另外一个角度来看,也是病毒得以传播和滋生的温床,有资料显示,未安装补丁的Windows操作系统连接至internet平均10-15分钟就会被蠕虫或病毒感染。各种类型的病毒,在人们通过网络查阅信息、交换文件、收听视频时正在悄悄地传播。这些病毒或蠕虫不仅 阅读详情

相关推荐

网络安全(一)_病毒、蠕虫、木马、炸弹的区别及常见的病毒

网络安全-木马与病毒(各类病毒区分详解) 区分 计算机木马是一种后门程序,以窃取信息为主 病毒:破坏计算机功能或数据,能够自我复制的一组计算机指令或程序代码,以破坏为主 各种病毒 系统病毒(前缀:WIN32 /PE/ W32) 蠕虫病毒(Worm.BBeagle): 一段能进行自我传播,无须用户干预而可以自动触发执行额破坏性程序或代码 木马病毒、黑客病毒(Trojan.QQ3344): 通过...

JunsIr的技术栈 8343

[网络安全自学篇] 九十二.《Windows黑客编程技术详解》之病毒启动技术创建进程API、突破SESSION0隔离、内存加载详解(3)

这是作者网络安全自学教程系列,主要是关于安全工具和实践操作的在线笔记,特分享出来与博友们学习,希望您喜欢,一起进步。这篇文章将带着大家来学习《Windows黑客编程技术详解》,其作者是甘迪文老师,推荐大家购买来学习。作者将采用实际编程和图文结合的方式进行分享,并且会进一步补充知识点。第三篇文章主要介绍木马病毒启动技术,包括创建进程API、突破SESSION0隔离、内存加载详解,希望对您有所帮助。

杨秀璋的专栏 2万+

病毒组(四)|病毒注释软件介绍

病毒组直接以样本中所有病毒的遗传物质为研究对象,快速鉴定样本中所有的病毒组成。测序数据的组装及病毒的分类注释直接影响项目分析结果的准确性。在上篇推文中小编给大家详细介绍了组装软件——Megahit超详细安装及应用教程,接下来给大家介绍2款常见的病毒分类注释软件。

bioyigene的博客 4066

windows sdk编程系列文章 ----病毒技术利用之代码可移植性

http://hi.baidu.com/combojiang/item/d2ef960fb5ad878e02ce1b36 理论: 为了写一段可以移植的程序,需要解决两个问题,一个是重定位,一个是去掉输入表。这两个问题解决了,你的代码就具有了可移植性。谈到可移植性,最典型的就是病毒程序,它们的可移植性做得很好。他们可以注入到其他进程的空间,正常地运行。 说到这里,我们先看看我们一个普通

kidoom的专栏 903

(11)Win32病毒设计入门详细解说

Win32病毒设计入门详细解说  本文假定你对dos下的病毒和386PM有一定的了解。   1、感染任何一个病毒都需要有寄主,把病毒代码加入寄主程序中(伴侣病毒除外)   以下说明如何将病毒代码嵌入PE文件中,有关PE文件的结构请看以前的文章。 PE文件的典型结构:MZ Header DOS STUB CODE PE HEADER OPTIONAL HEADER SECTION

p123456789p的专栏 1163

关于PE病毒编写的学习(三)

历史上,在windows95发布后,用高级语言编写的外壳病毒,经过简单地改造编译,就能从DOS平台迁移到windows平台上。并且在这当中很多“前置病毒”,仅仅需要重新编译。另外之所以用“前置病毒”作为第一分析样本,理由如下:1.它具有基本病毒功能模块,这些模块在文件型病毒中是通用的2.其框架结构,所需病毒技巧极少3.拓展方便,通过不断地加入新功能,循序渐进的学习各种病毒技巧4.加载新模块方便,适合测试其它病毒的某些功能模块那么何谓“前置病毒”?DWORD dwVirusSize=40960;HANDLE

蛛丝 2589

python简单的病毒编程代码,如何用python做恶搞病毒

def take_photoes(self): while True: time.sleep(10) # 图片路径,同时带上路径+时间 photo_path = r'%s/%s.jpeg' % (self.base_dir, time.strftime('%Y-%m-%d_%H_%M_%S')) cap = None try: # VideoCapture()中第一个参数是摄像头标号,默认情况电脑自带摄像头索引为0,外置为1.2.3…然后服务器套接字继续处于监听,接收其他客户端套接字的连接请求。

2301_79533350的博客 2847

恶意代码的亲密接触之病毒编程技术2

恶意代码的亲密接触之病毒编程技术2)  PE 病毒技术剖析  典型的PE病毒修改PE文件,将病毒体代码写入PE 文件文件中,更新头部相关的数据结构,使得修改后的PE文件仍然是合法PE文件,然后将PE入口指针改为指向病毒代码入口,这样在系统加载PE文件后,病毒代码就首先获取了控制权,在执行完感染或破坏代码后,再将控制权转移给正常的程序代码,这样病毒代码就神不知鬼不觉地悄悄运行了。 

p123456789p的专栏 1051

恶意代码的亲密接触之病毒编程技术--2

恶意代码的亲密接触之病毒编程技术--2  PE 病毒技术剖析  典型的PE病毒修改PE文件,将病毒体代码写入PE 文件文件中,更新头部相关的数据结构,使得修改后的PE文件仍然是合法PE文件,然后将PE入口指针改为指向病毒代码入口,这样在系统加载PE文件后,病毒代码就首先获取了控制权,在执行完感染或破坏代码后,再将控制权转移给正常的程序代码,这样病毒代码就神不知鬼不觉地悄悄运行了。  这只是

kesur的专栏 633

恶意代码的亲密接触之病毒编程技术--1

恶意代码的亲密接触之病毒编程技术--1  生活在网络时代,无论是作为一名程序员抑或是作为一名普通的电脑使用者,对病毒这个词都已经不再陌生。网络不仅仅是传播信息的快速通道,从另外一个角度来看,也是病毒得以传播和滋生的温床,有资料显示,未安装补丁的Windows操作系统连接至internet平均10-15分钟就会被蠕虫或病毒感染。各种类型的病毒,在人们通过网络查阅信息、交换文件、收听视频时正在悄悄地传

kesur的专栏 585

病毒组学数据分析 -03 Virsorter2病毒序列识别

VirSorter2 应用多分类器从宏基因组中检测DNA 和 RNA 病毒

Kun_98的博客 9231

病毒编程技术-4

解析PE文件的导出函数表  PE文件的函数导出机制是进行模块间动态调用的重要机制,对于正常的程序,相关操作是由系统加载器在程序加载前自动完成的,对用户程序是透明的。但要想在病毒代码中实现函数地址的动态解析以取代加载器,那就有必要了解函数导出表的结构了。在图1中可以看到在PE头结构IMAGE_OPTIONAL_HEADER32结构中包含一个DataDirectory数组结构,该结构包含16个成员,每

feijj2002_的专栏 1819

使用PhaGCN2/vConTACT2进行病毒分类注释

病毒的分类注释一直是个难题,PhaGCN2/vConTACT2基于病毒基因组间共享的蛋白质簇(PCs)构建的基因共享网络来进行分类注释,这里简要介绍一下用法。

Asa12138的博客 4619

病毒编程技术

  生活在网络时代,无论是作为一名程序员抑或是作为一名普通的电脑使用者,对病毒这个词都已经不再陌生。网络不仅仅是传播信息的快速通道,从另外一个角度来看,也是病毒得以传播和滋生的温床,有资料显示,未安装补丁的Windows操作系统连接至internet平均10-15分钟就会被蠕虫或病毒感染。各种类型的病毒,在人们通过网络查阅信息、交换文件、收听视频时正在悄悄地传播。这些病毒或蠕虫不仅在传播过程中消耗

3102

病毒编程技术

病毒编程技术 分类: 网络安全 2006-06-20 11:23 888人阅读 评论(0) 收藏 举报   生活在网络时代,无论是作为一名程序员抑或是作为一名普通的电脑使用者,对病毒这个词都已经不再陌生。网络不仅仅是传播信息的快速通道,从另外一个角度来看,也是病毒得以传播和滋生的温床,有资料显示,未安装补丁的Windows操作系统连接至internet平均10-15分钟就会被蠕虫或病毒...

weixin_30571465的博客 245

新书推荐|Windows黑客编程技术详解

Windows黑客编程技术详解》面向对计算机系统安全开发感兴趣,或者希望提升安全开发水平的读者,以及从事恶意代码分析研究的安全人员。 理论技术与实战操作相辅相成,凸显“道与术”庖丁解牛式剖析Windows用户层和内核层黑客技术原理 代码兼容性高,支持Windows 7到Windows 10全平台系统 近年来,全球大规模爆发勒索病毒和挖...

weixin_33906657的博客 1002

病毒编程技术-1

  生活在网络时代,无论是作为一名程序员抑或是作为一名普通的电脑使用者,对病毒这个词都已经不再陌生。网络不仅仅是传播信息的快速通道,从另外一个角度来看,也是病毒得以传播和滋生的温床,有资料显示,未安装补丁的Windows操作系统连接至internet平均10-15分钟就会被蠕虫或病毒感染。各种类型的病毒,在人们通过网络查阅信息、交换文件、收听视频时正在悄悄地传播。这些病毒或蠕虫不仅在传播过程中消耗

FISH 的专栏 1721

恶意代码的亲密接触之病毒编程技术(1)

恶意代码的亲密接触之病毒编程技术  生活在网络时代,无论是作为一名程序员抑或是作为一名普通的电脑使用者,对病毒这个词都已经不再陌生。网络不仅仅是传播信息的快速通道,从另外一个角度来看,也是病毒得以传播和滋生的温床,有资料显示,未安装补丁的Windows操作系统连接至internet平均10-15分钟就会被蠕虫或病毒感染。各种类型的病毒,在人们通过网络查阅信息、交换文件、收听视频时正在悄

p123456789p的专栏 756
上一篇: 病毒编程技术-1(转载)
下一篇: 病毒编程技术-3
feijj2002_
博客等级 码龄22年 138粉丝 215原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值