Frida 学习记录(二)

前言

        这是参考一个外国博主的博客写的,这是他的博客地址,本次大致内容是将一个apk中原有的fun函数进行修改,但如果遇到同名函数,需要注意重新实现时注意函数参数,同时实现调用app实例中定义了但未被调用的函数。使用到了Frida、pyhon、js、adb、jadx、cmd、逍遥模拟器等工具及编程语言。环境配置参考Frida 学习实战记录(一)。

11x256's Infosec blog (infosec-blog.com)

一、开始

 (1)查看代码

        同样使用jadx打开app-2,如图所示:

        大致含义相比于第一个apk-1,无非是多了一个同名函数fun,输出一个字符串,然后定义了一个secret函数,但未在onCreate中调用。

(2)重构原有的重名函数fun

        此时如果使用(一)中同样的python脚本,会发现控制台的输出会停留在Script loaded successfully这个输出,然后停止输出,明显是出现了问题,但python控制台没有输出错误结果。

        此时使用script.on方法,可以获得js脚本的错误输出。

import frida
import time


def message_handler(message, payload):
    print(message)
    print(payload)


def hook2():
    device = frida.get_usb_device()
    pid = device.spawn(["com.example.a11x256.frida_test"])
    device.resume(pid)
    time.sleep(1)  # Without it Java.perform silently fails
    session = device.attach(pid)
    script = session.create_script(open("s2.js").read())
    script.on("message", message_handler)
    script.load()

    # prevent the python script from terminating
    input()


if __name__ == "__main__":
    hook2()

        新定义了一个message_handler的函数用来展示错误结果,在script.on中进行调用,该方法的参数将会被自动填充,无需手动设置(实际上如果改成message_handler()会报错......)。

        由此,再运行该python脚本,就可以得到错误提示,如下所示

{'type': 'error', 
 'description': "Error: fun(): has more than one overload, 
  use .overload(<signature>) to choose from:\n\t.overload('java.lang.String')\n\t.overload('int', 'int')", 'stack': "Error: fun(): has more than one overload, use .overload(<signature>) to choose 
  from:\n\t.overload('java.lang.String')\n\t.overload('int', 'int')\n    at X 
(frida/node_modules/frida-java-bridge/lib/class-factory.js:622)\n    at K 
(frida/node_modules/frida-java-bridge/lib/class-factory.js:617)\n    at set 
(frida/node_modules/frida-java-bridge/lib/class-factory.js:1099)\n    at x 
(/script1.js:5)\n    at <anonymous> (frida/node_modules/frida-java-bridge/lib/vm.js:12)\n  
  at _performPendingVmOps (frida/node_modules/frida-java-bridge/index.js:250)\n    at 
<anonymous> (frida/node_modules/frida-java-bridge/index.js:225)\n    at <anonymous> 
(frida/node_modules/frida-java-bridge/lib/vm.js:12)\n    at _performPendingVmOpsWhenReady 
(frida/node_modules/frida-java-bridge/index.js:244)\n    at perform 
(frida/node_modules/frida-java-bridge/index.js:204)\n    at <eval> (/script1.js:14)", 
'fileName': 'frida/node_modules/frida-java-bridge/lib/class-factory.js', 'lineNumber': 622, 
'columnNumber': 1}
None

        大致含义就是对于同名函数没有做处理,有多余一个的重构,导致识别出现了问题。

        由此,需要修改先前的js文件,让他对每个fun都重新实现一次,代码如下:

console.log("Script loaded successfully ");
Java.perform(function x() {
    console.log("Inside java perform function");
    var my_class = Java.use("com.example.a11x256.frida_test.my_activity");

    my_class.fun.overload("int", "int").implementation = function (x, y) { //hooking the old function
        console.log("original call: fun(" + x + ", " + y + ")");
        var ret_value = this.fun(2, 5);
        return ret_value;
    };

    my_class.fun.overload("java.lang.String").implementation = function (x) { //hooking the new function
        var string_class = Java.use("java.lang.String");
        console.log("*************************************")
        var my_string = string_class.$new("My TeSt String#####");
        console.log("Original arg: " + x);
        var ret = this.fun(my_string);
        console.log("Return value: " + ret);
        console.log("*************************************")
        return ret;
    };
});

        可以看到代码实现了两个my_class.fun.overload,分别对两个源代码中的fun函数实现了重构,从而此时再次执行python脚本,就不会出现问题,此时我把它存到了新的js文件s2.js中。

        运行该脚本后输出结果为:

Script loaded successfully 
Inside java perform function
original call: fun(50, 30)
*************************************
Original arg: LoWeRcAsE Me!!!!!!!!!
Return value: my test string#####
*************************************
original call: fun(50, 30)
*************************************
Original arg: LoWeRcAsE Me!!!!!!!!!
Return value: my test string#####
*************************************

        使用adb logcat打印日志文件,结果如下:

11-16 21:59:09.800  8303  8303 D Sum     : 80
11-16 21:59:09.800  8303  8303 D string  : lowercase me!!!!!!!!!
11-16 21:59:10.802  8303  8303 D Sum     : 7
11-16 21:59:10.809  8303  8303 D string  : my test string#####
11-16 21:59:11.818  8303  8303 D Sum     : 7
11-16 21:59:11.820  8303  8303 D string  : my test string#####
11-16 21:59:12.821  8303  8303 D Sum     : 7
11-16 21:59:12.822  8303  8303 D string  : my test string#####
11-16 21:59:13.828  8303  8303 D Sum     : 7
11-16 21:59:13.828  8303  8303 D string  : my test string#####
11-16 21:59:14.835  8303  8303 D Sum     : 7
11-16 21:59:14.838  8303  8303 D string  : my test string#####
11-16 21:59:15.842  8303  8303 D Sum     : 7
11-16 21:59:15.843  8303  8303 D string  : my test string#####
11-16 21:59:16.846  8303  8303 D Sum     : 7
11-16 21:59:16.850  8303  8303 D string  : my test string#####
11-16 21:59:17.856  8303  8303 D Sum     : 7
11-16 21:59:17.861  8303  8303 D string  : my test string#####

        可以看到它成功完成了这两个函数的重构。

(3)secret的调用

        在源码中可以看到app的代码中定义了一个secret方法,实现对totoal的输出,但它在onCreate中没有被调用,故无法使用相同的方法来hook它。

        作者使用的完整代码如下:

console.log("Script loaded successfully ");
Java.perform(function x() {
    console.log("Inside java perform function");
    var my_class = Java.use("com.example.a11x256.frida_test.my_activity");
    my_class.fun.overload("int", "int").implementation = function (x, y) { //hooking the old function
        console.log("original call: fun(" + x + ", " + y + ")");
        var ret_value = this.fun(2, 5);
        return ret_value;
    };
    var string_class = Java.use("java.lang.String");

    my_class.fun.overload("java.lang.String").implementation = function (x) { //hooking the new function
        console.log("*************************************")
        var my_string = string_class.$new("My TeSt String#####");
        console.log("Original arg: " + x);
        var ret = this.fun(my_string);
        console.log("Return value: " + ret);
        console.log("*************************************")
        return ret;
    };
    Java.choose("com.example.a11x256.frida_test.my_activity", {
        onMatch: function (instance) {
            console.log("Found instance: " + instance);
            console.log("Result of secret func: " + instance.secret());
        },
        onComplete: function () { }

    });

});

        在最后使用Java.choose完成了对隐藏方法的调用,该方法有多少个实例,该回调就会被触发多少次。

        从而结果输出为:

Script loaded successfully 
Inside java perform function
Found instance: com.example.a11x256.frida_test.my_activity@58d29a7
Result of secret func: @@@###@@@LoWeRcAsE Me!!!!!!!!!
original call: fun(50, 30)
*************************************
Original arg: LoWeRcAsE Me!!!!!!!!!
Return value: my test string#####
*************************************
original call: fun(50, 30)
*************************************
Original arg: LoWeRcAsE Me!!!!!!!!!
Return value: my test string#####
*************************************

        作者说这个Result of secret func: 的输出应该只有@@@###@@@,但我却出现了total被修改的情况,很奇怪,我尝试了重装app,重启frida,重新运行python脚本,调整js代码中Java.choose的位置,但是均没有什么用,就很奇怪,网上也有人根据这个博主的博客做过,但好像都没有出现这个问题。此处留一个坑,有空回来填。

二、总结

        第二次frida尝试结束,同样很简单,这个博主仍然还有好几篇博客等待实操。 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值