亚洲精品亚洲人成在线观看麻豆,在线欧美视频一区,亚洲国产精品一区二区动图,色综合久久丁香婷婷

              當(dāng)前位置:首頁(yè) > IT技術(shù) > 其他 > 正文

              Frida 實(shí)現(xiàn) Hook 功能的強(qiáng)大能力
              2022-05-31 17:12:04

              技術(shù)分享 | Frida 實(shí)現(xiàn) Hook 功能的強(qiáng)大能力

              ??更多技術(shù)文章??

              Frida 通過(guò) C 語(yǔ)言將 QuickJS 注入到目標(biāo)進(jìn)程中,獲取完整的內(nèi)存操作權(quán)限,達(dá)到在程序運(yùn)行時(shí)實(shí)時(shí)地插入額外代碼和數(shù)據(jù)的目的。官方將調(diào)用代碼封裝為 python 庫(kù),當(dāng)然你也可以直接通過(guò)其他的語(yǔ)言調(diào)用 Frida 中的 C 語(yǔ)言代碼進(jìn)行操作。

              Frida安裝和啟動(dòng)

              電腦端 Frida 安裝

              pip install frida-tools
              • 如果在安裝中卡住,需要在 Frida 的 pypi 頁(yè)面下載對(duì)應(yīng)系統(tǒng)的 egg 文件,對(duì)應(yīng)頁(yè)面地址為:https://pypi.org/project/frida/#files ,并將該文件放置到個(gè)人文件夾路徑下,例如 C:Users當(dāng)前用戶名,再重新使用命令安裝。
              • 安裝完畢后可以通過(guò)命令frida --version來(lái)查看安裝的版本,確認(rèn)是否安裝成功。

              手機(jī)端 Frida-server 安裝

              • 本次示例使用 Android App 作為目標(biāo)程序,所以需要電腦端安裝 SDK 環(huán)境,以便能夠連接手機(jī)進(jìn)行調(diào)試操作,還需在手機(jī)端準(zhǔn)備一個(gè) Frida-server,下載地址為:https://github.com/frida/frida/releases,下載匹配手機(jī) CPU 架構(gòu)和本地 Frida 版本的包。
              • 下載之后解壓文件,使用adb push命令將文件推送到手機(jī)端,建議放置在/data/local/tmp文件夾中,并修改該文件的權(quán)限為 755,以便之后進(jìn)行啟動(dòng)。

              確認(rèn)環(huán)境運(yùn)行正常

              • 通過(guò) Frida 提供的一些小工具,對(duì) Frida 的安裝運(yùn)行環(huán)境做簡(jiǎn)單的確認(rèn)。
              • 首先準(zhǔn)備一個(gè) Android 模擬器或者真機(jī),將上一步中提到的 Frida-server 推送到手機(jī)端中,在本示例中將放置在手機(jī)的/data/local/tmp文件夾內(nèi),并將文件命名為frida-server。
              • 通過(guò)adb shell命令連接手機(jī),運(yùn)行/data/local/tmp/frida-server &,將 Frida-server 放在系統(tǒng)后臺(tái)自動(dòng)運(yùn)行。
              • 在本地電腦終端中運(yùn)行frida-ps -U,結(jié)果如下展示手機(jī)中的進(jìn)程信息,說(shuō)明環(huán)境已經(jīng)準(zhǔn)備完畢。
                PID  Name
              ----- --------------------------------------------------
              1313 adbd
              12621 android.process.acore
              18037 android.process.media
              14455 com.android.defcontainer
              11656 com.android.deskclock

              示例

              目標(biāo)應(yīng)用介紹

              • 因?yàn)?Hook 需要通過(guò)分析源碼中的邏輯來(lái)實(shí)現(xiàn),所以先展示一下目標(biāo)應(yīng)用的源碼部分,方便分析其中的邏輯,找到 Hook 時(shí)要修改的方法和變量。
              • 代碼是簡(jiǎn)單的猜黑白游戲,通過(guò)按下黑或白按鈕,與電腦結(jié)果進(jìn)行對(duì)比,結(jié)果相同加 1 分,結(jié)果不同分?jǐn)?shù)清零,當(dāng)滿 100 分時(shí)打出勝利提示語(yǔ)。具體代碼如下:
              package com.example.target_frida;

              import androidx.appcompat.app.AppCompatActivity;

              import android.annotation.SuppressLint;
              import android.os.Bundle;
              import android.view.View;
              import android.widget.Button;
              import android.widget.TextView;

              public class MainActivity extends AppCompatActivity implements View.OnClickListener {
              TextView winCountView;
              TextView battleInfoTextView;
              int winCount = 0;

              @SuppressLint("SetTextI18n")
              @Override
              public void onClick(View view) {
              if (winCount > 100) {
              return;
              }
              if (view.getId() == R.id.tvButtonBlack) {
              if (!getCPUResult()) {
              winCount++;
              winCountView.setText(winCount + "");
              battleInfoTextView.setText("Right!");
              } else {
              winCount = 0;
              winCountView.setText(winCount + "");
              battleInfoTextView.setText("Wrong! Clean All!");
              }
              } else if (view.getId() == R.id.tvButtonWhite) {
              if (getCPUResult()) {
              winCount++;
              winCountView.setText(winCount + "");
              battleInfoTextView.setText("Right!");
              } else {
              winCount = 0;
              winCountView.setText(winCount + "");
              battleInfoTextView.setText("Wrong! Clean All!");
              }
              }
              if (winCount >= 100) {
              battleInfoTextView.setText("Win 100 times!!!");
              }
              }

              @SuppressLint("SetTextI18n")
              @Override
              protected void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
              winCountView = findViewById(R.id.winCount);
              winCountView.setText(winCount + "");
              battleInfoTextView = findViewById(R.id.battleInfo);
              battleInfoTextView.setText("猜黑白!??!");
              Button buttonBlack = (Button) findViewById(R.id.tvButtonBlack);
              Button buttonWhite = (Button) findViewById(R.id.tvButtonWhite);
              buttonBlack.setOnClickListener(this);
              buttonWhite.setOnClickListener(this);
              }

              public boolean getCPUResult() {
              //true為白,false為黑
              return Math.random() > 0.5;
              }

              }

              Hook 需求分析

              • 由于正常情況下,連贏 100 次的概率幾乎為零,如果想要達(dá)到勝利條件,Hook 就是一個(gè)比較好的方式。
              • 首先分析一下源碼,想要達(dá)到連贏 100 次的情況,可以有兩種解決辦法:一種是通過(guò)修改用來(lái)記錄連贏次數(shù)的變量winCount,將連贏記錄改成 99,這樣只需要再贏一次就可以獲得勝利;還有一種是通過(guò)修改getCPUResult方法的返回值,讓其固定返回一種可能性,這樣只需要選擇對(duì)應(yīng)的顏色就可以連續(xù)獲勝。接下來(lái)通過(guò)實(shí)現(xiàn)第一個(gè)方案,看看使用 Frida 如何達(dá)到想要的效果。

              第一種實(shí)現(xiàn):修改結(jié)果變量中保存的值

              • 首先展示修改代碼,然后再進(jìn)行逐步講解:
              import time
              import frida, sys

              date_str = time.strftime('%m-%d %H:%M:%S')


              def on_message(message, data):
              if message['type'] == 'send':
              print(f"[{date_str}] {message['payload']}")
              else:
              print(f"[{date_str}] {message}")


              def run_all():
              # Java.perform方法:當(dāng) js 附加到目標(biāo)的進(jìn)程中時(shí)被執(zhí)行,運(yùn)行其中定義的函數(shù)
              # Java.choose方法:通過(guò)完整類名,獲取它的實(shí)例,從而對(duì)實(shí)例中的數(shù)據(jù)進(jìn)行修改
              # 通過(guò) key:value 結(jié)構(gòu)定義了兩個(gè)函數(shù):
              # onMatch 對(duì)應(yīng)的函數(shù)在命中一個(gè)實(shí)例的時(shí)候被調(diào)用,傳入函數(shù)中的參數(shù) instance 就是被命中的實(shí)例
              # onComplete 函數(shù)會(huì)在所有實(shí)例遍歷完畢之后被調(diào)用,可以做一些后續(xù)處理操作
              jscode = """
              Java.perform(function () {
              Java.choose("com.example.target_frida.MainActivity",{
              onMatch:function(instance){
              console.log("winCount value is "+instance.winCount.value);
              instance.winCount.value=99;
              console.log("winCount value is "+instance.winCount.value);
              },
              onComplete:function(){
              console.log("Complete!!!")
              }
              });
              });
              """
              # attach目標(biāo)App進(jìn)程
              target_app = 'com.example.target_frida'
              process = frida.get_usb_device().attach(target_app)
              # 將JS代碼注入進(jìn)程,并附加監(jiān)聽(tīng)方法,用來(lái)獲取返回的日志信息
              script = process.create_script(jscode)
              script.on('message', on_message)
              # 打印起始日志
              print(f'[{date_str}] Start Frida on {target_app}')
              # 加載注入的JS代碼邏輯
              script.load()
              # 使用系統(tǒng)輸入語(yǔ)句阻止函數(shù)運(yùn)行完畢自動(dòng)退出
              sys.stdin.read()


              if __name__ == '__main__':
              run_all()
              • 代碼中的 python 語(yǔ)句已經(jīng)添加了注釋,Hook 的核心邏輯,JS 語(yǔ)句作為字符串保存在 jscode 變量中。
              • 梳理一下整個(gè) JS 語(yǔ)句的流程:通過(guò)Java.choose函數(shù)獲取com.example.target_frida.MainActivity類的實(shí)例。在獲取到實(shí)例時(shí),首先使用console.log語(yǔ)句將當(dāng)前實(shí)例中的 winCount 變量值(使用 winCount.value)打印到日志中,之后直接通過(guò)賦值語(yǔ)句把變量值改為 99,再次輸出日志確認(rèn)修改無(wú)誤,修改邏輯就完成了。
              • 在手機(jī)端啟動(dòng) Frida-server 和被測(cè) App,電腦端運(yùn)行腳本,可以看到在命令行中輸出如下內(nèi)容:
              [04-15 18:19:57] Start Frida on com.example.target_frida
              winCount value is 0
              winCount value is 99
              Complete!!!

              這時(shí)在 App 中選擇一個(gè)顏色點(diǎn)擊,只要選中正確的顏色,就可以成功達(dá)到預(yù)期的 100 次連勝目標(biāo),如果沒(méi)能選中正確的顏色導(dǎo)致清零,可以再重復(fù)運(yùn)行腳本修改一次數(shù)值,在這種情況下要達(dá)到預(yù)期的場(chǎng)景就很容易。

              總結(jié)

              第二個(gè)方案以及其他更多的可能性,就留給讀者自行探索,在這里送上 Frida 官方 JavaScript API 鏈接:https://frida.re/docs/javascript-api/ ,可以通過(guò)這個(gè)鏈接找到你所需要的 JS 函數(shù)。
              通過(guò)示例可以看到 Frida 實(shí)現(xiàn) Hook 功能的強(qiáng)大能力,它可以定位到類的實(shí)例,并且對(duì)實(shí)例中的數(shù)據(jù)進(jìn)行直接的修改,達(dá)到場(chǎng)景構(gòu)建的目的。
              ???更多技術(shù)文章??

              本文摘自 :https://blog.51cto.com/u

              開(kāi)通會(huì)員,享受整站包年服務(wù)立即開(kāi)通 >