技术开发 频道

Java清除exe文件中的病毒

  【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

  感觉实现清除病毒的方法有点牵强,哪位高手有更好的方法,贴出来一块研究研究。

  如果在这个程序上加上结束病毒进程和清理注册表功能,就可以算是一个威金专杀工具啦

  有兴趣的朋友可以完善一下啊

0
相关文章