日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Frida之安装和使用教程

發(fā)布時間:2024/4/11 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Frida之安装和使用教程 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

在日常分析安卓應(yīng)用時,通常會有對應(yīng)用進(jìn)行hook的需求,用的比較多的hook框架有Xposed,frida,xhook等,正好最近接觸Frida接觸的較多,所以對Frida的一些常用操作做個記錄,方便以后翻閱查詢,同時也可以對學(xué)習(xí)frida的小伙伴有個參考的資料;

一般Frida逆向三階段:

  • 階段一.分析程序執(zhí)行邏輯,函數(shù)參數(shù),函數(shù)返回值
  • 階段二.在1的基礎(chǔ)上對數(shù)據(jù)進(jìn)行修改,執(zhí)行流程的控制,核心方法的調(diào)用
  • 階段三.在2的基礎(chǔ)上實(shí)現(xiàn)對核心方法的封裝調(diào)用,提供對外服務(wù)接口
  • 1.FRIDA安裝

    1.1.安裝python3環(huán)境

    https://www.python.org/ 下載最新的直接安裝

    1.2.frida安裝

    C:\Users\Administrator>pip install frida-tools Collecting frida-tools /...省略.../Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.Running setup.py install for frida-tools ... done Successfully installed colorama-0.4.0 frida-12.2.25 frida-tools-1.2.2 prompt-toolkit-1.0.15 pygments-2.2.0 six-1.11.0 wcwidth-0.1.7

    1.3.frida-server下載

    frida-server下載需要注意的有兩點(diǎn):
    1.安裝的frida版本:需要下載與安裝的frida版本對應(yīng)的frida-server,否則會出錯。

    C:\Users\Administrator>frida --version 12.2.25

    下載地址:https://github.com/frida/frida/releases

    2.手機(jī)設(shè)備的架構(gòu):因?yàn)槲业氖謾C(jī)是arm64平臺的所以選擇的是android-arm64

    frida-server-12.2.25-android-arm64.xz

    下載完畢之后,解壓后通過adb push到設(shè)備的臨時目錄下

    adb push frida-server-12.2.25-android-arm64 /data/local/tmp/

    1.4.啟動frida服務(wù)并連接

    adb shell進(jìn)入設(shè)備shell環(huán)境,cd到臨時目錄下,給frida-server文件設(shè)置可執(zhí)行權(quán)限使其可以運(yùn)行

    chmod 755 frida-server-12.2.25-android-arm64

    之后運(yùn)行frida服務(wù)文件,注意需要通過root權(quán)限去運(yùn)行

    ./frida-server-12.2.25-android-arm64

    然后 進(jìn)行端口轉(zhuǎn)發(fā)

    adb forward tcp:27042 tcp:27042 adb forward tcp:27043 tcp:27043

    完畢后就可以在windows上運(yùn)行簡單的frida命令測試我們是否安裝成功了

    /* -U 連接USB設(shè)備 */ /* frida-ps 列出正在運(yùn)行的進(jìn)程*/ C:\Users\Administrator>frida-ps -U PID Name ---- -------------------------------- 310 1:3 714 360sguard 723 360sguard 373 ATFWD-daemon 575 adbd 259 adsprpcd [....] 3289 zygote

    1.5.搭建frida開發(fā)環(huán)境

    $ git clone git://github.com/oleavr/frida-agent-example.git $ cd frida-agent-example/ $ npm install $ frida -U -f com.example.android --no-pause -l _agent.js

    2.FRIDA 基礎(chǔ)

    首先來看一下frida的常用功能

    2.1.frida查看當(dāng)前設(shè)備進(jìn)程

    λ frida-ps -UPID Name ----- ------------------------------------------------------- 6241 adbd 897 adsprpcd 749 android.hardware.audio@2.0-service 947 android.hardware.biometrics.fingerprint@2.1-service.fpc 750 android.hardware.bluetooth@1.0-service-qti 600 android.hardware.boot@1.0-service 752 android.hardware.camera.provider@2.4-service 753 android.hardware.cas@1.0-service 612 android.hardware.configstore@1.1-service [...]

    2.2.frida對指定方法進(jìn)行trace

    λ frida-ps -U | grep frida 31521 cn.gemini.k.fridatest 30073 frida-helper-32 λ frida-trace -i "open" -U "cn.gemini.k.fridatest" Instrumenting... open: Auto-generated handler at "E:\\Frida\\frida_work\\__handlers__\\libutils.so\\open.js" Started tracing 1 function. Press Ctrl+C to stop. /* TID 0x7b3a */ 16061 ms open()/* TID 0x7b3c */ 16114 ms open() 16114 ms open() 16114 ms open()

    用的比較多的一般就是上面的兩個功能,都是frida幫我們生成好了hook代碼,直接拿來使用就行,簡單方便,但有時候我們想自己定制些功能怎么辦?

    接下來看下如何通過編寫js代碼來實(shí)現(xiàn)對安卓APP中某些方法的hook。
    在hook之前首先要熟悉我們需要hook的目標(biāo)方法,應(yīng)用包名,參數(shù)等基礎(chǔ)信息。這里簡單寫了個demo,后面我們都通過這個demo來學(xué)習(xí)。

    package cn.gemini.k.fridatest; import android.util.Log;public class FridaHook1 {static String password = "88888888";int cde = 20;int abc = 10;public int abc(){return abc;}FridaHook1(){Log.e("FridaHook1","一般方法 ret:"+func1_add(cde,abc)); // 一般方法Log.e("FridaHook1","重載方法 ret:"+func2_add_overload(1,2)); // 重載方法Log.e("FridaHook1","重載方法 ret:"+func2_add_overload(1,2,3)); // 重載方法Log.e("FridaHook1","靜態(tài)方法 ret:"+func3_verify_static("12345678")); // 靜態(tài)方法new inner_class().inner_class_func("內(nèi)部類調(diào)用"); // 內(nèi)部類Log.e("匿名類方法 FridaHook1","ret:"+new anonymous_class(){ //匿名類public String output(){return "匿名類調(diào)用";}}.output());}public int func1_add(int a,int b){Log.e("func1_add","arg1:"+a+" arg2:"+b);return a+b;}public int func2_add_overload(int a,int b){Log.e("func2_add_overload","arg1:"+a+" arg2:"+b);return a+b;}public int func2_add_overload(int a,int b,int c){Log.e("func2_add_overload","arg1:"+a+" arg2:"+b+" arg3:"+c);return a+b+c;}public static int func3_verify_static(String str){Log.e("func3_verify_static",str);if(str.equals(password)){Log.e("func3_verify_static","密碼正確");return 1;}Log.e("func3_verify_static","密碼錯誤");return 0;}static class inner_class{inner_class(){}public void inner_class_func(String str){Log.e("inner_class_func",str);}}class anonymous_class{ } }

    整理一下hook時需要的信息:
    目標(biāo)應(yīng)用的包名:“cn.gemini.k.fridatest”(一般在AndroidManifest.xml文件中可以找到)
    目標(biāo)方法所在類的類名:“cn.gemini.k.fridatest.FridaHook1”;
    最后是目標(biāo)方法名和參數(shù):public int func1_add(int a,int b)
    沒有源碼的情況下這些信息都可以通過反編譯工具jadx或jeb獲取。
    接下來開始編寫hook代碼

    2.3.frida hook代碼的兩種形式

    2.3.1.代碼內(nèi)置在python文件中

    load.py代碼如下:

    # -*- coding: UTF-8 -*- import frida,sysjs_code = '''Java.perform(function(){console.log("Frida Test");var cls = Java.use("cn.gemini.k.fridatest.FridaHook1");cls.func1_add.implementation = function(arg1,arg2){console.log("hook arg1:",arg1," hook arg2:",arg2);return this.func1_add(arg1,arg2);}}); '''# 目標(biāo)包名 appPacknName = "cn.gemini.k.fridatest" scriptFile = "hook_script.js"# 輸出日志的回調(diào)方法 def on_message(message, data):if message['type'] == 'send':print("[*] {0}".format(message['payload']))else:print(message)device = frida.get_usb_device() # spawn模式,找到目標(biāo)包名并重啟,在啟動前注入腳本 pid = device.spawn([appPacknName]) session = device.attach(pid) # 注意這里需要將device.attach(pid)這句代碼寫在前面,這樣執(zhí)行才符合預(yù)期(啟動時程序白屏,等待下面這行代碼來恢復(fù)執(zhí)行) # 其實(shí)在https://www.jianshu.com/p/b833fba1bffe這篇文章中有提到 device.resume(pid)# 方式一: 通過js文件創(chuàng)建hook代碼 #with open(scriptFile, encoding='UTF-8') as f : # script = session.create_script(f.read()) # 方式二: 直接將hook代碼寫在python文件中 script = session.create_script(js_code)script.on('message', on_message) script.load() #把js代碼注入到目標(biāo)應(yīng)用中 # 避免結(jié)束 sys.stdin.read()

    解釋下上面的python代碼,先通過frida.get_usb_device連接到usb設(shè)備,接著使用spawn將目標(biāo)應(yīng)用重啟并掛起,之后再通過attach附加到目標(biāo)應(yīng)用,完成附加后開始喚起應(yīng)用主線程,最后是構(gòu)造需要注入的js代碼,通過session.create_script生成js腳本,script.on用來注冊一個回調(diào)方法監(jiān)聽目標(biāo)進(jìn)程的所有消息,script.load會把前面生成的js代碼注入到目標(biāo)應(yīng)用中完成hook。這里hook代碼只是簡單的將函數(shù)的參數(shù)給輸出了下。

    運(yùn)行結(jié)果如下:

    // frida打印日志 λ python load.py Frida Test hook arg1: 1 hook arg2: 2// APP程序執(zhí)行打印日志 19493-19493/cn.gemini.k.fridatest E/func1_add: arg1:1 arg2:2 19493-19493/cn.gemini.k.fridatest E/FridaHook1: 一般方法 ret:3

    2.3.2.代碼封裝成js文件

    hook_script.js代碼如下

    function main(){Java.perform(function(){console.log("Frida Test");var cls = Java.use("cn.gemini.k.fridatest.FridaHook1");cls.func1_add.implementation = function(arg1,arg2){console.log("hook arg1:",arg1," hook arg2:",arg2);return this.func1_add(arg1,arg2);}}); } setImmediate(main)

    load2.py代碼如下

    # -*- coding: UTF-8 -*- import frida,sys# 目標(biāo)包名 appPacknName = "cn.gemini.k.fridatest" scriptFile = "hook_script.js"# 輸出日志的回調(diào)方法 def on_message(message, data):if message['type'] == 'send':print("[*] {0}".format(message['payload']))else:print(message)device = frida.get_usb_device() # spawn模式,找到目標(biāo)包名并重啟,在啟動前注入腳本 pid = device.spawn([appPacknName]) session = device.attach(pid) # 注意這里需要將device.attach(pid)這句代碼寫在前面,這樣執(zhí)行才符合預(yù)期(啟動時程序白屏,等待下面這行代碼來恢復(fù)執(zhí)行) # 其實(shí)在https://www.jianshu.com/p/b833fba1bffe這篇文章中有提到 device.resume(pid)# 方式一: 通過js文件創(chuàng)建hook代碼 with open(scriptFile, encoding='UTF-8') as f :script = session.create_script(f.read()) # 方式二: 直接將hook代碼寫在python文件中 # script = session.create_script(js_code)script.on("message", on_message) script.load() #把js代碼注入到目標(biāo)應(yīng)用中 # 避免結(jié)束 sys.stdin.read()

    運(yùn)行結(jié)果如下:

    // frida打印日志 λ python load2.py Frida Test hook arg1: 1 hook arg2: 2// APP程序執(zhí)行打印日志 19493-19493/cn.gemini.k.fridatest E/func1_add: arg1:1 arg2:2 19493-19493/cn.gemini.k.fridatest E/FridaHook1: 一般方法 ret:3

    上面這種方式主要是將js代碼封裝成了一個單獨(dú)的js文件,不再是之前放在python文件中的形式,封裝成一個js文件可以方便我們對代碼進(jìn)行模塊化管理。同時這樣做還有一個好處就是可以在命令行直接使用frida注入工具來注入js代碼到指定進(jìn)程,省去了用python寫load的步驟。

    λfrida -U -n "cn.gemini.k.fridatest" -l hook_script.js____/ _ | Frida 14.2.2 - A world-class dynamic instrumentation toolkit| (_| |> _ | Commands:/_/ |_| help -> Displays the help system. . . . object? -> Display information about 'object'. . . . exit/quit -> Exit. . . .. . . . More info at https://www.frida.re/docs/home/ Attaching... Frida Test Hook [AOSP on walleye::cn.gemini.k.fridatest]->

    2.4.frida的兩種注入模式

    最后簡單了解下frida的兩種注入模式:
    第一種:直接通過attach方法對已啟動的目標(biāo)應(yīng)用進(jìn)行注入,這種一般用在hook時機(jī)比較晚的場景。
    第二種:先使用spawn方法以掛起模式重新啟動目標(biāo)應(yīng)用后再通過attach方法進(jìn)行注入,一般用在hook時機(jī)比較早的場景。
    暫時先大概有所了解,后面會將具體的使用場景。

    3.FRIDA HOOK

    3.1.hook普通方法、參數(shù)/返回值修改

    還是上面的hook demo那個例子,我們這次對傳入的參數(shù)以及返回值嘗試修改。
    修改js文件中的代碼

    function Hook1(){Java.perform(function(){console.log("Frida Test Hook1");var cls = Java.use("cn.gemini.k.fridatest.FridaHook1");cls.func1_add.implementation = function(arg1,arg2){console.log("func1_add --> hook arg1:",arg1," hook arg2:",arg2); // 輸出原始參數(shù)arg1 = arg1 + 1; // 修改參數(shù)值加1arg2 = arg2 + 1; // 修改參數(shù)值加1var ret = this.func1_add(arg1,arg2); // 將修改后的參數(shù)傳入給原始方法return ret + 3; // 將方法的返回值加3,并返回給調(diào)用方法}}); }

    上面的js代碼就是我們hook要實(shí)現(xiàn)的功能,Java.use方法通過類名獲取類的類型并返回一個相同類型的對象cls,之后通過cls對象對普通方法func1_add進(jìn)行hook,成功后當(dāng)func1_add方法被別的方法調(diào)用時就會走到我們設(shè)置的hook方法。
    我們的hook方法會將傳入的兩個參數(shù)都分別加1,被hook方法的參數(shù)獲取可以通過在hook方法中定義形參獲取也可通過在hook方法內(nèi)部利用arguments[*]數(shù)組獲取。修改完參數(shù)后再傳遞給原始方法進(jìn)行計算,原始方法將返回值返回給hook方法后我們再將返回值加3,最后返回給應(yīng)用的調(diào)用方法。
    運(yùn)行結(jié)果如下:

    λ python load2.py Frida Test Hook1 func1_add --> hook arg1: 1 hook arg2: 2// APP程序執(zhí)行打印日志 6374-6374/cn.gemini.k.fridatest E/func1_add: arg1:2 arg2:3 6374-6374/cn.gemini.k.fridatest E/FridaHook1: 一般方法 ret:8

    從上面的結(jié)果可以看到,不管是傳入的參數(shù),還是最后的返回值都被我們修改掉了。

    3.2.hook重載方法/所有重載方法

    如果需要hook的方法存在重載方法,那么就需要使用overload關(guān)鍵字來指明參數(shù)類型,否則frida會報錯。
    js代碼:

    function Hook2(){Java.perform(function(){console.log("Frida Test Hook2");var cls = Java.use("cn.gemini.k.fridatest.FridaHook1");// 重載方法hookcls.func2_add_overload.overload('int', 'int').implementation = function(arg1,arg2){console.log("func2_add_overload --> hook arg1:",arg1," hook arg2:",arg2);arg1 = arg1 + 1;arg2 = arg2 + 1;var ret = this.func2_add_overload(arg1,arg2);return ret + 3;}cls.func2_add_overload.overload('int', 'int', 'int').implementation = function(arg1,arg2,arg3){console.log("func2_add_overload --> hook arg1:",arg1," hook arg2:",arg2," hook arg3:",arg3);arg1 = arg1 + 1;arg2 = arg2 + 1;arg3 = arg3 + 1;var ret = this.func2_add_overload(arg1,arg2,arg3);return ret + 3;}}); }

    執(zhí)行結(jié)果

    λ python load2.py// APP程序執(zhí)行打印日志 6374-6374/cn.gemini.k.fridatest E/func2_add_overload: arg1:1 arg2:2 6374-6374/cn.gemini.k.fridatest E/FridaHook1: 重載方法 ret:6 6374-6374/cn.gemini.k.fridatest E/func2_add_overload: arg1:1 arg2:2 arg3:3 6374-6374/cn.gemini.k.fridatest E/FridaHook1: 重載方法 ret:9

    如果重載方法比較少上面的方法還行,但是如果重載方法較多的話一個個去寫重載就比較無趣了,frida還給我們提供了一種hook所有重載方法的方法。
    js代碼

    console.log(cls.func2_add_overload.overloads.length); for(var i = 0; i < cls.func2_add_overload.overloads.length; i++){cls.func2_add_overload.overloads[i].implementation = function(){if(arguments.length == 2){var arg1 = arguments[0] + 1;var arg2 = arguments[1] + 1;console.log("func2_add_overload --> hook arg1:",arg1," hook arg2:",arg2);return this.func2_add_overload.apply(this,arguments) + 3;}else if(arguments.length == 3){var arg1 = arguments[0] + 1;var arg2 = arguments[1] + 1;var arg3 = arguments[2] + 1;console.log("func2_add_overload --> hook arg1:",arg1," hook arg2:",arg2," hook arg3:",arg3);return this.func2_add_overload.apply(this,arguments) + 3;}} }

    3.3.hook構(gòu)造方法

    如果我們想hook一個類的構(gòu)造方法,那么使用固定的$init代替構(gòu)造方法名:

    function Hook3(){Java.perform(function(){console.log("Frida Test Hook3");var cls = Java.use("cn.gemini.k.fridatest.FridaHook1");cls.$init.implementation = function(){console.log("$init --> hook");//this.$init();}}); }

    執(zhí)行結(jié)果

    λ python load2.py Frida Test Hook3 $init --> hook// APP程序執(zhí)行打印日志 因?yàn)閔ook方法只輸出了"$init --> hook"并沒有調(diào)用原始構(gòu)造方法,所以程序并沒有輸出。

    3.4.hook靜態(tài)方法

    靜態(tài)方法的hook實(shí)際上和一般方法的hook類似。

    function Hook4(){Java.perform(function(){console.log("Frida Test Hook4");var cls = Java.use("cn.gemini.k.fridatest.FridaHook1");cls.func3_verify_static.implementation = function(arg1){console.log("func3_verify_static --> hook arg1:",arg1);return this.func3_verify_static(arg1);}}); }

    執(zhí)行結(jié)果

    λ python load2.py Frida Test Hook4 func3_verify_static --> hook arg1: 12345678// APP程序執(zhí)行打印日志 6374-6374/cn.gemini.k.fridatest E/func3_verify_static: 12345678 6374-6374/cn.gemini.k.fridatest E/func3_verify_static: 密碼錯誤 6374-6374/cn.gemini.k.fridatest E/FridaHook1: 靜態(tài)方法 ret:0

    3.5.hook內(nèi)部類方法/匿名類方法

    對于內(nèi)部類或匿名類方法的hook需要通過$+名字的方式來使用。

    function Hook5(){Java.perform(function(){console.log("Frida Test Hook5");// hook內(nèi)部類方法var innercls = Java.use("cn.gemini.k.fridatest.FridaHook1$inner_class");innercls.inner_class_func.implementation = function(arg1){console.log("inner_class_func arg1:",arg1);return this.inner_class_func(arg1);}// hook匿名類方法var innercls = Java.use("cn.gemini.k.fridatest.FridaHook1$1"); // 匿名類的類名一般使用反編譯軟件獲取innercls.output.implementation = function(){console.log("output 匿名類方法調(diào)用");return this.output();}}); }

    執(zhí)行結(jié)果

    λ python load2.py Frida Test Hook5 inner_class_func arg1: 內(nèi)部類調(diào)用 output 匿名類方法調(diào)用// APP程序執(zhí)行打印日志 6374-6374/cn.gemini.k.fridatest E/inner_class_func: 內(nèi)部類調(diào)用 6374-6374/cn.gemini.k.fridatest E/匿名類方法 FridaHook1: ret:匿名類調(diào)用

    3.6.枚舉所有類與類的所有方法

    Java.enumerateLoadedClasses(callbacks):無返回值,參數(shù)是一個回調(diào)方法,功能是列出當(dāng)前已經(jīng)加載的類,用回調(diào)方法處理。
    回調(diào)方法:
    onMath:function(name){}
    找到加載的每個類的時候被調(diào)用,參數(shù)就是類的名字,可以將name傳入Java.use()來獲得一個js類,還可以通過name對枚舉的類進(jìn)行過濾
    onComplete:function(){}
    枚舉完所有類之后被調(diào)用,用來做一些完成后的收尾工作

    Java.enumerateLoadedClassesSync():無參數(shù),方法返回所有已經(jīng)加載的類的數(shù)組。

    function Hook6(){Java.perform(function(){console.log("Frida Test Hook6");// 枚舉所有類console.log("枚舉所有類");Java.enumerateLoadedClasses({onMatch: function(name){console.log(name);// 這里可以添加過濾邏輯用來過濾我們關(guān)注的類//if(name.indexOf("cn.gemini.k.fridatest") != -1){// console.log(name);//}},onComplete: function(){}});// 打印類中的所有方法console.log("打印類中的所有方法");var clszz = Java.use("cn.gemini.k.fridatest.FridaHook1");var methods = clszz.class.getDeclaredMethods(); // 獲取類中的所有方法可使用反射獲得console.log(methods);}); }

    運(yùn)行結(jié)果

    λ python load2.py Frida Test Hook6 枚舉所有類 [.....] // 一大堆的系統(tǒng)類,可以添加過濾邏輯過濾一下 [Landroid.content.pm.ProviderInfo; androidx.core.app.CoreComponentFactory$CompatWrapped androidx.core.app.CoreComponentFactory 打印類中的所有方法 public static int cn.gemini.k.fridatest.FridaHook1.func3_verify_static(java.lang.String),public int cn.gemini.k.fridatest.FridaHook1.abc(),public int cn.gemini.k.fridatest.FridaHook1.func1_add(int,int),public int cn.gemini.k.fridatest.FridaHook1.func2_add_overload(int,int),public int cn.gemini.k.fridatest.FridaHook1.func2_add_overload(int,int,int)

    3.7.hook類中所有成員方法

    如果類中有靜態(tài)方法,又有重載方法的話下面代碼會報錯,沒有靜態(tài)方法則可以hook類中的成員方法。

    function Hook7(){Java.perform(function(){console.log("Frida Test Hook7");var clszz = Java.use("cn.gemini.k.fridatest.FridaHook1");// 先枚舉類的所有方法var methods = clszz.class.getDeclaredMethods();for(var i = 0; i < methods.length; i++){var methodName = methods[i].getName(); // 獲取到每個方法的名字console.log(methodName);console.log(clszz[methodName].overloads.length);// 重載方法的處理for(var j = 0; j < clszz[methodName].overloads.length; j++){clszz[methodName].overloads[j].implementation = function(){for(var k = 0;k < arguments.length; k++){console.log(this + " arg"+ k + ":" + arguments[k]);}return this[methodName].apply(this, arguments);}}}}); }

    3.8.實(shí)例化類對象/修改類字段

    一個類的字段包括靜態(tài)字段和非靜態(tài)字段。
    靜態(tài)字段的訪問可以直接通過 類.字段名.value = “XXX” 的方式進(jìn)行修改。

    非靜態(tài)字段則需要先拿到對象實(shí)例才能修改,獲取對象實(shí)例可使用Java.choose()。同時還需要注意非靜態(tài)字段又分為有同名方法的字段和無同名方法的字段。

    • 對于有同名方法的字段,在訪問時需要在字段名前面加一個下劃線"_"才能訪問。
    • 對于無同名方法的字段,則直接可以訪問。
      對象實(shí)例化則通過$new方法即可創(chuàng)建一個新的對象。
      js代碼
    function Hook8(){Java.perform(function(){console.log("Frida Test Hook8");var clazz = Java.use("cn.gemini.k.fridatest.FridaHook1");// 修改類中的靜態(tài)字段console.log("修改前靜態(tài)字段的值:" + clazz.password.value);clazz.password.value = "9"; // 靜態(tài)字段的修改console.log("修改后靜態(tài)字段的值:" + clazz.password.value);// 實(shí)例化類對象var newcls = clazz.$new(); // 通過$new方法對類進(jìn)行實(shí)例化console.log("實(shí)例化一個類對象"+newcls)console.log("修改前的字段值: abc=="+newcls._abc.value+" cde=="+newcls.cde.value);// 修改類中的非靜態(tài)字段Java.choose("cn.gemini.k.fridatest.FridaHook1",{onMatch: function(obj){obj.cde.value = 100; // 非靜態(tài)字段修改方式obj._abc.value = 200; // 非靜態(tài)字段修改:這里需要注意因?yàn)轭愔写嬖谝粋€同名的方法,所以訪問該字段時需要加個下劃線"_"console.log("修改后的字段值: abc=="+obj._abc.value+" cde=="+obj.cde.value);},onComplete: function(){}});}); }

    執(zhí)行結(jié)果

    λ python load2.py Frida Test Hook8 修改前靜態(tài)字段的值:88888888 修改后靜態(tài)字段的值:9 實(shí)例化一個類對象cn.gemini.k.fridatest.FridaHook1@a675c28 修改前的字段值: abc==10 cde==20 修改后的字段值: abc==200 cde==100

    3.9.frida方法主動調(diào)用

    frida的方法主動調(diào)用,主要分以下幾種情況
    1.frida主動調(diào)用Java類中的靜態(tài)方法,也就是使用static關(guān)鍵字聲明的。
    2.frida主動調(diào)用對象的Java成員方法,通過對象才能調(diào)用的方法,非static方法。

    • 方法一:創(chuàng)建一個新對象完成主動調(diào)用
    • 方法二:搜索內(nèi)存中已有對象完成主動調(diào)用(推薦使用內(nèi)存中原有的對象,因?yàn)閮?nèi)存中的對象才是應(yīng)用真實(shí)的應(yīng)用使用的對象,自己創(chuàng)建對象的數(shù)據(jù)可能與應(yīng)用當(dāng)時實(shí)際使用的數(shù)據(jù)不一致,一般協(xié)議分析會存在上面的情況(那么問題來了,如果內(nèi)存中有多個對象該如何區(qū)分哪個是我們要的對象呢?),如果只是單純使用對象方法的功能那么一般問題不大)

    3.frida主動調(diào)用so中的方法。
    對so方法的直接調(diào)用需要用到frida的NativeFunction方法,方法原型如下:
    NativeFunction(address, returnType, argTypes[, abi])
    1)address:要hook的方法地址
    2)returnType:返回值類型
    3)argTypes[, abi]: 參數(shù)類型 這里參數(shù)可以是多個
    js代碼

    function Hook9(){Java.perform(function(){console.log("Frida Test Hook9");// 主動調(diào)用類靜態(tài)方法var clszz = Java.use("cn.gemini.k.fridatest.FridaHook1");clszz.func3_verify_static(">>>pwd<<<");// 主動調(diào)用類成員方法// 第一種方式:創(chuàng)建一個新對象完成主動調(diào)用var obj = clszz.$new();var ret = obj.func2_add_overload(11,22);console.log("返回值: " + ret);// 第二種方式:搜索內(nèi)存中已有對象完成主動調(diào)用Java.choose("cn.gemini.k.fridatest.FridaHook1",{onMatch: function(instance){console.log("found instance :"+ instance);console.log("返回值: "+ instance.func2_add_overload(33,44));},onComplete: function(){console.log("Search Completed!");}})// 主動調(diào)用so的native方法var str_name_so = "libnative-lib.so"; //要hook的so名var str_name_func = "JNI_Frida_Test"; //要hook的方法名// 獲取方法地址var addr_func = Module.findExportByName(str_name_so , str_name_func);console.log("func addr is ---" + addr_func);//定義NativeFunction 等下要調(diào)用var func_JNI_Frida_Test = new NativeFunction(addr_func,"void",[]);func_JNI_Frida_Test();}); }

    文章轉(zhuǎn)載于: https://blog.csdn.net/weixin_46734340/article/details/117401345

    總結(jié)

    以上是生活随笔為你收集整理的Frida之安装和使用教程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。