最近在学习使用Frida,主要是Android 7之后,Xposed不大容易安装。写这篇文章,方便之后用的时候,直接按记录的文档进行操作。
安装与环境配置
- pc端安装frida
C:\Users\user>pip install frida
- 手机端设置
- 下载
frida-server
https://github.com/frida/frida/releases
下载好之后,push 进手机,最好先root
C:\Users\user>adb root
C:\Users\user>adb remount
C:\Users\user>adb push D:\work\demo\Frida\frida-server-14.0.8-android-arm\frida-server-14.0.8-android-arm /data/local/tmp/frida-server
2021-06-03 更新
PS C:\Users\user> adb push E:\work\main_dir\code\Python_job\Frida\frida-server-14.2.18-android-arm\frida-server-14.2.18-android-arm /data/local/tmp/frida-server
更新结束
- 修改权限
C:\Users\user>adb -s 16744485 shell
root# cd data/local/tmp/
/data/local/tmp #chmod 777 frida-server
- 运行
adb shell ./data/local/tmp/frida-server
/data/local/tmp # ./frida-server
- 代理转发
C:\Users\user>adb -s 16744485 forward tcp:27043 tcp:27043
C:\Users\user>adb -s 16744485 forward tcp:27042 tcp:27042
如果没有多台设备,直接
C:\Users\user>adb forward tcp:27043 tcp:27043
C:\Users\user>adb forward tcp:27042 tcp:27042
这样 Frida就运行好了,剩下的就是编写hook代码了。
代码编写
- 要Hook的类与方法代码
public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
Button mTest;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
mTest= (Button)findViewById(R.id.test_btn);
mTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//startActivity(new Intent(MainActivity.this, BIanjiActivity.class));
String re = getTest("weuou");
Log.d("Fuck", "reshih = "+re);
}
});
}
private String getTest(String ss){
Log.d("Fuck", "ss ="+ss);
return "123"+ss+"222";
}
}
简单的测试代码,只是用来试试,能不能修改getTest的返回值
- python代码
import frida
import sys
rdev = frida.get_remote_device()
session = rdev.attach("com.vovo.voffice") # 要hook的apk包名
src = """
Java.perform(function(){
var mainAc = Java.use("com.vovo.voffice.MainActivity");
mainAc.getTest.overload("java.lang.String").implementation = function () {
send("Hook Start...");
var arg = arguments[0];
send("getTest arg:"+arg);
var res = this.getTest("5656");
send("getTest res:"+res);
return this.getTest("5656") + "yyyy";
}
});
"""
script = session.create_script(src)
def on_message(message, data):
print(message)
print(data)
script.on("message", on_message)
script.load()
sys.stdin.read()
运行结果:
logcat
08-10 17:01:06.286: D/Fuck(4923): ss =5656
08-10 17:01:06.296: D/Fuck(4923): ss =5656
08-10 17:01:06.297: D/Fuck(4923): reshih = 1235656222yyyy
python输出log:
{'type': 'send', 'payload': 'Hook Start...'}
None
{'type': 'send', 'payload': 'getTest arg:weuou'}
None
{'type': 'send', 'payload': 'getTest res:1235656222'}
None
可以看到
调用了2次getTest,所以,logcat中,打印了2次ss =5656
但是,最后的结果是return this.getTest("5656") + "yyyy";
运行的结果。
reshih = 1235656222yyyy
简单的教程结束,之后,如果有实际运用,会继续记录。
3、so的延迟hook
function hookAll(){
....
}
function hookMain(){
Java.perform(function () {
var libc=Module.findExportByName("libc.so","dlopen");
var find = 0;
Interceptor.attach(Module.findExportByName("libc.so" , "dlopen"), {
onEnter: function(args) {
var addr = args[0];
var str = Memory.readCString(addr);
// console.log("dlopen ",soName);
if (str.indexOf(soName) > 0){
find = 1;
console.log("dlopen:",soName);
}else{
find = 0;
}
},
onLeave:function(retval){
if (find > 0){
hookAll();
}
}
});
}
}
参考资料
官网:https://www.frida.re/docs/android/
GitHub:https://github.com/frida/frida/releases
Android逆向之旅---Hook神器家族的Frida工具使用详解