为何你的应用老是被破解,该如何有效的做签名校验?
前言
上一篇发了个简单的NDK实现的签名校验,众所周知,签名校验是防止二次打包最普遍的方式。下面是常见的签名校验方法:
/**
* 做普通的签名校验
*/
private boolean doNormalSignCheck() {
String trueSignMD5 = "d0add9987c7c84aeb7198c3ff26ca152";
String nowSignMD5 = "";
try {
// 得到签名的MD5
PackageInfo packageInfo = getPackageManager().getPackageInfo(
getPackageName(),
PackageManager.GET_SIGNATURES);
Signature[] signs = packageInfo.signatures;
String signBase64 = Base64Util.encodeToString(signs[0].toByteArray());
nowSignMD5 = MD5Utils.MD5(signBase64);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return trueSignMD5.equals(nowSignMD5);
}
系统将应用的签名信息封装在 PackageInfo 中,调用 PackageManager 的 getPackageInfo(String packageName, int flags) 即可获取指定包名的签名信息。这个并不用我多说了,如果没听过的话,用搜索引擎找一下「Android 签名校验」,花上几分钟就明白了,很容易的。
1.使用通用工具去除我们先前的校验
很多人可能不知道,去除简单的签名校验连小朋友都能做到!
下面请看具有「安全性测试」功能的「MT管理器」上场,一键去除我们上文准备好的受害者的签名校验:
神奇的一幕发生了,居然还是通过,也就是我们刚才的操作形同虚设,我们把被破解后的安装包传回 PC,准备下一步分析
2.JADX 上场
为了知道他做了什么,我们需要逆向出目前受害者的代码。这里我们使用开源项目「jadx」来完成。
打开 jadx 之后会直接弹出「打开」对话框,选取被破解的 apk 即可:
简单对比下可以发现,多了一个HookApplication类
点击进去即可直接看见源代码:
package bin.mt.apksignaturekillerplus;
public class HookApplication extends Application implements InvocationHandler {
private static final int GET_SIGNATURES = 64;
private String appPkgName = BuildConfig.FLAVOR;
private Object base;
private byte[][] sign;
private void hook(Context context) {
try {
DataInputStream dataInputStream = new DataInputStream(new ByteArrayInputStream(Base64.decode("省略很长的签名 base64", 0)));
byte[][] bArr = new byte[(dataInputStream.read() & 255)][];
for (int i = 0; i < bArr.length; i++) {
bArr[i] = new byte[dataInputStream.readInt()];
dataInputStream.readFully(bArr[i]);
}
Class cls = Class.forName("android.app.ActivityThread");
Object invoke = cls.getDeclaredMethod("currentActivityThread", new Class[0]).invoke(null, new Object[