APP被修改检测探索

一、背景介绍

现在市面上,诸如:MT管理器、APK Editor等软件,可以对APK文件进行修改,提取AndroidManifest文件,修改包名、版本号、图标、应用名称等。

通过修改版本号,可以跳过应用升级检测,从而出现新版本修复的漏洞无法修复的情况;还会造成新功能无法使用,新推广的业务无法正常展开。

二、修改检测

通过研究,发现要达到上述修改目的,势必要对APK文件进行修改,再重新打包签名安装。

我们知道,Android在安装apk时,会在目录 /data/app/包名/ 路径拷贝一份APK文件:base.apk。因此,可以通过获取到base.apk文件,计算base.apk的MD5,检测文件是否被修改。

同时可以获取以下信息:app的 包名、版本号、名称、签名信息、md5,上报服务接口进行校验,从而阻止被修改的app继续使用。

交互流程

三、客户端获取信息
1、AppInfoUtils
public class AppInfoUtils {

    // 获取appid
    public static String getAppId(Context context) {
        return context == null ? "" : context.getPackageName();
    }

    // 获取app名称
    public static String getAppName(Context context) {
        return context == null ? "" : context.getString(context.getApplicationInfo().labelRes);
    }

    // 获取base.apk的路径
    public static String getBaseApkPath(Context context) {
        return context == null ? "" : context.getApplicationInfo().sourceDir;
    }

    // 获取appVersionName
    public static String getAppVersionName(Context context) {
        try {
            return context == null ? "" : context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    // 获取appVersionCode
    public static long getAppVersionCode(Context context) {
        if (context == null) return 0;
        try {
            PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
            return AndroidSysUtils.isOverP9() ? packageInfo.getLongVersionCode() : packageInfo.versionCode;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    // 获取签名文件的md5
    public static String getSignMD5(Context context) {
        if (context == null) return "";
        try {
            Signature[] signatures;
            if (AndroidSysUtils.isOverP9()) {
                PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNING_CERTIFICATES);
                SigningInfo signingInfo = packageInfo.signingInfo;
                signatures = signingInfo.getApkContentsSigners();
            } else {
                PackageInfo packageInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);
                signatures = packageInfo.signatures;
            }
            StringBuilder stringBuilder = new StringBuilder();
            for (Signature signature : signatures) {
                stringBuilder.append(MD5Utils.getMd5ByByteArray(signature.toByteArray())).append(",");
            }
            return stringBuilder.substring(0, stringBuilder.length() - 1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    // 获取base.apk的md5
    public static String getBaseApkMD5(Context context) {
        try {
            return context == null ? "" : MD5Utils.getMd5ByFile(getBaseApkPath(context));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
}
2、MD5Utils
public class MD5Utils {
    public static String getMd5ByFile(String fileName) {
        FileInputStream in = null;
        try {
            in = new FileInputStream(fileName);
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] buffer = new byte[1024];
            int readCound;
            while ((readCound = in.read(buffer)) > 0) {
                md5.update(buffer, 0, readCound);
            }
            BigInteger bi = new BigInteger(1, md5.digest());
            return bi.toString(16);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return "";
    }

    public static String getMd5ByByteArray(byte[] byteArray) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            md5.update(byteArray);
            BigInteger bi = new BigInteger(1, md5.digest());
            return bi.toString(16);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值