zoukankan      html  css  js  c++  java
  • 批量检查APK是否具有指定的权限。

    为测试组的妹子提供的。

    效果如下:

    目录结构如下:

    源代码思路:

    1、将apk文件变为zip文件。这里是修改后缀

    2、解压文件到指定目录。可以只解压其中mainfest.xml文件

    3、移动xml文件到反编译的工具目录下。运行Bat将二进制xml转为txt文本

    4、读取配置文件,比对字符串,得出你想要的结果。

    具体代码,请去下载工程吧。

    部分代码:

    package com.wuwenfu;
    
    import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Properties;
    
    public class FileUtils {
    
        // 修改apk为zip
        /**
         * @author Administrator
         * @param apk文件路径
         *            c:\1.apk
         * @param zip文件保存的路径
         *            如c:\1
         * @param b
         *            源文件是否删除。false表示不删除 true 表示删除
         * @return 返回zip文件的路径
         * 
         */
        public static String apkToZip(String apkPath, String zipPath, Boolean b) {
            // TODO Auto-generated method stub
            File apk = new File(apkPath);
    
            // 获取apk文件的名字。去掉后缀。作为zip文件名
            String apkName = apk.getName();
            int p = apkName.indexOf(".apk");
            String zipName = apkName.substring(0, p) + ".zip";
    
            File zip = new File(zipPath + File.separatorChar + zipName);
    
            // 检查文件是否存在、存在则删除
            if (zip.exists()) {
                zip.delete();
            }
    
            if (b) {
                // 重命名
                apk.renameTo(zip);
            } else {
                // 读取文件 到另一个文件
                FileInputStream fis = null;
                FileOutputStream fos = null;
    
                try {
                    fis = new FileInputStream(apk);
                    fos = new FileOutputStream(zip);
                    int c = 0;
                    byte[] bys = new byte[1024];
    
                    while ((c = fis.read(bys)) != -1) {
                        // fos.write(bys);
                        fos.write(bys, 0, c);
                        fos.flush();
                    }
    
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } finally {
                    try {
                        fos.close();
                        fis.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
    
            }
    
            return zip.getAbsolutePath();
    
        }
    
        /**
         * @description 移动文件到指定路径.是剪切操作
         * @param 源文件的路径
         *            c:\1.txt
         * @param 指定的目录
         *            c:\1
         */
        public static void moveTo(String from, String to) {
            // TODO Auto-generated method stub
            File fromF = new File(from);
            String toName = to + File.separatorChar + fromF.getName();
            File toF = new File(toName);
            fromF.renameTo(toF);
    
        }
    
        public static void log(String logPath, String logstr) {
            File f = new File(logPath);
            FileOutputStream fos = null;
    
            try {
                fos = new FileOutputStream(f, true);
                try {
                    fos.write(logstr.getBytes());
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                try {
                    fos.flush();
                    fos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    
        /**
         * @param mainfest文件的路径
         * @return String[2]。第一个参数表示 有多少权限。第二个参数则是权限的字符串.第三个参数。是否具有配置文件中的3个权限
         */
        public static String[] readPermission(String mainfesttxtPath) {
    
            // 读取配置文件的参数
            InputStream in;
            String pr1 ="";
            String pr2 ="";
            String pr3 ="";
    
            try {
                in = new BufferedInputStream(new FileInputStream("e:\test\per.properties"));
    
                Properties pr = new Properties();
    
                pr.load(in);
                
                pr1 = pr.getProperty("pr1").toLowerCase();
                pr2 = pr.getProperty("pr2").toLowerCase();
                pr3 = pr.getProperty("pr3").toLowerCase();
            } catch (FileNotFoundException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
    
            String[] returnArray = new String[3];
            File f = new File(mainfesttxtPath);
    
            FileInputStream fis = null;
            StringBuffer sb = new StringBuffer();
    
            try {
                fis = new FileInputStream(f);
    
                int c = 0;
                byte[] bys = new byte[1024];
    
                try {
                    while ((c = fis.read(bys)) != -1) {
                        // fos.write(bys);
                        sb.append(new String(bys, 0, c));
                    }
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
    
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                try {
                    fis.close();
    
                    
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
    
            String temp = sb.toString().toLowerCase();
    
            // 判断有多少权限
            int count = 0;
    
            // 获得最后一次出现的位置
            String findStr = "<uses-permission";
    
            int p = temp.indexOf(findStr);
            while (-1 != p) {
                count++;
                // System.out.println("第"+count+"权限");
                p = temp.indexOf("<uses-permission", p + findStr.length());
            }
    
            returnArray[0] = count + "";
    
            // 截取权限的字符串
            // 找到第一次的位置。
            // 找到最后一次的位置。
            // 截取字符串即可
            int p1 = temp.indexOf("<uses-permission");
            int p2 = temp.lastIndexOf("</uses-permission>");
    
            String perStr = temp.substring(p1, p2);
    
            returnArray[1] = perStr + "</uses-permission>";
            
            //判断是否具备制定的3个权限。这里全部转换为小写字母进行比对
            String configPerStr = "";
            if(temp.indexOf(pr1) > 0){
                configPerStr +="[具备"+pr1+"权限]";
            }
            if(temp.indexOf(pr2) > 0){
                configPerStr +="[具备"+pr2+"权限]";
            }
            if(temp.indexOf(pr3) > 0){
                configPerStr +="[具备"+pr3+"权限]";
            }
            
            returnArray[2] = configPerStr;
            
    
            return returnArray;
    
        }
    
        /**
         * 获得目录下的文件。这里只获取一级。不递归。
         * 
         * @param 目录的路径
         * @return 目录下文件的数组.
         */
        public static File[] getDirFile(String dirPath) {
            // TODO Auto-generated method stub
            File f = new File(dirPath);
    
            File[] fs = null;
    
            if (f.isDirectory()) {
    
                fs = f.listFiles();
            }
    
            return fs;
    
        }
    
        /**
         * apk文件。获取权限数据方法。
         */
        public static void apkPer(File af) {
    
            // String apk = "e:\test\TTXL-FengWang-release-1504271406.apk";
            String apk = af.getAbsolutePath();
            // String apk ="e:\test\AndroidManifest.apk";
            String zipTargetPath = "e:\test\zips";
            String logPath = "e:\test\log.txt";
    
            String resultPath = "e:\test\result.txt";
            
            //当前的时间
            Date d = new Date();
            DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    
            FileUtils.log(logPath,
                    "
    
    
    --------------------" + af.getName()
                            + "开始--------"+format.format(d)+"-----------------");
    
            // 将apk文件变成zip文件
            String zipPath = FileUtils.apkToZip(apk, zipTargetPath, false);
    
            FileUtils.log(logPath, "
    --->>获得zip文件");
    
            // 取得zip文件路径
            // System.out.println(zipPath);
    
            // 解压zip文件。
    
            try {
                FirstZip.unzip(zipPath, "e:\test\unzips");
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
            // 解压需要时间。这里需要等待
            try {
                Thread.sleep(1000 * 3);
            } catch (InterruptedException e2) {
                // TODO Auto-generated catch block
                e2.printStackTrace();
            }
    
            FileUtils.log(logPath, "
    --->>完成解压");
    
            // 移动main.xml文件到指定目录下。执行bat
            FileUtils.moveTo("e:\test\unzips\AndroidManifest.xml",
                    "e:\test\apktools");
    
            FileUtils.log(logPath, "
    --->>移动完成");
    
            // 执行cmd命令.
            String cmd = "cmd /c start e:\test\apktools\AXMLPrinter.bat";
            Runtime rt = Runtime.getRuntime();
    
            try {
                Process p = rt.exec(cmd);
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
    
            FileUtils.log(logPath, "
    --->>运行bat");
    
            try {
                Thread.sleep(1000 * 5);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    
            // 解析mainfest.txt文件。
            // 这里读取txt文件。取出里面的权限字符串。
            // 这里可以转成xml。读取里面的节点
            // 权限字符串。以<uses-permission 与</uses-permission>之间。
            String mainfestPath = "e:\test\apktools\AndroidManifest.txt";
            String[] perArray = FileUtils.readPermission(mainfestPath);
    
            // 组合下字符串。
            String result = "
    ---------" + af.getName()
                    + "---------------------";
            result += "
    拥有的权限数量为" + perArray[0];
    //        result += "
    具体权限为" + perArray[1];
            result +="
    制定的权限是否具备:"+perArray[2];
    
            result += "
    ------------------------------";
    
            FileUtils.log(resultPath, result);
    
            FileUtils.log(logPath, "
    --->>处理权限");
    
            FileUtils.log(logPath, "
    -------------------" + af.getName()
                    + "结束-------------------------");
    
            // System.out.println(perArray[0]);
            // System.out.println("-------------------------");
            // System.out.println(perArray[1]);
    
        }
    
    }

    最后补充。这里的解压缩包,使用了apache的ant.jar。自己去下载下吧。博客园没附件功能。。。。

    工程下载地址:http://download.csdn.net/detail/douniwan123654/8645939

  • 相关阅读:
    Makefile 运行
    fortran中//表示什么啊?双斜杠
    如何设置EXCEL打印范围
    Makefile学习_简介
    小白初学Ioc、DI、Castle Windsor依赖注入,大神勿入(不适)
    小白初学ABP框架,着实累啊
    职场初体验
    3.8.1 块作用域
    3.8 控制流程
    3.7.3 文件输入与输出
  • 原文地址:https://www.cnblogs.com/jsRunner/p/4466338.html
Copyright © 2011-2022 走看看