Frida hook入门

frida是有效的插桩工具。

插桩技术
插桩技术是指将额外的代码注入程序中以收集运行时的信息,可分为两种:
(1)源代码插桩[Source Code Instrumentation(SCI)]:额外代码注入到程序源代码中。
(2)二进制插桩(Binary Instrumentation):额外代码注入到二进制可执行文件中。

●静态二进制插桩[Static Binary Instrumentation(SBI)]:在程序执行前插入额外的代码和数据,生成一个永久改变的可执行文件。
●动态二进制插桩[Dynamic Binary Instrumentation(DBI)]:在程序运行时实时地插入额外代码和数据,对可执行文件没有任何永久改变

frida自带的Messages机制与进程交互,模板

import frida, sys

//hook代码,采用javascript编写
jscode = """
//javascript代码,重点
"""
def on_message(message, data):
    if message['type'] == 'send':
        print("[*] {0}".format(message['payload']))
    else:
        print(message)

 
process = frida.get_usb_device().attach('应用完整包名')
script = process.create_script(jscode)
script.on('message', on_message)
script.load()
sys.stdin.read()

Android例子

例子APK 提取码: uba5。

Java层hook

Frida的Java层重要函数
1)使用java平台--->Java.perform(function () {}
2)获取Java类:动态获取JavaScript包装器 --->Java.use(className)
3)当我们获取到Java类之后,我们直通过接 <wrapper>.<method>.implementations = function() {}的方式来hook wrapper类的method方法,不管是实例方法还是静态方法都可以。

因为Frida的hook主要是python框架,但运行的却是js脚本,这里我将其些分开,方便调用。
创建exp.js


console.log("[*]  Java Starting script");
Java.perform(function() {
    var dexclassLoader= Java.use('ese.xposedtest.MainActivity');
    //外部类 的OutClass方法  修改返回值
    dexclassLoader.OutClass.implementation = function () {
        var ret = this.OutClass();
        console.log('Done:' + JSON.stringify(ret));
        return "Frida "+ret;
    }

    //内部类
    var dexclassLoader1= Java.use('ese.xposedtest.MainActivity$inClasse');
    //打印参数 的formInclass方法 参数随意修改了
    dexclassLoader1.formInclass.implementation = function()
    {
        var arg0 = arguments[0];
        var arg1 = arguments[1];
        send("params1: "+arg0+" params2: "+arg1);
        return this.formInclass(1,"Frida");
    }

});

使用模板调用js代码demo.py

import frida, sys
import io
#python2.7

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

def run(pkg):
    jscode  = io.open('hooks.js','r',encoding= 'utf8').read()
    device  = frida.get_usb_device(timeout=5)
    pid     = device.spawn(pkg)
    session = device.attach(pid)
    script = session.create_script(jscode)
    script.on('message', on_message)
    script.load()
    sys.stdin.read()

def main(argv):
    if len(argv) != 2:
        print("must input two arg")
        print("For exanple: python demo.py packName")
    else:
        run(argv[1])

if __name__ == "__main__":
    main(sys.argv)

简单编写一个自动启动Frida_Service的脚本startFridaService.py

# -*- coding: utf-8 -*-
# python2.7
import sys
import subprocess
forward1 = "adb forward tcp:27042 tcp:27042"
forward2 = "adb forward tcp:27043 tcp:27043"

cmd = ["adb shell","su","cd /data/local/tmp","./frida-server64"]

def Forward1():
    s = subprocess.Popen(str(forward1+"\r\n"), stderr=subprocess.PIPE, stdin=subprocess.PIPE,stdout=subprocess.PIPE, shell=True)
    stderrinfo, stdoutinfo = s.communicate()
    return s.returncode

def Forward2():
    s = subprocess.Popen(str(forward2+"\r\n"), stderr=subprocess.PIPE, stdin=subprocess.PIPE,stdout=subprocess.PIPE, shell=True)
    stderrinfo, stdoutinfo = s.communicate()
    return s.returncode

def Run():
    s = subprocess.Popen(str(cmd[0]+"\r\n"), stderr=subprocess.PIPE, stdin=subprocess.PIPE,stdout=subprocess.PIPE, shell=True)
    
    for i in range(1,len(cmd)):
        s.stdin.write(str(cmd[i]+"\r\n"))
        s.stdin.flush() 
     
    stderrinfo, stdoutinfo = s.communicate()
    return s.returncode

if __name__ == "__main__":
    Forward1()
    print("adb forward tcp:27042 tcp:27042")
    Forward2()
    print("adb forward tcp:27043 tcp:27043")
    print("Android server--->./frida-server64")
    print("success-->frida-ps -R")
    Run()

python2.7下运行
1、一个cmd运行
python startFridaService.py
2、一个cmd查看frida服务器是否允许成功
frida-ps -U
3、运行需要hook的app,然后运行frida hook脚本
python demo.py packName

注意:

如果需要hook有3个名为myMethod的方法怎么办?
1 )不需要参数
2 )需要两个字节数组
3 )需要应用程序的上下文和布尔值
我们需要用到 overload

// If two methods of a class have the same name
// you need to use 'overload'

myClass.myMethod.overload().implementation = function(){
  // do sth
}

myClass.myMethod.overload("[B", "[B").implementation = function(param1, param2) {
  // do sth
}

myClass.myMethod.overload("android.context.Context", "boolean").implementation = function(param1, param2){
  // do sth
}

这样我们就可以hook到需要的方法。例如:

image.png

hook导出函数exp.js

console.log("[*]  Java Starting script");
Java.perform(function() {
    //hook 类
    var dexclassLoader = Java.use('com.sitech.appdev.threedes.ThreeDesSecretLib');
    console.log('Done:' + JSON.stringify("dexclassLoader  -----> ok"));

    //hook encrypt 方法 这里多个encrypt方法,选择用overload重载
    dexclassLoader.encrypt.overload('java.lang.String').implementation = function (param1) {
        //进入 encrypt方法 输出传入 参数
        console.log('Done:' + JSON.stringify("encrypt  before------> "+param1));

        //保存第一次传如的参数
        var barparam1 = param1;

        //运行 encrypt方法 得到运行结果 输出结果
        var ret = this.encrypt(param1);
        console.log('Done:' + JSON.stringify("encrypt  after-------> "+ret));

        //最后 继续运行encrypt 方法
        return this.encrypt(barparam1);
    }

});

结果:

hook

so层hook

hook导出函数exp2.js

setImmediate(function() {
    console.log("[*]  Native Starting script");
    var nativePointer = Module.findExportByName("libnative-lib.so","Java_ese_xposedtest_MainActivity_stringFromJNI");
    send("nativePointer--->"+nativePointer);
    Interceptor.attach(nativePointer,{
        onEnter:function(args){
            console.log("ok");
            send("Sart arg-->"+args[0]+"  "+args[1]);
        },
        onLeave:function(retval){
            send("return value:"+retval);
        }
    });
})

技巧

bytes ---> string

function bin2string(array){
        var result = "";
        for(var i = 0; i < array.length; ++i){
            result+= (String.fromCharCode(array[i]));
        }
        return result;
    }

objection
参考: https://bbs.pediy.com/thread-229657.htm
参考: https://blog.csdn.net/jiangwei0910410003/article/details/80372118

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容