Frida绕过APK的签名校验
APP简单启动顺序
- 点击APP启动
- 执行Application(attach, onCreate方法)
- 执行开屏界面Activity
- 执行Main
- Activity(onCreate方法) 启动成功
简单签名校验
签名校验一般在APP启动阶段
几个安卓中常见的类
Context类
:android.content.Context保存应用环境信息
PackageManager类
: 获取安卓系统信息和APP的信息
Signature类
:
https://developer.android.google.cn/reference/android/content/pm/Signature
签名校验一般格式
例如:context.getPackageManager().getPackageInfo(context.getPackageName(), 64).signatures[0].hashCode()
可以尝试使用签名关键字搜索或hook的方式去定位关键代码。
hook方法寻找签名校验
如果代码被混淆,我们无法通过搜索关键字定位到签名校验代码位置,就需要使用firda进行hook定位;一般是hook其中的Signature中的方法;
注意:这里要使用以
spawn
方式启动Frida
//先尝试hook一波hashcode()发现没有,再加入hook一波toByteArray()
Java.perform(
function(){
console.log('enter frida');
var signature = Java.use('android.content.pm.Signature')
signature.hashCode.implementation = function(){
console.log('enter signature.hashCode')
return this.hashCode()
}
signature.toByteArray.implementation = function(){
console.log('enter signature.toByteArray')
return this.toByteArray()
}
}
)
以spawn
方式启动Frida,控制台打印出:“enter signature.toByteArray”,说明调用了这个方法,尝试打印其堆栈,看看能否找到其关键代码进行定位:
function printstack() {
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
}
控制台打印结果如下:
根据堆栈找到其代码位置:
观察后可以得知这是一个检验签名的代码,可以直接hook其返回值,令其直接返回true,完整代码如下:
Java.perform(
function(){
console.log('enter frida');
var signature = Java.use('android.content.pm.Signature')
signature.hashCode.implementation = function(){
console.log('enter signature.hashCode')
return this.hashCode()
}
signature.toByteArray.implementation = function(){
console.log('enter signature.toByteArray')
//printstack()
return this.toByteArray()
}
var hook_signature = Java.use('com.chaozhuo.texteditor.widget.a')
hook_signature.a.overload('android.content.Context').implementation = function(){
console.log('enter hook_signature.a')
return true
}
function printstack() {
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
}
}
)