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的方式去定位关键代码。
实战案例:
首先使用jadx反编译APP,先尝试搜索signature
发现没有找到其签名校验的关键代码,接下来尝试使用frida进行hook。
//先尝试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()));
}
}
)