Frida使用—js脚本记录

        本篇用于记录我在使用frida时的一些脚本,以便后续查阅。

目录

一、代码结构

二、脚本

(1)常用函数Hook

HashMap

ConcurrentHashMap

(2)可能用到的脚本

打印Map的值

打印调用堆栈

(3)hook初始化函数

(3)需要注意的地方

三、总结


一、代码结构

import frida, sys


def on_message(message, data):
    if message['type'] == 'send':
        print("[*] {0}".format(message['payload']))
    else:
        print(message)

src = """
Java.perform(
    function test(){
        var v = Java.androidVersion;
        send('Version:' + v)
        console.log("process pid = " + Process.id);
    }
);
"""

dev = frida.get_usb_device()
pid = dev.spawn("com.example")
process = frida.get_usb_device().attach(pid)
script = process.create_script(src)
script.on('message', on_message)
print('[*] HooK Start running')
script.load()
dev.resume(pid)
sys.stdin.read()

        src 中即为js脚本内容,在启动frida时使用了resume是因为需要hook一些启动时只执行一次的函数,正常情况下不需要这一步。

二、脚本

(1)常用函数Hook

HashMap

var HashMap = Java.use('java.util.HashMap');
HashMap.get.implementation = function(key) {
    if(key !== null){
        let keyStr = (key.toString())
        if (keyStr.includes("xxx") || keyStr.includes("xxx")){
            console.log("HashMap get() called with key: " + keyStr);
            var result = this.get(key);
            console.log("HashMap get() returned: " + result);
            return result;
        }else{
            var result = this.get(key);
            return result;
        }
    }
        var result = this.get(key);
        return result;
    };
    HashMap.put.implementation = function(key, value) {
        if(key !== null){
            let keyStr = (key.toString())
            if (keyStr.includes("xxx")){
                console.log('put function called with key: ' + key + ' and value: ' + value);
                return this.put(key, value);
            }else{
                return this.put(key, value);
            }
        }
        return this.put(key, value);
    };

        此处加入了一些判断,懒得删了

ConcurrentHashMap

var ConcurrentHashMap = Java.use('java.util.concurrent.ConcurrentHashMap');
ConcurrentHashMap.get.implementation = function(key) {
    let keyStr = (key.toString())
    if(keyStr.includes("xxx")){
        console.log('ConcurrentHashMap.get 方法被调用,key: ' + key);
        var result = this.get(key);
        console.log('ConcurrentHashMap.get result ' + result);
        var resultClass = result.getClass();
        var fields = resultClass.getDeclaredFields();
        for (var i = 0; i < fields.length; i++) {
            fields[i].setAccessible(true);
            var fieldName = fields[i].getName();
            var fieldValue = fields[i].get(result);
            console.log(fieldValue.getClass().getName());
            console.log(fieldName + ': ' + fieldValue);
        }
        return result;
    }else{
        var result = this.get(key);
        return result;
    }
};

        也加入了一些筛选,并能通过反射获取obj的字段及字段值

(2)可能用到的脚本

打印Map的值

var HashMap = Java.use('java.util.HashMap');

let A= Java.use("com.example.A");
A["a"].overload('int', '[B', 'java.util.Map').implementation = function (i2, bArr, map) {
        console.log(`A.a is called: i2=${i2}, bArr=${bArr}, map=${map}`);
        let result = this["a"](i2, bArr, map);
        console.log("A.a.map:" + Java.cast(map, HashMap).toString());
        console.log(`a.a result=${result}`);
        return result;
    };   

打印调用堆栈

function printstack() {           
    send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()))
}

let B = Java.use("com.example.B");
B["a"].overload('java.lang.String', 'java.lang.String').implementation = function (str, str2) {
    console.log(`B.a is called: str=${str}, str2=${str2}`);
    let result = this["a"](str, str2);
    console.log(`B.a result=${result}`);
    /*printstack();*/
    return result;
};

        想要打印堆栈把注释去了即可。

(3)hook初始化函数

var HashMap = Java.use('java.util.HashMap');

let C = Java.use("com.example.C");   
C["$init"].implementation = function (map) {
    console.log(`C.$init is called: map=${map}`);
    console.log("C.map:" + Java.cast(map, HashMap).toString());
    this["$init"](map);
};

(3)需要注意的地方

        目前我想到的需要注意的地方,首先注意有没有多个实现,有的话加上overload,然后有些native函数的hook也是可以hook到的,再就是注意frida版本,版本低了可能有些东西hook不到,也不一定吧,只是可能。

三、总结

        只是自己用的脚本的一些总结,也许还会往里面加点儿以后?最后感谢jadx,能直接给我frida代码(不会还有人不知道jadx右键能自己生成firda代码吧)

        2024.6.14

Frida是一款强大的应用程序动态分析工具,可以用于拦截和修改应用程序的行为。以下是一些步骤,可以使用Frida获取应用程序获取用户隐私信息的行为。 1. 在PC上安装Frida工具和Python环境,可以使用pip来安装Frida库。 2. 在手机上安装Frida-Server,并启动它。 3. 使用Frida-Client连接到Frida-Server: ``` frida -U -f com.example.app --no-pause ``` 其中,com.example.app是要检测的App的包名。 4. 使用Frida-Script编写Hook脚本,拦截和修改应用程序的行为。以下是一个可以检测应用程序获取用户隐私信息的示例脚本: ```javascript Java.perform(function() { var Context = Java.use('android.content.Context'); Context.getSystemService.implementation = function(serviceName) { // 拦截系统服务的获取,检查是否获取了隐私相关的服务 if (serviceName === 'phone' || serviceName === 'telephony' || serviceName === 'sms' || serviceName === 'location') { // 记录获取隐私服务的行为 console.log('应用程序获取隐私服务:', serviceName); } // 继续正常获取系统服务 return this.getSystemService(serviceName); }; }); ``` 在这个示例脚本中,我们使用Java.perform()来获取Context类,并重写了它的getSystemService()方法。在重写方法中,我们检查是否获取了名为'phone'、'telephony'、'sms'、'location'等隐私相关的系统服务,如果获取了,则记录下来。 当应用程序获取系统服务时,这个Hook脚本就会被触发,如果服务名称是隐私相关的,则会输出一条日志,记录下应用程序获取隐私服务的行为。 需要注意的是,这个过程需要一定的技术和经验,如果您不确定如何做或者没有相关的技术背景,建议寻求安全专家的帮助。同时,为了保护用户隐私,不要将这些技术用于非法活动。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值