准备阶段
Android 应用开发

先准备一个工程,编写以下代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| package cn.mineseb.rpc;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle; import android.util.Log;
public class MainActivity extends AppCompatActivity {
private String total = "codecat"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);
while (true){ try { Thread.sleep(1000); }catch (InterruptedException e){ e.printStackTrace(); } }
}
void fun(int x,int y){ Log.d("r0ysue.com",String.valueOf(x+y)); } String fun(String x){ return x.toLowerCase(); } void secret(){ total += "cool!!!"; Log.d("secret","this is secret func"); } static void staticSecret(){ Log.d("staticSecret","this is static secret func"); } }
|
将模拟器 adb 链接 studio 并且点击开始按钮后 出现 成功

主动调用

拷贝包名 copy path
cn.mineseb.rpc.MainActivity
静态方法
静态方法直接调用即可
MainActivity.staticSecret;
但是非静态方法调用不可用.来调用
Java.choose(‘cn.mineseb.rpc.MainActivity’, {
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| function main() { console.log('Script loaded successfully') Java.perform(function () { console.log('Java perform function') var MainActivity = Java.use('cn.mineseb.rpc.MainActivity') MainActivity.staticSecret
Java.choose('cn.mineseb.rpc.MainActivity', { onMatch: function (instance) { console.log('instance found', instance)
console.log('===========before========') console.log('total >>>> ', instance.total.value) instance.secret() console.log('===========after=========') console.log('total >>>> ', instance.total.value) }, onComplete: function () { console.log('search Complete') }, }) }) } setTimeout(main, 2000)
|

RPC
RPC 的目的是我们可以通过远程调用 实现自动化 所以我们需要借助 python 来进行通信 如果需要进行实时的话可以加上 WebSocket 进行通信
使用上面提到的 APP Demo
修改 Frida Js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| function callSecretFunc() { Java.perform(function() { Java.choose('cn.mineseb.rpc.MainActivity'. { onMatch: function(instance) { console.log("=====callSecretFunc======"); instance.secret(); }, onComplete: function() {} }) }) }
function getTotalValue() { Java.perform(function() { var MainActivity = Java.use("cn.mineseb.rpc.MainActivity") Java.choose('cn.mineseb.rpc.MainActivity', { onMatch: function(instance) { console.log("=====getTotalValue======"); console.log(instance.total.value); }, onComplete: function() {
} }) }) }
setTimeout(getTotalValue, 2000)
|
Frida hook

在 js 脚本后面导出
注意导出名称不可包含大写字母或者下划线
1 2 3 4
| rpc.exports = { callsecretsunc: callSecretFunc, gettotalvalue: getTotalValue, }
|

出现这个错误时候 但是 adb 是连接的 并且手机端 frida 是打开的 说明映射没有开启
adb forward tcp:27042 tcp:27042

提示

选择用 spawn 进行 hook
1 2 3 4 5 6 7 8 9 10 11 12
| device = frida.get_remote_device() pid = device.spawn(["cn.mineseb.rpc"]) session = device.attach(pid) device.resume(pid)
with open("rpc.js") as f: jscode = f.read()
script = session.create_script(jscode) script.on('message', on_message) print('[*] Hook Start Running') script.load()
|
远程 python 脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import frida, sys
def on_message(message, data): if message['type'] == 'send': print("[*] {0}".format(message['payload'])) else: print(message)
device = frida.get_remote_device() pid = device.spawn(["cn.mineseb.rpc"]) session = device.attach(pid) device.resume(pid)
with open("rpc.js") as f: jscode = f.read()
script = session.create_script(jscode) script.on('message', on_message) print('[*] Hook Start Running') script.load()
command = ""
while True: command = input("command = ") if command == "0": break elif command == "1": script.exports.callsecretsunc() else: script.exports.gettotalvalue()
|

总结
通过 frida 的主动调用可以实现自吐算法 不用去跟进。将关键算法拿到并且 fridaHook 成功 与 rpc 相结合可以实现远程调用,不用自写算法即可拿到加密后的值,实现自动化