签名校验
反编译 dex,修改重新打包签名后 apk 的签名信息肯定会改变,所以可以在代码中判断签名信息是否不一致,不一致就不进入程序。
public static String getSignature(Context context) {
PackageManager pm = context.getPackageManager();
PackageInfo pi;
StringBuilder sb = new StringBuilder();
try {
pi = pm.getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES);
Signature[] signatures = pi.signatures;
for (Signature signature : signatures) {
sb.append(signature.toCharsString());
}
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return sb.toString();
}
拿到字符串以后,可以对字符串进行MD5加密等加密手段,然后与存放在本地的加密字符串作比较,不相等则不进入APP。originalSign为自己打包签名文件所得到的字符串。
public static boolean verifySignature(Context context, String originalSign){
String currentSign = getSignature(context);
if (originalSign.equals(currentSign)) {
return true;//签名正确
}
return false;//签名被篡改
}
对classes.dex文件完整性校验
DEX文件打包在APK文件中,针对APK代码的篡改攻击就是针对该文件,比如使用apktool工具反编译文件,修改smali代码。以下就是通过检查classes.dex文件的CRC32值来判断文件是否被篡改。
其中R.string.str_code是存放在本地的crc加密后的值,string.xml文件是不在dex文件中的,所以修改string.xml文件是不会造成crc值的变化(亲测),其实也可以把这个值存放在后台,通过请求网络来获取。(感觉没必要,为什么,往下看哈)
private void checkCRC() {
String orginalCrc = getString(R.string.str_code);
ZipFile zf;
try {
zf = new ZipFile(getApplicationContext().getPackageCodePath());
ZipEntry ze = zf.getEntry("classes.dex");
String strCrc = String.valueOf(ze.getCrc());
String MD5Crc = MD5Util.GetMD5Code(strCrc);
Log.e("checkcrc", MD5Crc);
if (!orginalCrc.equals(MD5Crc)) {
//ActivityManagerUtil.getScreenManager().removeAllActivity();
Process.killProcess(Process.myPid());
}
} catch (IOException e) {
e.printStackTrace();
}
}
还有其它几种方法,比如校验APK包的完整性、对签名文件中classes.dex哈希值的校验等。其实都大同小异。
把这些手段用在了程序中,但是通过多次反编译,都很容易确认程序在什么地方做了这些处理(可全局搜索关键词),恶意破解的话直接将修改返回值true或false,或者修改接收这个函数的if-else语句条件取个反,直接就绕过了判断。
留言