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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 118,716评论 1 241
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 51,755评论 1 200
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 73,983评论 0 167
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 36,280评论 0 127
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 43,096评论 1 206
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 35,774评论 1 125
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 27,750评论 2 207
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 26,881评论 0 119
  • 想象着我的养父在大火中拼命挣扎,窒息,最后皮肤化为焦炭。我心中就已经是抑制不住地欢快,这就叫做以其人之道,还治其人...
    爱写小说的胖达阅读 25,847评论 5 172
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 29,937评论 0 178
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 27,142评论 1 168
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 28,402评论 1 178
  • 白月光回国,霸总把我这个替身辞退。还一脸阴沉的警告我。[不要出现在思思面前, 不然我有一百种方法让你生不如死。]我...
    爱写小说的胖达阅读 22,706评论 0 25
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 25,320评论 2 164
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 29,167评论 3 172
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 24,161评论 0 4
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 24,200评论 0 113
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 30,371评论 2 189
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 30,793评论 2 188