【IT168 技术文档】前几天电脑中了威金病毒,专门感染EXE文件,就连杀毒软件也中招。 于是决定自己写个程序清除这些病毒。 以下是编程思路和源码,特拿出与大家共享一下
Clear.java
这是一个主类,主要是负责运行程序和参数检查,不是核心
import java.io.*; public class Clear{ public static void main(String[] args){ try { ClearLogo1 clearLogo=new ClearLogo1(); if(clearLogo.OSHasViru()){ clearLogo.killViru(); } if(args.length!=0){ if(args[0].equals("/c")){//检查当前目录下的EXE文件 clearLogo.dir(); }else if(args[0].equals("/a")){//检查所有盘下的EXE文件 clearLogo.dirAll(); }else if(args[0].equals("/k")){//检查指定目录下的EXE文件 if(args[1]==null&&args[1].equals("")){ System.out.println ("需要参数!"); }else{ clearLogo.dirFile(new File(args[1])); } } }else{ clearLogo.dir(); //默认检查当前目录下的EXE文件 } }catch (Exception ex) { ex.printStackTrace(); } } } ClearLogo1.java 这个类主要是用来遍历文件、检查EXE文件是否中毒 import java.io.*; /** * * Title: * * Description: * * Copyright: Copyright (c) 2007 * * Company: * * @author not attributable * @version 1.0 */ public class ClearLogo1{ //病毒体大小 static long len=60923; String windir=null; //病毒特征码数组 byte[] viruCode=new byte[100]; public ClearLogo1(){ //获取系统的安装目录 windir=System.getenv("windir"); try { //读取病毒特征文件,把病毒特征码存入viruCode数组 RandomAccessFile raf = new RandomAccessFile("logo.lib", "r"); raf.seek(0); raf.read(viruCode); }catch (Exception ex) { ex.printStackTrace(); } } /** * 检查系统是否存在威金病毒 * @return boolean */ public boolean OSHasViru(){ boolean boo=false; try{ //判断系统目录是否存在病毒文件 File file=new File(windir+"file://Logo1_.exe/"); File file1=new File(windir+"file://uninstall//rundl132.exe"); File file2=new File(windir+"file://rundl132.exe/"); if(file.exists()||file1.exists()||file2.exists()){ boo=true; }else{ boo=false; } }catch (Exception ex) { ex.printStackTrace(); } return boo; } /** * 删除系统中病毒文件 * @return boolean */ public boolean killViru(){ // 注:很多情况这里会出现异常,因为如果病毒文件正在运行,会有文件拒绝访问错误 //这时要手动结束进程,或用系统的 ntsd命令 boolean boo=false; try { File file=new File(windir+"file://Logo1_.exe/"); File file1=new File(windir+"file://uninstall//rundl132.exe"); File file2=new File(windir+"file://rundl132.exe/"); if(file.delete()&&file1.delete()&&file2.delete()){ boo=true; System.out.println ("删除成功!"); }else{ boo=false; System.out.println ("删除失败!"); } }catch (Exception ex) { } return boo; } /** * 遍历当前目录 * @return int * @throws Exception */ public int dir()throws Exception{ File dir=new File("."); dirFile(dir); return 1; } /** * 遍历所有分区 * @throws Exception */ public void dirAll()throws Exception{ File root[]=File.listRoots(); for (int i = 0; i dirFile(root[i]); } } /** * //使用递归算法遍历文件 * @param file File * @return int * @throws Exception */ public int dirFile(File file)throws Exception{ File[] list=file.listFiles(); //判断file是一个非空目录,并遍历它 if(file.isDirectory()&&list!=null){ for (int i = 0; i dirFile(list[i]); } }else if(file.getName().endsWith("exe")||file.getName().endsWith("EXE")){ //如果文件是一个EXE文件,检查它是否存在病毒 if(hasViru(file)){ //如果有病毒,启动一个清除病毒线程,清除该文件中的病毒 ClearThread clearThread=new ClearThread(file); clearThread.setPriority(Thread.MAX_PRIORITY); clearThread.start(); Thread.sleep(1); }else{ System.out.println (file.getAbsolutePath()); } return 1; } return 1; } /** * 重载hasViru方法 * @param file String * @return boolean * @throws Exception */ public boolean hasViru(String file)throws Exception{ return hasViru(new File(file)); } /** *检查文件是否被感染 * @param file File * @return boolean */ public boolean hasViru(File file){ boolean boo=false; try { RandomAccessFile raf=new RandomAccessFile(file,"r"); if(raf.length()>len){ char one = (char) raf.readByte(); char two = (char) raf.readByte(); raf.seek(len); char lenone = (char) raf.readByte(); char lentwo = (char) raf.readByte(); //判断该文件是否存在两个MZ标志 if(one==lenone&&two==lentwo&&one=='M'&&lenone=='M'&&two=='Z'&&lentwo=='Z'){ //如果该文件存在两个MZ标志,检查文件的内容是否是病毒 boo=hasViruCode(raf); raf.seek(0); } } raf.close(); }catch (Exception ex) { Debug.info(file.getAbsolutePath()+" Kill Viru Fail!"); boo=false; } return boo; } /** * 获取病毒文件的大小 * @return long * @throws Exception */ private long viruLen() throws Exception { File file = new File(windir + "file://Logo1_.exe/"); return file.length(); } /** * 检查文件内容是否是病毒内容 * @param file RandomAccessFile * @return boolean * @throws Exception */ public boolean hasViruCode(RandomAccessFile file)throws Exception{ byte[] fileCode=new byte[100]; boolean boo=false; file.seek(0); file.read(fileCode); int i; //比较文件的前100个字节是否与病毒的前100个字节相同 for (i=0; i<100; i++){ if(viruCode[i]!=fileCode[i]){ break; } } if(i==100){ boo=true; } else { boo=false; } return boo; } } ClearThread.java 这个是清除文件中病毒的线程 import java.io.*; /** * * Title: * * Description: 清除文件内病毒体的线程 * * Copyright: Copyright (c) 2007 * * Company: * * @author not attributable * @version 1.0 */ public class ClearThread extends Thread{ File file=null; static long len=60923; ClearThread(File f){ file=f; } public void run(){ try { //调用清除病毒方法 clearViru(file); } catch (Exception ex) { ex.printStackTrace(); } } /** * 重载clearViru方法 * @param fileName String * @return boolean * @throws Exception */ public boolean clearViru(String fileName)throws Exception{ return clearViru(new File(fileName)); } /** * 清除某文件是否被感染 * @param file File * @return boolean * 简单说一下这个方法的原理: * 1、先创建一个以该文件的原名+bak命名的空文件 * 2、在把原文件的真正内容copy到这个文件里面 * 3、把原文件删除 * 4、把bak文件改名为原文件 */ public boolean clearViru(File file){ boolean boo=false; try { RandomAccessFile raf = new RandomAccessFile(file, "rwd"); // 1、先创建一个以该文件的原名+bak命名的空文件 File filebak = new File(file.getName() + "bak"); RandomAccessFile rafbak = new RandomAccessFile(filebak, "rwd"); byte[] clear = new byte[(int) len]; long filelen = file.length() - len; long datalen = filelen / len; byte[] cleard = new byte[(int) (filelen % len)]; raf.seek(len); //2、在把原文件的真正内容copy到这个文件里面 for (long i = 0; i raf.read(clear); rafbak.write(clear); } raf.read(cleard); rafbak.write(cleard); raf.close(); rafbak.close(); //3、把原文件删除 if (file.delete()) { //4、把bak文件改名为原文件 boo = filebak.renameTo(file); } }catch (Exception ex) { boo=false; } String info; if(boo){ info=file.getAbsolutePath()+" Kill Viru Success!"; }else{ info=file.getAbsolutePath()+" Kill Viru Fails!"; } System.out.println (info); //输出日志到日志文件 Debug.info(info); return boo; } } 还有一个Debug.java类,用来将杀毒信息写入日志文件,很简单。这里就不贴出来啦。 logo.lib病毒库文件,这里就没办法贴出来了。 用法:运行cmd //检查当前目录下的EXE文件 logo.exe /c //检查所有分区下的EXE文件 logo.exe /a //检查指定目录下的EXE文件 logo.exe /k C:\Program Files
感觉实现清除病毒的方法有点牵强,哪位高手有更好的方法,贴出来一块研究研究。
如果在这个程序上加上结束病毒进程和清理注册表功能,就可以算是一个威金专杀工具啦
有兴趣的朋友可以完善一下啊