汇编源代码之CIH文件型病毒检测消除程序
2009-01-28 09:37:12 来源:WEB开发网核心提示:;本程序在Tasm下编译通过;CIH文件型病毒检测消除程序GOFIRST MACROXOR CX,CXXOR DX,DXMOV AX,4200HINT 21H;文件指针指到文件首ENDMALTERLINE MACROMOV DL,0DHMOV AH,02HINT 21H;回车MOV DL,0AHMOV AH,02HIN
;本程序在Tasm下编译通过
;CIH文件型病毒检测消除程序
GOFIRST MACRO
XOR CX,CX
XOR DX,DX
MOV AX,4200H
INT 21H ;文件指针指到文件首
ENDM
ALTERLINE MACRO
MOV DL,0DH
MOV AH,02H
INT 21H ;回车
MOV DL,0AH
MOV AH,02H
INT 21H ;换行
ENDM
COPYHANDLE MACRO
PUSH BX
MOV AH,45H
INT 21H ;复制文件把柄
MOV BX,AX
MOV AH,3EH
INT 21H ;关闭复制文件
POP BX
ENDM
DATA SEGMENT PARA PUBLIC 'DATA'
EXEFILE DB '*.EXE',00
DIRFILE DB '*.*',00
FILEBZ DB 00 ;文件标志(COM:00;EXE:FF)
DISKSGN DB 00 ;检测盘号
CURRDISK DB 00 ;当前盘号
DISKCHA DB 00,3AH,24H
DAT DB 256 DUP(24H) ;磁盘传送地址DISK TRANSPORT AREA
OVERMSG DB '所有CIH病毒已被清除!!!',0DH,0AH,24H
FILESUF DB 2000 DUP(0) ;存放被检测文件部份内容
PE_HEAD DB 4 DUP(0) ;存放PE HEAD指针
VIRSUF DB 1024 DUP(0) ;存放CIH病毒头块程序
VIRPOINT DB 4 DUP(0) ;存放CIH 首块及链表区首指针
SECNUM DB 00,00 ;Number of FILE SECTIONS
T_ENTRY DB 4 DUP(0) ; true Entry RVA
FILEMSG DB ' ( CIH virus) ',24H
CLEAMSG DB ' killed !!',0DH,0AH,24H
CL_ZERO DB 1024 DUP(0) ;清零数据
HZSM DB '正在扫描: ',24H
BLANK DB 60 DUP(20H),24H ;送空格
INITDIR DB "",64 DUP(0) ;初始目录
CURRDIR DB " PE",00,63 DUP(24H) ;当前目录
UPDIR DB "..",00 ;上一级目录
DIRSUFF DB 4096 DUP(0) ;目录参数保留区
DIRSUFP DB 00,00 ;目录参数保留区指针
DIRNUM DB 01,00 ;盘中目录文件个数
EXENUM DB 00,00 ;盘中EXE文件个数
VIREXE DB 00,00 ;感染病毒EXE文件个数
DIRMSG DB "subdirectory number:",24H
EXEMSG DB "*.EXE numbers:",24H
ERRMSG DB "; which affected:",24H
DECSUF DB 11 DUP(0) ;二进制->十进制数存放区
TITL DB "CIH CLEAN ASM SOURCECODE TESTING",0dh,0ah
DB "kuibing kuibing@163.com",0DH,0AH,0dh,0ah
DB "The virus is a Parastic Virus which infects Windows 95/98 .EXE files",0DH,
0AH
DB 0DH,0AH,0dh,0ah,24H
BEGIN DB 07H,07H,"按任意键开始检测/清除病毒!!",0dh,0ah,24h
DATA ENDS
CODE SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK
KILLCIH PROC FAR
MOV DI,0082H
MOV DL,[DI]
dec di
mov bl,[di]
PUSH DS
XOR AX,AX
PUSH AX
PUSH DS
MOV AX,DATA
MOV DS,AX
MOV ES,AX
MOV AX,STACK
MOV SS,AX
;确定检测盘号
cmp bl,0dh
jz disk2
AND DL,05FH
CMP DL,41H
JNZ DISK1
MOV BYTE PTR[DISKSGN],01H
MOV BYTE PTR[DISKCHA],41H
JMP DISK2
DISK1: CMP DL,42H
JNZ DISK3
MOV BYTE PTR[DISKSGN],02H
MOV BYTE PTR[DISKCHA],42H
JMP DISK2
DISK3: CMP DL,43H
JNZ DISK2
MOV BYTE PTR[DISKSGN],03H
MOV BYTE PTR[DISKCHA],43H
DISK2: MOV AH,19H
INT 21H ;取当前盘号
MOV BYTE PTR[CURRDISK],AL ;保存当前盘号
;
CMP BYTE PTR[DISKSGN],00H
JNZ DISK4
ADD AL,41H
MOV BYTE PTR[DISKCHA],AL
JMP DISK5
;
DISK4: MOV DL,BYTE PTR[DISKSGN]
DEC DL
MOV AH,0EH
INT 21H ;选择磁盘驱动器
;
DISK5: PUSH ES
MOV AX,0040H
MOV ES,AX
MOV DI,0087H
MOV AL,ES:[DI]
POP ES
CMP AL,00H
JZ CGA
MOV AX,0003H
JMP CLS
CGA: MOV AX,0006H
CLS: INT 10H ;清屏
MOV AH,09H
MOV DX,OFFSET TITL
INT 21H
MOV DX,OFFSET DAT ;磁盘传送首址->DX
MOV AH,1AH
INT 21H ;CREAT DAT
MOV AH,47H
MOV DL,BYTE PTR[DISKSGN]
MOV SI,OFFSET INITDIR+1
INT 21H ;保存初始目录名
MOV AH,3BH
MOV DX,OFFSET CURRDIR
INT 21H ;回到根目录
MOV BYTE PTR[FILEBZ],0FFH ;置EXE文件标志
MOV DX,OFFSET EXEFILE
;
CALL CLEA_VIRUS ;chesk and clear CIH virus
CALL CLE_SDIR ;检测各子目录下文件及消除
;
MOV AH,3BH
MOV DX,OFFSET INITDIR
INT 21H ;恢复初始目录
MOV DL,BYTE PTR[CURRDISK]
MOV AH,0EH
INT 21H ;选择磁盘驱动器
DONE: ALTERLINE
MOV DX,OFFSET OVERMSG
MOV AH,09H
INT 21H
MOV DX,OFFSET DIRMSG
MOV AH,09H
INT 21H
MOV DI,OFFSET DIRNUM
CALL BTOD ;显示目录个数
ALTERLINE
MOV DX,OFFSET EXEMSG
MOV AH,09H
INT 21H
MOV DI,OFFSET EXENUM
CALL BTOD ;显示EXE文件个数
MOV DX,OFFSET ERRMSG
MOV AH,09H
INT 21H
MOV DI,OFFSET VIREXE
CALL BTOD ;显示病毒EXE文件个数
ALTERLINE
MOV CX,0200H
MOV AH,01H
INT 10H ;恢复光标
MOV AH,4CH
INT 21H ;结束程序退回DOS
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;Key programm;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CLEA_VIRUS PROC NEAR ;在同一子目下搜寻EXE文件并检测是否存在病毒以及消除
MOV CX,027H
MOV AH,4EH
INT 21H ;搜寻第一匹配文件
JNC LOOK
JMP EXIT ;没找到,->EXIT
LOOK: INC BYTE PTR[EXENUM]
MOV DX,OFFSET HZSM
MOV AH,09H
INT 21H
MOV DX,OFFSET DISKCHA
MOV AH,09H
INT 21H
MOV DX,OFFSET CURRDIR
MOV AH,09H
INT 21H ;显示当前目录路径
MOV DI,OFFSET CURRDIR+1
CMP BYTE PTR[DI],00H
JZ ZJS1
MOV AH,02H
MOV DL,5CH
INT 21H
ZJS1: MOV DX,OFFSET DAT
ADD DX,1EH ;DX:匹配文件名首址
PUSH DX
PUSH DX
POP DI
BZ5: INC DI
CMP BYTE PTR[DI],00H
JNZ BZ5
INC DI
MOV BYTE PTR[DI],24H
POP DX
MOV AH,09H
INT 21H ;显示文件名
MOV DX,OFFSET DAT
ADD DX,1EH
MOV AX,3D02H
INT 21H ;打开匹配文件
JNB CL0
JMP NEXTFILE
;;;;;;;;;;;;;
CL0: MOV BX,AX
MOV AX,4200H
MOV CX,00H
MOV DX,3CH
INT 21H ;文件指针移到文件头第3CH字节
MOV DX,OFFSET FILESUF ;文件缓冲区首址->DX
MOV CX,04H
MOV AH,3FH
INT 21H ;读入4个字节(File address of new exe header)
JNB CL1
JMP NEXTFILE
CL1: MOV AX,4200H
MOV CX,WORD PTR[FILESUF+2]
MOV DX,WORD PTR[FILESUF]
MOV WORD PTR[PE_HEAD],DX ;保存PE FILE HEAD 指针
MOV WORD PTR[PE_HEAD+2],CX
DEC DX
INT 21H ;文件指针移到new exe header-1
MOV DX,OFFSET FILESUF ;文件缓冲区首址->DX
MOV CX,0200H
MOV AH,3FH
INT 21H ;读入512个字节(PE File Signature)
JNB CL2
JMP NEXTFILE
CL2: CMP WORD PTR[FILESUF+1],04550H ;see if is "PE" format file
JZ CL21
JMP NEXTFILE
CL21: CMP BYTE PTR[FILESUF],00H
JNZ CL3 ;"XPE" May have CIH viurs
JMP NEXTFILE ;NOT BEEN INFECTED CIH VIRUS
CL3: MOV CX,WORD PTR[FILESUF+07H] ;Get Number of Sections
MOV WORD PTR[SECNUM],CX
INC CX
SHL CX,1
SHL CX,1
SHL CX,1
PUSH CX ;(Section 数+1)*8 =病毒块指针区大小
POP DI
;get PE FILE Entry RVA
MOV CX,WORD PTR[FILESUF+2BH] ;
MOV DX,WORD PTR[FILESUF+29H] ;[FILESUF+29,2A,2B,2CH]=Entry RVA
CMP CX,WORD PTR[FILESUF+57H] ;[FILESUF+55,56,57,58H]=File Header Size
JE CL4
JB CL5 ;Maybe has CIH virus
JMP NEXTFILE
CL4: CMP DX,WORD PTR[FILESUF+55H]
JB CL5 ;Maybe has CIH virus
JMP NEXTFILE
CL5: SUB DX,DI
MOV WORD PTR[VIRPOINT],DX
MOV WORD PTR[VIRPOINT+2H],CX ;Save CIH first block point
MOV AX,4200H
INT 21H ;文件指针移到FILE Entry address-病毒块指针区大小(DI)
MOV DX,OFFSET VIRSUF ;病毒缓冲区首址->DX
MOV CX,100H
MOV AH,3FH
INT 21H ;读入100H个字节
JNB CL6
JMP NEXTFILE
CL6: CMP WORD PTR[VIRSUF+DI+36H],056CCH
JZ CL7 ;May CIH virus
JMP NEXTFILE
CL7: CMP WORD PTR[VIRSUF+DI+4BH],0FBCCH
JZ CL8 ;Sure CIH virus
JMP NEXTFILE
CL8: MOV DX,OFFSET FILEMSG
MOV AH,09H
INT 21H ;显示有病毒
MOV AX,4301H
MOV CX,0020H
MOV DX,OFFSET DAT
ADD DX,1EH
INT 21H ;置文件属性为归档
;
;Save true Entry RVA
MOV AX,WORD PTR[VIRSUF+DI+5EH]
MOV WORD PTR[T_ENTRY],AX
MOV AX,WORD PTR[VIRSUF+DI+60H]
MOV WORD PTR[T_ENTRY+2H],AX
;
MOV DX,WORD PTR[VIRPOINT]
MOV CX,WORD PTR[VIRPOINT+2H] ;GET CIH first block point
MOV AX,4200H
INT 21H ;文件指针移到FILE Entry address-病毒块指针区大小
;
MOV CX,WORD PTR[VIRSUF+DI-04H] ;取CIH病毒首块长度
ADD CX,DI ;加上CIH病毒链表指针块区大小
MOV DX,OFFSET CL_ZERO
MOV AH,40H
INT 21H ;病毒首块及链表指针区清零
;
;;;;;;;;;;;;;;;;;;;;;;
;Clear other block viurs
; omitted
;;;;;;;;;;;;;;;;;;;;;;
;
;Restore True Entry RVA(Address of Entry Point)
MOV AX,4200H
MOV CX,WORD PTR[PE_HEAD+2]
MOV DX,WORD PTR[PE_HEAD]
ADD DX,28H
ADC CX,0
INT 21H ;文件指针移到文件头的Entry Point
MOV DX,OFFSET FILESUF ;文件缓冲区首址->DX
; MOV CX,4H
; MOV AH,3FH
; INT 21H ;读入Entry Point
; JNB CL11
; JMP NEXTFILE
CL11: MOV CX,WORD PTR[T_ENTRY]
MOV WORD PTR[FILESUF],CX
MOV CX,WORD PTR[T_ENTRY+2]
MOV WORD PTR[FILESUF+2],CX
MOV CX,2H
MOV AH,40H
INT 21H ;将正常的Entry 参数写回
JB NEXTFILE
COPYHANDLE
MOV SI,[OFFSET DAT+15H]
MOV CL,[SI]
MOV AX,4301H
MOV DX,OFFSET DAT
ADD DX,1EH
INT 21H ;恢复文件原属性
JB NEXTFILE
MOV DX,OFFSET DAT
MOV SI,WORD PTR[OFFSET DAT+16H]
MOV DI,WORD PTR[OFFSET DAT+18H]
MOV CX,[SI]
MOV DX,[DI]
MOV AX,5701H
INT 21H ;恢复文件原建立日期
MOV DX,OFFSET CLEAMSG
MOV AH,09H
INT 21H
INC BYTE PTR[VIREXE]
NEXTfile:MOV AH,3EH
INT 21H
CLD
MOV DI,OFFSET DAT
ADD DI,1EH
MOV CX,0EH
MOV AL,24H
REPZ STOSB
MOV DI,OFFSET FILESUF
MOV CX,600H
MOV AL,00
REPZ STOSB ;清文件缓冲区
MOV CX,0FFFFH
BZ6: LOOP BZ6
MOV CX,0FFFFH
BZ7: LOOP BZ7
MOV CX,0FFFFH
BZ8: LOOP BZ8
MOV CX,0FFFFH
BZ9: LOOP BZ9
MOV DL,0DH
MOV AH,02H
INT 21H ;只回车
MOV DX,OFFSET HZSM
MOV AH,09H
INT 21H
MOV DX,OFFSET DISKCHA
MOV AH,09H
INT 21H
MOV DX,OFFSET BLANK
MOV AH,09H
INT 21H
MOV DL,0DH
MOV AH,02H
INT 21H ;回车
MOV AH,4FH
INT 21H
JC EXIT
JMP LOOK
EXIT: RET
CLEA_VIRUS ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
CLE_SDIR PROC NEAR ;搜寻各子目EXE文件并检测是否存在病毒以及消除
CL_SUBD:MOV DX,OFFSET DIRFILE
MOV CX,0010H
MOV AH,4EH
INT 21H ;搜寻第一匹配文件
JNC LOOKS
JMP EXITS ;没找到,->EXITS
LOOKS: MOV SI,OFFSET DAT
ADD SI,15H
CMP BYTE PTR[SI],10H
JZ NEXT1
JMP NEXTSUB
NEXT1: MOV BX,OFFSET DAT
ADD BX,1EH ;BX:匹配文件名首址
CMP BYTE PTR[BX],2EH ;是否是“.”或“..”子目录
JNZ SUB1
JMP NEXTSUB
SUB1: INC [DIRNUM] ;子目录数量加1
CLD
MOV SI,OFFSET DAT
MOV DI,OFFSET DIRSUFF
ADD DI,WORD PTR[DIRSUFP]
MOV CX,0015H
REPZ MOVSB ;保存当前目录参数
ADD WORD PTR[DIRSUFP],0015H ;目录参数指针+15H
MOV DI,OFFSET CURRDIR+1
CMP BYTE PTR[DI],00H
JZ LP2
LP1: INC DI
CMP BYTE PTR[DI],00H
JNZ LP1 ;找当前子目录名路径尾
MOV BYTE PTR[DI],5CH
INC DI
LP2: MOV SI,BX
MOV CX,0DH
REPZ MOVSB
MOV DX,OFFSET CURRDIR
MOV AH,3BH
INT 21H ;进入下一级子目录
CLD
MOV DI,OFFSET CURRDIR+1
MOV CX,003FH
MOV AL,24H
REPZ STOSB
MOV AH,47H
MOV DL,BYTE PTR[DISKSGN]
MOV SI,OFFSET CURRDIR+1
INT 21H ;取当前子目录
MOV BYTE PTR[FILEBZ],0FFH ;置EXE文件标志
MOV DX,OFFSET EXEFILE
CALL CLEA_VIRUS ;chesk and clear CIH virus
JMP CL_SUBD ;查找当前子目录下一级目录及EXE文件
EXITS: MOV BX,OFFSET CURRDIR+1
CMP BYTE PTR[BX],00 ;判当前目录为根目录否
JNZ SUB2
JMP OVERS ;当前目录为根目录->OVERS
SUB2: MOV AH,3BH
MOV DX,OFFSET UPDIR
INT 21H ;返回上一子目录
MOV AH,47H
MOV DL,BYTE PTR[DISKSGN]
MOV SI,OFFSET CURRDIR+1
INT 21H ;取当前子目录
STD
MOV SI,OFFSET DIRSUFF-1H
ADD SI,WORD PTR[DIRSUFP]
MOV DI,OFFSET DAT+14H
MOV CX,0015H
REPZ MOVSB
SUB WORD PTR[DIRSUFP],0015H ;恢复当前子目录参数及指针
NEXTSUB:MOV AH,4FH
INT 21H
JC EXITS
JMP LOOKS
OVERS: RET
CLE_SDIR ENDP
;
;
BTOD PROC NEAR ;将[DI]中2进制数转换成十进制数显示
MOV WORD PTR[DECSUF+10H],OFFSET DECSUF
MOV DX,0000H
MOV AX,[DI]
;DX=数值的高位;AX=数值的低位
PUSH AX
POP SI
PUSH DX
POP DI
PUSH BP
PUSH BX
XOR AX,AX
MOV BX,AX
MOV BP,AX
MOV CX,0020H
BTOD1: SHL SI,1
RCL DI,1
XCHG BP,AX
ADC AL,AL
DAA
XCHG AH,AL
ADC AL,AL
DAA
XCHG AH,AL
XCHG BP,AX
XCHG BX,AX
ADC AL,AL
DAA
XCHG AH,AL
ADC AL,AL
DAA
XCHG AH,AL
XCHG BX,AX
ADC AL,00
LOOP BTOD1
MOV CX,1810H
XCHG DX,AX
CALL BTOD2
XCHG BX,AX
CALL BTOD3
MOV AX,BP
CALL BTOD3
MOV BYTE PTR[DECSUF+0BH],24H
MOV AH,09H
MOV DX,OFFSET DECSUF
INT 21H
JMP BTOD6
BTOD3 PROC NEAR
PUSH AX
MOV DL,AH
CALL BTOD7
POP DX
BTOD7 PROC NEAR
MOV DH,DL
SHR DL,1
SHR DL,1
SHR DL,1
SHR DL,1
CALL BTOD2
MOV DL,DH
BTOD2 PROC NEAR
AND DL,0FH
JZ BTOD8
MOV CL,00
BTOD8: DEC CH
AND CL,CH
OR DL,30H
SUB DL,CL
PUSH DI
MOV DI,WORD PTR[DECSUF+10H]
MOV [DI],DL
INC DI
MOV WORD PTR[DECSUF+10H],DI
POP DI
RET
BTOD2 ENDP
BTOD7 ENDP
BTOD3 ENDP
BTOD6: POP BX
POP BP
RET
BTOD ENDP
;
;
KILLCIH ENDP
;
CODE ENDS
STACK SEGMENT PARA STACK 'STACK'
DB 256 DUP(?)
STACK ENDS
END KILLCIH
;CIH文件型病毒检测消除程序
GOFIRST MACRO
XOR CX,CX
XOR DX,DX
MOV AX,4200H
INT 21H ;文件指针指到文件首
ENDM
ALTERLINE MACRO
MOV DL,0DH
MOV AH,02H
INT 21H ;回车
MOV DL,0AH
MOV AH,02H
INT 21H ;换行
ENDM
COPYHANDLE MACRO
PUSH BX
MOV AH,45H
INT 21H ;复制文件把柄
MOV BX,AX
MOV AH,3EH
INT 21H ;关闭复制文件
POP BX
ENDM
DATA SEGMENT PARA PUBLIC 'DATA'
EXEFILE DB '*.EXE',00
DIRFILE DB '*.*',00
FILEBZ DB 00 ;文件标志(COM:00;EXE:FF)
DISKSGN DB 00 ;检测盘号
CURRDISK DB 00 ;当前盘号
DISKCHA DB 00,3AH,24H
DAT DB 256 DUP(24H) ;磁盘传送地址DISK TRANSPORT AREA
OVERMSG DB '所有CIH病毒已被清除!!!',0DH,0AH,24H
FILESUF DB 2000 DUP(0) ;存放被检测文件部份内容
PE_HEAD DB 4 DUP(0) ;存放PE HEAD指针
VIRSUF DB 1024 DUP(0) ;存放CIH病毒头块程序
VIRPOINT DB 4 DUP(0) ;存放CIH 首块及链表区首指针
SECNUM DB 00,00 ;Number of FILE SECTIONS
T_ENTRY DB 4 DUP(0) ; true Entry RVA
FILEMSG DB ' ( CIH virus) ',24H
CLEAMSG DB ' killed !!',0DH,0AH,24H
CL_ZERO DB 1024 DUP(0) ;清零数据
HZSM DB '正在扫描: ',24H
BLANK DB 60 DUP(20H),24H ;送空格
INITDIR DB "",64 DUP(0) ;初始目录
CURRDIR DB " PE",00,63 DUP(24H) ;当前目录
UPDIR DB "..",00 ;上一级目录
DIRSUFF DB 4096 DUP(0) ;目录参数保留区
DIRSUFP DB 00,00 ;目录参数保留区指针
DIRNUM DB 01,00 ;盘中目录文件个数
EXENUM DB 00,00 ;盘中EXE文件个数
VIREXE DB 00,00 ;感染病毒EXE文件个数
DIRMSG DB "subdirectory number:",24H
EXEMSG DB "*.EXE numbers:",24H
ERRMSG DB "; which affected:",24H
DECSUF DB 11 DUP(0) ;二进制->十进制数存放区
TITL DB "CIH CLEAN ASM SOURCECODE TESTING",0dh,0ah
DB "kuibing kuibing@163.com",0DH,0AH,0dh,0ah
DB "The virus is a Parastic Virus which infects Windows 95/98 .EXE files",0DH,
0AH
DB 0DH,0AH,0dh,0ah,24H
BEGIN DB 07H,07H,"按任意键开始检测/清除病毒!!",0dh,0ah,24h
DATA ENDS
CODE SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK
KILLCIH PROC FAR
MOV DI,0082H
MOV DL,[DI]
dec di
mov bl,[di]
PUSH DS
XOR AX,AX
PUSH AX
PUSH DS
MOV AX,DATA
MOV DS,AX
MOV ES,AX
MOV AX,STACK
MOV SS,AX
;确定检测盘号
cmp bl,0dh
jz disk2
AND DL,05FH
CMP DL,41H
JNZ DISK1
MOV BYTE PTR[DISKSGN],01H
MOV BYTE PTR[DISKCHA],41H
JMP DISK2
DISK1: CMP DL,42H
JNZ DISK3
MOV BYTE PTR[DISKSGN],02H
MOV BYTE PTR[DISKCHA],42H
JMP DISK2
DISK3: CMP DL,43H
JNZ DISK2
MOV BYTE PTR[DISKSGN],03H
MOV BYTE PTR[DISKCHA],43H
DISK2: MOV AH,19H
INT 21H ;取当前盘号
MOV BYTE PTR[CURRDISK],AL ;保存当前盘号
;
CMP BYTE PTR[DISKSGN],00H
JNZ DISK4
ADD AL,41H
MOV BYTE PTR[DISKCHA],AL
JMP DISK5
;
DISK4: MOV DL,BYTE PTR[DISKSGN]
DEC DL
MOV AH,0EH
INT 21H ;选择磁盘驱动器
;
DISK5: PUSH ES
MOV AX,0040H
MOV ES,AX
MOV DI,0087H
MOV AL,ES:[DI]
POP ES
CMP AL,00H
JZ CGA
MOV AX,0003H
JMP CLS
CGA: MOV AX,0006H
CLS: INT 10H ;清屏
MOV AH,09H
MOV DX,OFFSET TITL
INT 21H
MOV DX,OFFSET DAT ;磁盘传送首址->DX
MOV AH,1AH
INT 21H ;CREAT DAT
MOV AH,47H
MOV DL,BYTE PTR[DISKSGN]
MOV SI,OFFSET INITDIR+1
INT 21H ;保存初始目录名
MOV AH,3BH
MOV DX,OFFSET CURRDIR
INT 21H ;回到根目录
MOV BYTE PTR[FILEBZ],0FFH ;置EXE文件标志
MOV DX,OFFSET EXEFILE
;
CALL CLEA_VIRUS ;chesk and clear CIH virus
CALL CLE_SDIR ;检测各子目录下文件及消除
;
MOV AH,3BH
MOV DX,OFFSET INITDIR
INT 21H ;恢复初始目录
MOV DL,BYTE PTR[CURRDISK]
MOV AH,0EH
INT 21H ;选择磁盘驱动器
DONE: ALTERLINE
MOV DX,OFFSET OVERMSG
MOV AH,09H
INT 21H
MOV DX,OFFSET DIRMSG
MOV AH,09H
INT 21H
MOV DI,OFFSET DIRNUM
CALL BTOD ;显示目录个数
ALTERLINE
MOV DX,OFFSET EXEMSG
MOV AH,09H
INT 21H
MOV DI,OFFSET EXENUM
CALL BTOD ;显示EXE文件个数
MOV DX,OFFSET ERRMSG
MOV AH,09H
INT 21H
MOV DI,OFFSET VIREXE
CALL BTOD ;显示病毒EXE文件个数
ALTERLINE
MOV CX,0200H
MOV AH,01H
INT 10H ;恢复光标
MOV AH,4CH
INT 21H ;结束程序退回DOS
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;Key programm;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
CLEA_VIRUS PROC NEAR ;在同一子目下搜寻EXE文件并检测是否存在病毒以及消除
MOV CX,027H
MOV AH,4EH
INT 21H ;搜寻第一匹配文件
JNC LOOK
JMP EXIT ;没找到,->EXIT
LOOK: INC BYTE PTR[EXENUM]
MOV DX,OFFSET HZSM
MOV AH,09H
INT 21H
MOV DX,OFFSET DISKCHA
MOV AH,09H
INT 21H
MOV DX,OFFSET CURRDIR
MOV AH,09H
INT 21H ;显示当前目录路径
MOV DI,OFFSET CURRDIR+1
CMP BYTE PTR[DI],00H
JZ ZJS1
MOV AH,02H
MOV DL,5CH
INT 21H
ZJS1: MOV DX,OFFSET DAT
ADD DX,1EH ;DX:匹配文件名首址
PUSH DX
PUSH DX
POP DI
BZ5: INC DI
CMP BYTE PTR[DI],00H
JNZ BZ5
INC DI
MOV BYTE PTR[DI],24H
POP DX
MOV AH,09H
INT 21H ;显示文件名
MOV DX,OFFSET DAT
ADD DX,1EH
MOV AX,3D02H
INT 21H ;打开匹配文件
JNB CL0
JMP NEXTFILE
;;;;;;;;;;;;;
CL0: MOV BX,AX
MOV AX,4200H
MOV CX,00H
MOV DX,3CH
INT 21H ;文件指针移到文件头第3CH字节
MOV DX,OFFSET FILESUF ;文件缓冲区首址->DX
MOV CX,04H
MOV AH,3FH
INT 21H ;读入4个字节(File address of new exe header)
JNB CL1
JMP NEXTFILE
CL1: MOV AX,4200H
MOV CX,WORD PTR[FILESUF+2]
MOV DX,WORD PTR[FILESUF]
MOV WORD PTR[PE_HEAD],DX ;保存PE FILE HEAD 指针
MOV WORD PTR[PE_HEAD+2],CX
DEC DX
INT 21H ;文件指针移到new exe header-1
MOV DX,OFFSET FILESUF ;文件缓冲区首址->DX
MOV CX,0200H
MOV AH,3FH
INT 21H ;读入512个字节(PE File Signature)
JNB CL2
JMP NEXTFILE
CL2: CMP WORD PTR[FILESUF+1],04550H ;see if is "PE" format file
JZ CL21
JMP NEXTFILE
CL21: CMP BYTE PTR[FILESUF],00H
JNZ CL3 ;"XPE" May have CIH viurs
JMP NEXTFILE ;NOT BEEN INFECTED CIH VIRUS
CL3: MOV CX,WORD PTR[FILESUF+07H] ;Get Number of Sections
MOV WORD PTR[SECNUM],CX
INC CX
SHL CX,1
SHL CX,1
SHL CX,1
PUSH CX ;(Section 数+1)*8 =病毒块指针区大小
POP DI
;get PE FILE Entry RVA
MOV CX,WORD PTR[FILESUF+2BH] ;
MOV DX,WORD PTR[FILESUF+29H] ;[FILESUF+29,2A,2B,2CH]=Entry RVA
CMP CX,WORD PTR[FILESUF+57H] ;[FILESUF+55,56,57,58H]=File Header Size
JE CL4
JB CL5 ;Maybe has CIH virus
JMP NEXTFILE
CL4: CMP DX,WORD PTR[FILESUF+55H]
JB CL5 ;Maybe has CIH virus
JMP NEXTFILE
CL5: SUB DX,DI
MOV WORD PTR[VIRPOINT],DX
MOV WORD PTR[VIRPOINT+2H],CX ;Save CIH first block point
MOV AX,4200H
INT 21H ;文件指针移到FILE Entry address-病毒块指针区大小(DI)
MOV DX,OFFSET VIRSUF ;病毒缓冲区首址->DX
MOV CX,100H
MOV AH,3FH
INT 21H ;读入100H个字节
JNB CL6
JMP NEXTFILE
CL6: CMP WORD PTR[VIRSUF+DI+36H],056CCH
JZ CL7 ;May CIH virus
JMP NEXTFILE
CL7: CMP WORD PTR[VIRSUF+DI+4BH],0FBCCH
JZ CL8 ;Sure CIH virus
JMP NEXTFILE
CL8: MOV DX,OFFSET FILEMSG
MOV AH,09H
INT 21H ;显示有病毒
MOV AX,4301H
MOV CX,0020H
MOV DX,OFFSET DAT
ADD DX,1EH
INT 21H ;置文件属性为归档
;
;Save true Entry RVA
MOV AX,WORD PTR[VIRSUF+DI+5EH]
MOV WORD PTR[T_ENTRY],AX
MOV AX,WORD PTR[VIRSUF+DI+60H]
MOV WORD PTR[T_ENTRY+2H],AX
;
MOV DX,WORD PTR[VIRPOINT]
MOV CX,WORD PTR[VIRPOINT+2H] ;GET CIH first block point
MOV AX,4200H
INT 21H ;文件指针移到FILE Entry address-病毒块指针区大小
;
MOV CX,WORD PTR[VIRSUF+DI-04H] ;取CIH病毒首块长度
ADD CX,DI ;加上CIH病毒链表指针块区大小
MOV DX,OFFSET CL_ZERO
MOV AH,40H
INT 21H ;病毒首块及链表指针区清零
;
;;;;;;;;;;;;;;;;;;;;;;
;Clear other block viurs
; omitted
;;;;;;;;;;;;;;;;;;;;;;
;
;Restore True Entry RVA(Address of Entry Point)
MOV AX,4200H
MOV CX,WORD PTR[PE_HEAD+2]
MOV DX,WORD PTR[PE_HEAD]
ADD DX,28H
ADC CX,0
INT 21H ;文件指针移到文件头的Entry Point
MOV DX,OFFSET FILESUF ;文件缓冲区首址->DX
; MOV CX,4H
; MOV AH,3FH
; INT 21H ;读入Entry Point
; JNB CL11
; JMP NEXTFILE
CL11: MOV CX,WORD PTR[T_ENTRY]
MOV WORD PTR[FILESUF],CX
MOV CX,WORD PTR[T_ENTRY+2]
MOV WORD PTR[FILESUF+2],CX
MOV CX,2H
MOV AH,40H
INT 21H ;将正常的Entry 参数写回
JB NEXTFILE
COPYHANDLE
MOV SI,[OFFSET DAT+15H]
MOV CL,[SI]
MOV AX,4301H
MOV DX,OFFSET DAT
ADD DX,1EH
INT 21H ;恢复文件原属性
JB NEXTFILE
MOV DX,OFFSET DAT
MOV SI,WORD PTR[OFFSET DAT+16H]
MOV DI,WORD PTR[OFFSET DAT+18H]
MOV CX,[SI]
MOV DX,[DI]
MOV AX,5701H
INT 21H ;恢复文件原建立日期
MOV DX,OFFSET CLEAMSG
MOV AH,09H
INT 21H
INC BYTE PTR[VIREXE]
NEXTfile:MOV AH,3EH
INT 21H
CLD
MOV DI,OFFSET DAT
ADD DI,1EH
MOV CX,0EH
MOV AL,24H
REPZ STOSB
MOV DI,OFFSET FILESUF
MOV CX,600H
MOV AL,00
REPZ STOSB ;清文件缓冲区
MOV CX,0FFFFH
BZ6: LOOP BZ6
MOV CX,0FFFFH
BZ7: LOOP BZ7
MOV CX,0FFFFH
BZ8: LOOP BZ8
MOV CX,0FFFFH
BZ9: LOOP BZ9
MOV DL,0DH
MOV AH,02H
INT 21H ;只回车
MOV DX,OFFSET HZSM
MOV AH,09H
INT 21H
MOV DX,OFFSET DISKCHA
MOV AH,09H
INT 21H
MOV DX,OFFSET BLANK
MOV AH,09H
INT 21H
MOV DL,0DH
MOV AH,02H
INT 21H ;回车
MOV AH,4FH
INT 21H
JC EXIT
JMP LOOK
EXIT: RET
CLEA_VIRUS ENDP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
CLE_SDIR PROC NEAR ;搜寻各子目EXE文件并检测是否存在病毒以及消除
CL_SUBD:MOV DX,OFFSET DIRFILE
MOV CX,0010H
MOV AH,4EH
INT 21H ;搜寻第一匹配文件
JNC LOOKS
JMP EXITS ;没找到,->EXITS
LOOKS: MOV SI,OFFSET DAT
ADD SI,15H
CMP BYTE PTR[SI],10H
JZ NEXT1
JMP NEXTSUB
NEXT1: MOV BX,OFFSET DAT
ADD BX,1EH ;BX:匹配文件名首址
CMP BYTE PTR[BX],2EH ;是否是“.”或“..”子目录
JNZ SUB1
JMP NEXTSUB
SUB1: INC [DIRNUM] ;子目录数量加1
CLD
MOV SI,OFFSET DAT
MOV DI,OFFSET DIRSUFF
ADD DI,WORD PTR[DIRSUFP]
MOV CX,0015H
REPZ MOVSB ;保存当前目录参数
ADD WORD PTR[DIRSUFP],0015H ;目录参数指针+15H
MOV DI,OFFSET CURRDIR+1
CMP BYTE PTR[DI],00H
JZ LP2
LP1: INC DI
CMP BYTE PTR[DI],00H
JNZ LP1 ;找当前子目录名路径尾
MOV BYTE PTR[DI],5CH
INC DI
LP2: MOV SI,BX
MOV CX,0DH
REPZ MOVSB
MOV DX,OFFSET CURRDIR
MOV AH,3BH
INT 21H ;进入下一级子目录
CLD
MOV DI,OFFSET CURRDIR+1
MOV CX,003FH
MOV AL,24H
REPZ STOSB
MOV AH,47H
MOV DL,BYTE PTR[DISKSGN]
MOV SI,OFFSET CURRDIR+1
INT 21H ;取当前子目录
MOV BYTE PTR[FILEBZ],0FFH ;置EXE文件标志
MOV DX,OFFSET EXEFILE
CALL CLEA_VIRUS ;chesk and clear CIH virus
JMP CL_SUBD ;查找当前子目录下一级目录及EXE文件
EXITS: MOV BX,OFFSET CURRDIR+1
CMP BYTE PTR[BX],00 ;判当前目录为根目录否
JNZ SUB2
JMP OVERS ;当前目录为根目录->OVERS
SUB2: MOV AH,3BH
MOV DX,OFFSET UPDIR
INT 21H ;返回上一子目录
MOV AH,47H
MOV DL,BYTE PTR[DISKSGN]
MOV SI,OFFSET CURRDIR+1
INT 21H ;取当前子目录
STD
MOV SI,OFFSET DIRSUFF-1H
ADD SI,WORD PTR[DIRSUFP]
MOV DI,OFFSET DAT+14H
MOV CX,0015H
REPZ MOVSB
SUB WORD PTR[DIRSUFP],0015H ;恢复当前子目录参数及指针
NEXTSUB:MOV AH,4FH
INT 21H
JC EXITS
JMP LOOKS
OVERS: RET
CLE_SDIR ENDP
;
;
BTOD PROC NEAR ;将[DI]中2进制数转换成十进制数显示
MOV WORD PTR[DECSUF+10H],OFFSET DECSUF
MOV DX,0000H
MOV AX,[DI]
;DX=数值的高位;AX=数值的低位
PUSH AX
POP SI
PUSH DX
POP DI
PUSH BP
PUSH BX
XOR AX,AX
MOV BX,AX
MOV BP,AX
MOV CX,0020H
BTOD1: SHL SI,1
RCL DI,1
XCHG BP,AX
ADC AL,AL
DAA
XCHG AH,AL
ADC AL,AL
DAA
XCHG AH,AL
XCHG BP,AX
XCHG BX,AX
ADC AL,AL
DAA
XCHG AH,AL
ADC AL,AL
DAA
XCHG AH,AL
XCHG BX,AX
ADC AL,00
LOOP BTOD1
MOV CX,1810H
XCHG DX,AX
CALL BTOD2
XCHG BX,AX
CALL BTOD3
MOV AX,BP
CALL BTOD3
MOV BYTE PTR[DECSUF+0BH],24H
MOV AH,09H
MOV DX,OFFSET DECSUF
INT 21H
JMP BTOD6
BTOD3 PROC NEAR
PUSH AX
MOV DL,AH
CALL BTOD7
POP DX
BTOD7 PROC NEAR
MOV DH,DL
SHR DL,1
SHR DL,1
SHR DL,1
SHR DL,1
CALL BTOD2
MOV DL,DH
BTOD2 PROC NEAR
AND DL,0FH
JZ BTOD8
MOV CL,00
BTOD8: DEC CH
AND CL,CH
OR DL,30H
SUB DL,CL
PUSH DI
MOV DI,WORD PTR[DECSUF+10H]
MOV [DI],DL
INC DI
MOV WORD PTR[DECSUF+10H],DI
POP DI
RET
BTOD2 ENDP
BTOD7 ENDP
BTOD3 ENDP
BTOD6: POP BX
POP BP
RET
BTOD ENDP
;
;
KILLCIH ENDP
;
CODE ENDS
STACK SEGMENT PARA STACK 'STACK'
DB 256 DUP(?)
STACK ENDS
END KILLCIH
更多精彩
赞助商链接