Frida上手和逆向三段
本章主要内容:
Frida基本操作:参数、调用栈、返回值
Frida精髓:方法重载、参数构造、动静态处理、主动调用、忽略内部细节,直接返回结果
逆向三段:(hook ・invoke)・rpc
编写代码测试hook
新建一个java类型的项目
目标Demo源码
package com.xiaoeryu.lesson4_4;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
while (true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
int m = fun(4, 5);
}
}
int fun(int x, int y){
Log.d("xiaoeryu", String.valueOf(x + y));
return x + y;
}
}
hook被调用的fun()
函数
function main(){
Java.perform(function(){
Java.use("com.xiaoeryu.lesson4_4.MainActivity").fun.implementation = function(arg1, arg2){
var result = this.fun(arg1, arg2);
console.log("arg1, arg2, result", arg1, arg2, result);
return result;
}
})
}
setImmediate(main)
方法重载hook
给源码添加一个重载函数,并调用
int fun(int x, int y){
Log.d("xiaoeryu", String.valueOf(x + y));
return x + y;
}
有重载情况下的hook
function main(){
Java.perform(function(){
// overloading with two parameters
Java.use("com.xiaoeryu.lesson4_4.MainActivity").fun.overload('int', 'int').implementation = function(arg1, arg2){
var result = this.fun(100, 200); // parameters can be changed
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new())); // print call stack
console.log("arg1, arg2, result", arg1, arg2, result);
return result;
}
// overloading with a one parameter
Java.use("com.xiaoeryu.lesson4_4.MainActivity").fun.overload('java.lang.String').implementation = function(arg1){
var result = this.fun(Java.use('java.lang.String').$new('NIHAO')); // parameters can be changed
console.log("arg1, result", arg1, result);
return result;
}
})
}
setImmediate(main)
主动调用未被调用的函数
hook方法
Java.choose("com.xiaoeryu.lesson4_4.MainActivity",{
onMatch:function(instance){
console.log("found instance: ", instance)
console.log("found instance: ", instance.secret())
},onComplete:function(){}
})
静态方法
如果是静态方法的话,会更简单点
hook方法
var result = Java.use("com.xiaoeryu.lesson4_4.MainActivity").secret2();
console.log(result);
实践
把各种情况分析完了,用上一章测试用的CTF题目来实践一下
在hook的时候如果是动态方法的话,我们需要去搜索实例,如果是静态方法直接调用就ok
用jadx可以看到我们要调用的
a方法
没有static修饰,是一个动态方法这样的话我们就需要在
MainActivity
类中去搜索它的实例去调用
上一章已经分析过了,我们要hook的是里面的getWritableDatabase
函数
- 可以看到这个函数有重载,对于有重载的方法如果我们不确定应该hook哪一个就可以全部都hook
hook方法
- 可以看到报错提示有重载,修改一下脚本hook这两个重载
- 修改完就不报错了,但是因为没有调用所以我们也获取不到想要的信息
在MainActivity中搜索实例a并调用
function invoke(){
Java.perform(function(){
Java.choose("com.example.yaphetshan.tencentwelcome.MainActivity", {
onMatch:function(instance){
console.log("found instance ", instance);
console.log("invoke instance.a ", instance.a());
}, onComplete:function(){console.log("search completed!")}
})
})
}
实现完成CTRL+S
保存一遍就执行了
- 可以看到密码已经被我们成功的拿到了
- 并且可以看到是通过参数为String的重载拿到的
- 顺便也打印它的调用堆栈看一下
附件:
- 标题: Frida上手和逆向三段
- 作者: xiaoeryu
- 创建于 : 2023-11-17 17:05:39
- 更新于 : 2023-11-24 16:18:10
- 链接: https://github.com/xiaoeryu/2023/11/17/Frida上手和逆向三段/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论