日期:2023-04-27 作者:Zero 介绍:Frida 工程师的备忘录小本本。
1、前言
很久很久以前,有一个东西叫Xposed
,在Android
上秒天秒地秒空气,但是随着慢慢发展Xposed
的一些短板渐渐出现,每次安装新的模块都要重启(虽然后来出现了一些免重启方案)等问题。后来Frida
横空出世,它相当于给程序注入了一个修改版的Chrome
内核,用Javascript
作为脚本语言,学习成本也较低廉,同时这个Hook
工具可Hook
市面上较为流行的操作系统,不局限于Android
这一个平台,其他平台的表现也很好,功能十分强大。
现如今安卓工程师已变成Frida
工程师,一手Frida
走天下,一份常见用法备忘录分享出来,抛砖引玉。
2、Java 层
先说Java
层,我们需要用:
Java.perform(() => {
//对java层的操作
});
这个代码块包裹我们对java
的代码操作。
然后假设我们要Hook
包名com.example.seccon2015.rock_paper_scissors.MainActivity
下的onClick
函数,以及修改其中的m
、n
、cnt
的值,我们可以这样写:
Java.perform(() => {
// Function to hook is defined here
const MainActivity = Java.use('com.example.seccon2015.rock_paper_scissors.MainActivity');
// Whenever button is clicked
const onClick = MainActivity.onClick;
onClick.implementation = function (v) {
// Call the original onClick handler
onClick.call(this, v);
// Set our values after running the original onClick handler
this.m.value = 0;
this.n.value = 1;
this.cnt.value = 999;
// Log to the console that it's done, and we should have the flag!
console.log('Done:' + JSON.stringify(this.cnt));
};
});
其中先Java.use
到使用的类,然后再implementation
包名 com.example.seccon2015.rock_paper_scissors.MainActivity'
类中的onClick
函数,此时只Hook
,但是不会调用,如果不写onClick.call(this, v);
这个函数是相当于被nop
掉了,所以在Hook
函数内部重新调用一下。
而当我们遇到重载函数的时候可以:
MyClass.MyFuncs.overload("int", "int").implementation = function (s1, s2) {
var ret = this.MyFuncs(s1, s2);
}
进行指定参量Hook
。
遇到内部类时,譬如MainActivity
类中有一个User
类,我们可以这样做。
Java.use("com.example.seccon2015.rock_paper_scissors.MainActivity$User")
而对于匿名的内部类,这个时候就要看其Smali
代码了,通常为:MainActivity$1
或者MainActivity$ExternalSyntheticLambda0
形式。
3、So 层(Native层)
Hook Native
层其实也十分的方便,譬如libc.so
的open
函数:
Interceptor.attach(Module.findExportByName("libc.so" , "open"), {
onEnter: function(args) {
log("open() called!")
},
onLeave:function(retval){
}
});
而遇到未导出的匿名函数:
var base_addr = Module.findBaseAddress("libMylib.so");
先获取so
基址,然后根据IDA
等逆向软件程序,计算其偏移,再进行Hook
即可:
var nativePointer = base_addr.add(0x1498+1) //注意+1 CPU架构问题
Interceptor.attach(nativePointer, {
onEnter:
function (args) {
},
onLeave:
function (retval) {
}
});
4、Stack Trace
调试时可以方便地查看堆栈信息,虽然Frida
轻量,但也可以做到,而且还很方便。
Java.perform(function () {
var ma = Java.use('com.xx.xx.xx');
ma.onClick.implementation = function (a) {
send("Stack Trace...");
stackinfo();
}
function stackinfo(){
var threadef = Java.use('java.lang.Thread');
var threadinstance = threadef.$new();
var stack = threadinstance.currentThread().getStackTrace();
for(var i = 0;i<stack.length;i++){
send("stack:" + stack[i].toString());
}
}
});
5、Hook String
有时混淆会将应用的字符串进行加密编码,无法直观定位,此时可以通过Hook
字符串的操作,结合上面的堆栈信息进行定位。
['java.lang.StringBuilder', 'java.lang.StringBuffer'].forEach(function(clazz, i) {
Java.use(clazz)['toString'].implementation = function() {
var ret = this.toString();
console.log('ret:', ret)
return ret;
}
});
6、Bypass SSL
我们在抓取APP
数据包的时候会出现证书错误,导致抓不到包,更甚至有的开启了双向证书验证,此时我们可以通过Frida
来Hook
系统的一些函数,来强制让其验证通过。由于代码量较大影响观感,可通过公众号获取附件,获取方式见文末。
7、结语
本文仅作备忘录使用,记录的仅是个人常用的操作,肯定会有所遗漏且片面,如果有新奇的操作也可以相互交流!
0427zero
获取,感谢您能看到此处~~~ 关注我们了解更多趣事,我们下期见!免责声明:本文仅供安全研究与讨论之用,严禁用于非法用途,违者后果自负。
原文始发于微信公众号(宸极实验室):『工具使用』Frida 工程师备忘录
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论