安卓签名校验绕过:Frida hook和native层两种方案
很多 App 会校验自身签名,防止被重打包篡改。做逆向需要绕过签名校验。一、校验原理
App 在代码里获取自身签名,跟预设的签名指纹对比。不一致就退出。代码通常用 PackageManager.getPackageInfo 获取签名。
二、Frida 绕过
Java.perform(function() {
var PackageManager = Java.use("android.app.PackageManager");
var PackageInfo = Java.use("android.content.pm.PackageInfo");
// hook getPackageInfo
PackageManager.getPackageInfo.overload('java.lang.String', 'int').implementation = function(name, flags) {
var info = this.getPackageInfo(name, flags);
// 伪造签名字段
try {
var signatures = Java.array("android.content.pm.Signature", [
Java.use("android.content.pm.Signature").$new("预设的签名hex")
]);
info.signatures.value = signatures;
} catch(e) {}
return info;
};
});
三、更简单的方案:hook 比较
如果 App 用 String.equals 比较签名哈希,直接 hook 比较函数让它返回 true:
Java.perform(function() {
var String = Java.use("java.lang.String");
String.equals.implementation = function(other) {
if (this.toString().length === 64) {
return true; // 签名hash比较直接返回true
}
return this.equals(other);
};
});
四、Native 层校验
有些 App 把签名校验放 native 层(so 库里),用 IDA 找到校验函数,Frida hook native 函数:
Interceptor.attach(Module.findExportByName("libtarget.so", "verify_signature"), {
onLeave: function(retval) {
retval.replace(1); // 返回校验通过
}
});
https://www.metk.cn/img/posts/signature_bypass.jpg 楼主的排版可以再优化下,代码块用起来会更清楚。 看完最大的感受是基础知识还是要扎实,不然工具报错都不知道怎么查。 这个流程我在真机上验证过,确实可行,注意备份就行。 试了下你说的第二种方法,成功率更高,推荐。 同求后续,想知道绕过之后怎么稳定保持,重签名这块一直搞不定。 步骤写得很清楚,跟着走了一遍,卡在第二步的环境配置上,后来装了老版本才好。 这个思路让我想到另一个场景,回头试试能不能套用。 这篇干货,比那些只有命令没有解释的强太多了。 讲得挺细的,不过我建议加一句免责,这东西容易被拿去做坏事。