程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 匯編語言 >> 匯編源代碼之CIH文件型病毒檢測消除程序

匯編源代碼之CIH文件型病毒檢測消除程序

編輯:匯編語言
;本程序在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 [email protected]",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
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved