naoga

病毒免疫程式

这是一个病毒免疫模块 主要的工作是监控自己是否被改变 监控的方法使用监控文件的长度 当发现被修改可以恢复宿主 COM文件通过从内存中重新写回恢复 
EXE文件通过把EXE文件头写回恢复 
当然,这里有不安全的地方: 如果采用压缩工具例如PKLITE压缩的 EXE文件这样写回会导致文件被破坏 这个文件由UNVIR.EXE来负责感染。UNVIR是由PASCAL编写的 


Include stdio.h 
Include PushPop.asm 
;Include Myname.h 
EXE Equ 0 
COM EQU 1 
TheSaveLen Equ 32 
Pmain 
GetName Macro Run_file_name ;在环境块中取得自己的运行程序名 
Local file_name_find,cmp_if_1,file_name_true1,file_name_true,exit_000 
Mov ds,cs:ThePsp 
Push SI 
Mov Si,2ch 
mov ax,word ptr ds:[SI] 
Pop SI 
mov es,ax 
push cs 
pop ds 
mov si,0 
mov di,0 
file_name_find: 
mov al,0 
cmp es:[di],al 
je cmp_if_1 
inc di 
jmp file_name_find 
cmp_if_1: 
inc di 
mov al,1 
cmp es:[di],al 
je file_name_true1 
jmp file_name_find 
file_name_true1: 
inc di 
file_name_true: 
inc di 
mov al,0 
cmp es:[di],al 
je exit_000 
mov al,es:[di] 
mov Cs:[offset run_file_name+si],al 
inc si 
jmp file_name_true 
exit_000: push cs 
pop ds 
mov al,0 
mov Cs:[offset run_file_name+si],al 
Endm 
Jmp Begin 
TheExeType db COM 
TheFSize dd 0 
TheCS dw 0 
TheIp dw 0 
TheBeginSave db TheSaveLen dup (0) 
ThePsp dw 0 
TheRetCS dw 0 
The100 dw 100h 
RunExeName db 256 dup (0) 
Handle dw 0 
OpenFileError db 'Open the executing program error !',0dh,0ah 
db 'Exiting...',0dh,0ah,07h,'$' 
ThePrompt db 'The executing program has been changed ',07h,'!',0dh,0ah 
db 'It may be a virus infected it .',0dh,0ah 
db 'Do you want to restore this program ? [Y/N]',0dh,0ah 
db '$' 
RestoreOk db 'The program has been restored successful !',0dh,0ah 
db 'Thanks for your use .',0dh,0ah,'$' 
Begin: 
Pushall 
Mov cs:SaveSS,SS 
Mov cs:SaveSP,SP 
Mov ax,cs 
Mov ss,ax 
Mov sp,0ffeeh 
Push cs 
Pop ds 
mov ah,51h 
Int 21h 
Mov ThePsp,Bx 
GetName RunExeName 
Mov Dx,Offset RunExeName 
Mov ax,3d00h 
Int 21h 
Jnc OpenFileOk 
Print OpenfileError 
Retms 
OpenFileOk: 
Mov Handle,ax 
Mov bx,Handle 
Mov ax,4202h 
Xor cx,cx 
Xor dx,dx 
Int 21h 
Push Dx 
Push Ax 
Mov ah,3eh 
Mov Bx,Handle 
Int 21h 
Pop Ax 
Pop Dx 
Cmp Dx,Word Ptr TheFSize+2 
Jne SizeError 
Cmp Ax,Word Ptr TheFSize 
Jne SizeError 
Jmp SizeOk 
SizeError: 
Print ThePrompt 
Mov ah,0 
Int 16h 
Or al,'a'-'A' 
Cmp al,'y' 
Je ResFile 
Cmp al,'n' 
Jne SizeError 
Jmp SizeOk 
ResFile: 
mov ax,3d01h 
Mov Dx,Offset RunExeName 
Int 21h 
Mov Handle,Ax 
Cmp cs:TheExeType,COM 
Je TheCOMRes 
Mov Dx,Offset TheBeginSave 
Mov Cx,TheSaveLen 
Mov Bx,Handle 
Mov ah,40h 
Int 21h 
Mov ax,4200h 
Mov Bx,Handle 
Mov Cx,Word Ptr TheFSize+2 
Mov Dx,Word Ptr TheFSize 
Int 21h 
Mov cx,0 
Mov ah,40h 
Mov Bx,Handle 
Int 21h 
Mov ah,3eh 
Mov Bx,Handle 
Int 21h 
Jmp SizeRelOk 
TheCOMRes: 
Mov ah,3ch 
mov cx,0 
Mov dx,Offset RunExeName 
int 21h 
Mov Handle,ax 
Mov Bx,Handle 
Mov Cx,Word Ptr TheFSize 
Push ThePsp 
Pop Ds 
Mov Dx,100h 
Mov ah,40h 
Int 21h 
Mov Bx,Handle 
Mov ah,3eh 
Int 21h 
SizeRelOk: 
Push cs 
Pop ds 
Print RestoreOk 
SizeOk: 
Cmp cs:TheExeType,EXE 
Je TheExe 
Push cs 
Pop ds 
Mov ax,ThePsp 
Mov es,ax 
Mov Si,Offset TheBeginSave 
Mov DI,100h 
Mov Cx,TheSaveLen 
CLD 
Rep Movsb 
Mov SS,cs:SaveSS 
Mov SP,cs:SaveSP 
Popall 
Push cs:ThePsp 
Push cs:The100 
RetF 
TheExe: 
Mov ax,cs:ThePsp 
add ax,16 
Add ax,cs:TheCS 
Mov cs:TheRetCS,ax 
Mov SS,cs:SaveSS 
Mov SP,cs:SaveSP 
Popall 
Push cs:TheRetCS 
Push cs:TheIP 
RetF 
SaveSS dw 0 
SaveSp dw 0 
TheFlag db 'LXELMM' 
Pend 
用于传播的PASCAL代码如下 
Program kill; {程序名UNVIR,前面的模块编译连接后更名为unvir.ovl} 
{$M 60000,60000,60000} 
Uses Dos,crt; 
Const s:string='*.com'; 
Const c:string='*.exe'; 
Var 
NDIR,TheDir,NowDir,FirstDir:String; 
cFile:File; 
cfile1:file of char; 
NewPage,FPointer,Offset,Segment:Word; 
Handle:Word; 
SaveBuf:array[1..33] of char; 
fattr:word; 
FilePointer:LongInt; 
TheP:array[1..2000] of char; 
SIzeP:integer; 
I,J:integer; 
TheChar:char; 
cc:char; 
NewFree:Word; 
TheFSize:longint; 
OldPage:Word; 
readchar:char; 
TT:Boolean; 
comBuf:array[1..12] of char; 
Chr0:char; 
TheFlag:Word; 
Function Ucase(S:string):string; 
Var S1:string; 
I:integer; 
Begin 
S1:=S; 
For I:=1 to Length(S) do 
S1:=Upcase(S); 
ucase:=s1; 
end; 
Function LOWI(NUMM:Longint):Word; 
Var nu:Longint; 
nu1:Word; 
Begin 
nu:=numm; 
ASM 
mov ax,Word Ptr nu 
Mov nu1,ax 
end; 
LowI:=nu1; 
end; 
Function higI(NUMM:Longint):Word; 
Var nu:Longint; 
nu1:Word; 
Begin 
nu:=numm; 
ASM 
mov ax,Word Ptr nu+2 
Mov nu1,ax 
end; 
higi:=nu1; 
end; 
Procedure DOCOMFILE(FILENAME:STRING); forward; 
Procedure DoExeFile(Filename:string); 
Var I,J,Newcs,newIP:word; 
Begin 
Assign(cfile,filename); 
GetFattr(cfile,Fattr); 
{$I-} 
SetFattr(Cfile,0); 
{$I+} 
If IoResult<>0 then begin writeln('Write protect error !'); Halt;end; 
Reset(cfile,1); 
BlockRead(cfile,TheFlag,2); 
If ((TheFlag<>$4d5a) and (TheFlag<>$5a4d)) Then 
Begin 
SetFattr(Cfile,Fattr); 
Close(cfile); 
DoComFile(FileName); 
end 
Else 
If Filesize(cfile)<64000 then 
Begin 
Seek(cfile,8); 
{$I-} 
BlockRead(cfile,FPointer,2); 
Seek(cfile,$4); 
BlockRead(cfile,OldPage,2); 
seek(cfile,$14); 
BlockRead(cfile,Offset,2); 
Seek(cfile,$16); 
BlockRead(cfile,Segment,2); 
Seek(cfile,filesize(cfile)-6); 
BlockRead(cfile,SaveBuf,6); 
{$I+} 
TT:=True; 
If (longint((longint(OldPage)+1)*512) Begin 
Writeln(chr($0d)+chr($a)+'The file ',Filename,' may be has overlay code .'); 
Write('Do you wish to immute it ?[Y/N]'); 
If ((Ucase(Paramstr(2))<>'-Y') and (Ucase(Paramstr(2))<>'-N')) Then 
Begin 
repeat 
asm 
mov ah,0 
int 16h 
or al,'a'-'A' 
mov readchar,al 
end; 
until readchar in ['n','y']; 
If readchar='n' then TT:=False; 
End 
Else If Ucase(Paramstr(2))='-Y' then TT:=True 
Else If Ucase(Paramstr(2))='-N' then TT:=False 
end; 
If TT=True then 
If not ((SaveBuf[1]='L') and (SaveBuf[2]='X') and (SaveBuf[3]='E') and (SaveBuf[4]='L') 
and (SaveBuf[5]='M') and (SaveBuf[6]='M')) then 
Begin 
TheP[9]:=chr(lo(Segment)); 
TheP[10]:=chr(hi(Segment)); 
TheP[11]:=chr(lo(Offset)); 
TheP[12]:=chr(hi(Offset)); 
TheP[4]:=chr(0); 
Seek(cfile,filesize(cfile)+128); 
Begin 
J:=FIleSize(cfile); 
chr0:=chr(0); 
for i:=1 to (64+(16-(J Mod 16))) do 
Begin 
Blockwrite(cfile,chr0,1); 
end; 
end; 
TheFsize:=FileSize(cfile); 
TheFsize:=TheFsize+SizeP; 
TheFsize:=Longint(TheFSize); 
I:=lowI(TheFsize); 
J:=higI(TheFsize); 
TheP[5]:=chr(lo(i)); 
TheP[6]:=chr(hi(i)); 
TheP[7]:=chr(lo(j)); 
TheP[8]:=chr(hi(j)); 
NewPage:=(FileSize(cfile)+sizeP+511) div 512; 
NewFree:=(FileSize(cfile)+sizeP) mod 512; 
NewCS:=((FileSize(cfile)) div 16)-FPointer-16; 
NewIp:=256; 
Seek(cfile,$2); 
Blockwrite(cfile,NewFree,2); 
Seek(cfile,$4); 
Blockwrite(cfile,NewPage,2); 
Seek(cfile,$14); 
blockwrite(cfile,NewIp,2); 
Seek(cfile,$16); 
BlockWrite(cfile,NewCS,2); 
{Seek(cfile,4); 
I:=(filesize(cfile)+sizeP+15) div 16; 
Blockwrite(cfile,I,2);} 
Seek(cfile,0); 
blockread(cfile,SaveBuf,32); 
For I:=1 to 32 do 
TheP[12+I]:=SaveBuf; 
Seek(cfile,filesize(cfile)); 
For I:=1 to SizeP do 
Begin 
Thechar:=TheP; 
Blockwrite(cfile,TheChar,1); 
end; 
end 
Else 
Writeln(chr($D)+Chr($A)+'The file:',Filename,' has been immuned !'); 
Close(cfile); 
{$I-} 
SetFattr(CfILE,Fattr); 
{$I+} 
End; 
end; 
Procedure DoComFile(Filename:string); 
Var I:integer; 
Begin 
If Pos('COMMAND.COM',UCASE(FILENAME))+Pos('IBMBIO.COM',UCASE(FILENAME))+Pos('IBMDOS.COM',UCASE(FILENAME))=0 
Then 
Begin 
Assign(cfile,FileName); 
GetFattr(cfile,Fattr); 
{$I-} 
SETfATTR(CFILE,0); 
{$I+} 
If Ioresult<>0 then Begin Writeln('Write Protect error !'); Halt; end; 
Reset(cfile,1); 
BlockRead(cfile,TheFlag,2); 
If ((TheFlag=$4d5a) or (TheFlag=$5a4d)) Then 
Begin 
SETfATTR(CFILE,Fattr); 
Close(cfile); 
DoEXEFile(FileName); 
end 
Else 
Begin 
If FileSize(cfile)>64 Then 
Begin 
Seek(cfile,FileSize(cfile)-6); 
{$I-} 
BlockRead(cfile,saveBuf,6); 
If not ((SaveBuf[1]='L') and (SaveBuf[2]='X') and (SaveBuf[3]='E') and (SaveBuf[4]='L') 
and (SaveBuf[5]='M') and (SaveBuf[6]='M')) then 
Begin 
Seek(cfile,0); 
BlockRead(cfile,SaveBuf,32); 
For I:=1 to 32 do 
Thep[12+I]:=SaveBuf; 
TheFSize:=FileSize(Cfile); 
Seek(CFile,TheFSize+128); 
chr0:=chr(0); 
For I:=1 to (32-(TheFSize Mod 16)) do 
Blockwrite(Cfile,Chr0,1); 
TheFSize:=fileSize(Cfile)+SizeP; 
I:=lowI(TheFsize); 
J:=higI(TheFsize); 
TheP[4]:=chr(1); 
TheP[5]:=chr(lo(i)); 
TheP[6]:=chr(hi(i)); 
TheP[7]:=chr(lo(j)); 
TheP[8]:=chr(hi(j)); 
ComBuf[4]:=chr(lo((FileSize(Cfile)) div 16)); 
ComBuf[5]:=chr(hi((FileSize(Cfile)) div 16)); 
ComBuf[1]:=chr($8c); 
ComBuf[2]:=chr($C8); 
ComBuf[3]:=chr($05); 
ComBuf[6]:=chr($50); 
ComBuf[7]:=chr($B8); 
ComBuf[8]:=chr($00); 
ComBuf[9]:=chr($01); 
ComBuf[10]:=chr($50); 
ComBuf[11]:=chr($CB); 
BlockWrite(cfile,TheP,SizeP); 
Seek(cfile,0); 
BlockWrite(cfile,ComBuf,11); 
end 
Else 
Writeln(chr($D)+chr($A)+'The file:',Filename,' has been immuned !'); 
end; 
Close(cfile); 
SetFattr(CfILE,Fattr); 
END; 
end; 
End; 
ProceDure DoDir(Dir:string); 
Var FileRec:SearchRec; 
Begin 
ChDir(Dir); 
GetDir(0,nDir); 
FindFirst(c,AnyFile,FileRec); 
While DosError=0 Do 
Begin 
gotoxy(1,wherey); 
write(' '); 
gotoxy(1,wherey); 
Write('Search file :',NDIR+'\'+FileRec.name); 
DoExeFile(fileRec.name); 
FindNext(FileRec); 
End; 
FindFirst(s,AnyFile,FileRec); 
While DosError=0 Do 
Begin 
gotoxy(1,whereY); 
write(' '); 
gotoxy(1,whereY); 
Write('Search file :',NDIR+'\'+filerec.name); 
DoComFile(FileRec.name); 
FindNext(FileRec); 
End; 
FindFirst('*.*',$10,FileRec); 
While DosError=0 Do 
Begin 
If (FileRec.attr and $10)<>0 then 
If ((FileRec.Name<>'.') and (FileRec.Name<>'..')) Then 
doDir(FileRec.Name); 
FindNext(FileRec); 
End; 
GetDir(0,TheDir); 
If TheDir=NowDir Then 
ChDir(FirstDir) Else 
Chdir('..'); 
End; 
Begin 
assign(cfile1,Copy(Paramstr(0),1,length(Paramstr(0))-3)+'OVL'); 
reset(cfile1); 
I:=1; 
While not eof(cfile1) do 
Begin 
Read(cfile1,TheP); 
Inc(I); 
end; 
SizeP:=I-1; 
close(cfile1); 
Writeln('Automantic Anti Virus Copyright(C) New star software lab 1995'); 
Writeln('All rights reserved.'); 
writeln; 
GetDir(0,FirstDir); 
If ParamCount=0 then 
Begin 
Writeln('Expect:'); 
Writeln(' Unvir C: [-N|-Y]'); 
Halt; 
end; 
{$I-} 
Chdir(Paramstr(1)); 
{$I+} 
if Ioresult<>0 then 
Begin 
Writeln('Path is not exist ...'); 
Halt; 
end; 
GetDir(0,NowDir); 
DoDir('.'); 
writeln; 
Writeln('Anti virus completed ,thanks for use !'); 
Writeln; 
Writeln('If you have any question about it or found new virus'); 
Writeln('please report to me.'); 
Writeln; 
Writeln('Address: HUST Computer Department,Wuhan,CHINA'); 
Writeln('Name : Mr. Liuermou'); 
Writeln('Zip : 430074'); 
end. 

评论

热度(1)