手机杀毒的原理

手机杀毒:
1.什么是计算机病毒?
特殊的程序,运行起来才能成为病毒,如果没有运行就是一个普通的文件。
2.传统杀毒软件的工作原理:
扫描硬盘上的每个文件,分析这些文件特征码,
查看病毒文件的特征是否在病毒数据库存在。
校验文件的md5 sha1签名。
算法提权软件的关键信息。
遍历文件里面的字符串。http://

通过sdk/tools/hierarchyviewer.bat文件,可以查看手机运行的软件,黑色突出的代表正在运行的,双击可以看到这个页面的布局信息

 图中的数据库可在文件中查看,版本比较老了

public class MainActivity extends Activity {
    
    private PackageManager pm;
    private ProgressBar progressBar;
    private ImageView img_scanner;//扫描旋转的图片
    private LinearLayout linearLayout;//存放扫描结果
    private TextView showScannerInfo;//显示正在扫描的软件信息
    
    private Handler handler=new Handler(){
        public void handleMessage(Message msg) {
            Bundle data=msg.getData();
            boolean scannerInfo = data.getBoolean("是病毒吗");
            String appName = data.getString("软件名");
            String packageName = data.getString("包名");
            TextView textView = new TextView(MainActivity.this);
            textView.setTextSize(20);
            showScannerInfo.setText("正在扫描:"+appName);
            switch (msg.what) {
            case 0://扫描完成
                if(scannerInfo){
                    textView.setText("扫描结果:"+appName+"发现病毒");
                    textView.setTextColor(Color.RED);
                }else{
                    textView.setText("扫描结果:"+appName+"安全");
                    textView.setTextColor(Color.BLACK);
                }
                linearLayout.addView(textView,0);//添加到最上面
                img_scanner.clearAnimation();//取消扫描动画的执行
                img_scanner.setVisibility(View.INVISIBLE);//并设置为不可见
                showScannerInfo.setText("扫描完毕");
                break;
            case 1://还在扫描
                if(scannerInfo){
                    textView.setText("扫描结果:"+appName+"发现病毒");
                    textView.setTextColor(Color.RED);
                }else{
                    textView.setText("扫描结果:"+appName+"安全");
                    textView.setTextColor(Color.BLACK);
                }
                linearLayout.addView(textView,0);
                break;
            }
        };
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        img_scanner = (ImageView) findViewById(R.id.img_scanner);
        linearLayout = (LinearLayout) findViewById(R.id.scanner_result);
        showScannerInfo = (TextView) findViewById(R.id.tv_showScannerInfo);
        RotateAnimation ra=new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f,Animation.RELATIVE_TO_SELF, 0.5f);
        ra.setDuration(1000);
        ra.setRepeatCount(Animation.INFINITE);//重复次数为无限
        //图片旋转,开始扫描
        img_scanner.startAnimation(ra);
        //杀毒的简单原理:获取文件的特征码,然后去病毒数据库中查询有没有这个特征码记录
        scanVirus();
    }

    /**
     * 扫描病毒,实际上就是找到手机里每个软件的文件,然后得到该文件的特征码md5值,看在病毒数据库中存不存在
     */
    private void scanVirus() {
        pm = getPackageManager();
        //查询比较耗时,所以放在子线程中运行
        new Thread(){
            public void run() {
                List<PackageInfo> infos = pm.getInstalledPackages(0);
                progressBar.setMax(infos.size()-1);
                int progress=0;//记录扫描进度
                boolean scannerInfo;//记录是否发现病毒
                copDB();//复制病毒数据库
                for (PackageInfo info : infos) {
                    //数据目录:/data/data/包名
                    String dataDir=info.applicationInfo.dataDir;
                    //得到apk的完整路径:system/app/xxx.apk
                    String sourceDir=info.applicationInfo.sourceDir;
                    //获取文件的MD5值
                    String fileMD5 = getFileMD5(sourceDir);
                    String appName=info.applicationInfo.loadLabel(pm).toString();
                    String packageName=info.applicationInfo.packageName;
                    System.out.println("软件名:"+appName+",MD5值:"+fileMD5);
                    //查询md5信息,是否在病毒数据库里面存在
                    if(isVirus(MainActivity.this, fileMD5)){
                        scannerInfo=true;//是病毒
                    }else{
                        scannerInfo=false;//扫描安全
                    }
                    progressBar.setProgress(progress++);
                    Message message = Message.obtain();
                    if(progress == infos.size()){
                        System.out.println("扫描完成");
                        message.what=0;//扫描完成
                    }else{
                        message.what=1;//还在扫描
                    }
                    Bundle data = new Bundle();
                    data.putBoolean("是病毒吗", scannerInfo);
                    data.putString("软件名", appName);
                    data.putString("包名", packageName);
                    message.setData(data);
                    handler.sendMessage(message);
                    try {
                        Thread.sleep(300);//不然扫描太快了
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
        }.start();
    }
    
    /**
     * 因为这里需要将数据库放到自己的软件里面,所以先将需要的数据库放到当前工程的assets文件夹中,
     * 然后在代码中进行读取,复制到该软件装数据的文件夹中.并且只需要复制一次,assets文件夹里的数据就不需要了
     * 把antivirus.db这个数据库拷贝到 data/data/<包名>/files/antivirus.db
     */
    private void copDB(){
        try {
            //只需要拷贝一次,antivirus.db作为病毒数据库的名字
            File file = new File(getFilesDir(),"antivirus.db");
            if(file.exists() && file.length()>0){
                System.out.println("已经拷贝了,不需要再复制");
            }else{
                //复制当前工程下assets文件夹中的数据库到手机内存中
                InputStream is=getAssets().open("antivirus.db");
                FileOutputStream fos=new FileOutputStream(file);
                byte[] buffer = new byte[1024];
                int len= 0;
                while((len=is.read(buffer))!=-1){
                    fos.write(buffer, 0, len);
                }
                is.close();
                fos.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    
    
    /**
     * 查询一个md5值是否在病毒数据库中存在
     * @param md5
     * @return true代表是病毒
     */
    public boolean isVirus(Context context,String md5){
        boolean result=false;
        String packageName = context.getPackageName();
        //病毒数据库的全路径
        String path = "/data/data/"+packageName+"/files/antivirus.db";
        //打开病毒数据库文件
        SQLiteDatabase db = SQLiteDatabase.openDatabase(path, null, SQLiteDatabase.OPEN_READONLY);
        //datable为这个病毒数据库的表名
        Cursor cursor=db.rawQuery("select * from datable where md5=?", new String[]{md5});
        if(cursor.moveToNext()){
            result = true;//是病毒
        }
        cursor.close();
        db.close();
        return result;
    }
    
    
    /**
     * 获取文件的MD5值,path为文件的全路径
     * 获取文件的特征信息
     */
    public String getFileMD5(String path){
        try {
            File file=new File(path);
            FileInputStream fis=new FileInputStream(file);
            byte[] byffer = new byte[1024];
            int len=-1;
            MessageDigest digest = MessageDigest.getInstance("md5");
            while((len=fis.read(byffer))!=-1){
                digest.update(byffer,0,len);
            }
            byte[] result=digest.digest();
            StringBuffer sb=new StringBuffer();
            for (byte b : result) {
                int number=b & 0xff;//加盐
                String str = Integer.toHexString(number);
                if(str.length() == 1){
                    sb.append("0");
                }
                sb.append(str);
            }
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        } 
        return null;
    }
}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:layout_marginTop="5dp"
        android:gravity="center_vertical"
        android:orientation="horizontal" >

        <FrameLayout
            android:layout_width="100dp"
            android:layout_height="100dp" >

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@drawable/ic_scanner_malware" />

            <ImageView
                android:id="@+id/img_scanner"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@drawable/act_scanning_03" />
        </FrameLayout>

        <LinearLayout 
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:gravity="center_vertical"
            android:layout_marginLeft="5dp"
            android:layout_marginRight="5dp" 
            android:orientation="vertical">
            
            <TextView 
                android:id="@+id/tv_showScannerInfo"
                android:textSize="20sp"
                android:text="正在扫描"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
            
            <ProgressBar
                android:id="@+id/progressBar"
                style="@android:style/Widget.ProgressBar.Horizontal"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>
            
        </LinearLayout>
    </LinearLayout>
    
  <!-- 存放扫描结果的TextView -->
    <LinearLayout 
        android:id="@+id/scanner_result"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#ffcccc">
        
    </LinearLayout>
</LinearLayout>

效果图:

 

这里对扫描出的病毒还没做处理

posted @ 2016-09-08 18:50  ts-android  阅读(1726)  评论(0编辑  收藏  举报