官宣| 反手就送你們一個hook神器

上期的Android逆向之動態分析so篇大家學習的如何啦?本期鬥哥將帶來Android逆向之動態分析Frida篇。主要內容有Frida環境搭建與Frida在Android環境下的運行與使用。

0X01 Frida框架安裝詳解

1.簡述:

Frida是以Python爲載體,注入Javascript作爲Android中執行代碼的一款Hook框架,可用Android、ios、linux、win等平臺。

2.安裝客戶端:

在已有python和pip環境的系統下安裝frida,如windows則使用pip install frida-tools命令安裝frida包。

使用frida命令查看版本(成功查看到frida版本表示安裝成功)。

2. 安裝服務端:

首先到github上下載frida-server,網址爲https://github.com/frida/frida/releases 下載與客戶端相同版相同的frida-server(注意位數)。 在客戶端(windows)上使用adb push命令將frida-servser傳到Android設備目錄中。

修改frida-servser權限,讓frida-servse擁有可執行權限。

運行frida服務器。

在客戶端開啓端口轉發。 adb forward tcp:27042 tcp:27042 adb forward tcp:27043 tcp:27043

使用frida-ps -U或者frida-ps -R命令查看手機端進程(成功查看到進程表示Frida環境搭建成功)。

0X02 Frida框架的初步使用

將frida服務器運行起來後,客戶端就可以利用frida API對Android設備中的進程以及APP應用進行操作。

例一:

使用Frida獲取android手機當前最前端Activity所在的進程。

import frida
rdev = frida.get_usb_device()
front_app = rdev.get_frontmost_application()
print(front_app)

例二:

查看手機所有已安裝的android APP應用。

import frida
rdev = frida.get_usb_device()
apps = rdev.enumerate_applications()
for app in apps:
    print(app)

例三:

frida自帶的Messages機制與進程交互模板。

import frida, sys


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


jscode = """
//分析hook點,編寫javascript代碼
//javascript代碼,重點
"""

process = frida.get_usb_device().attach('ds.tetris.android')
script = process.create_script(jscode)
script.on('message', on_message)
script.load()
sys.stdin.read()

0X03 Frida框架解題技巧

Frida可以用來解決CTF中移動安全題,如Frida官網的一個APP例子,就是一道CTF題。以如下的CTF題爲例,通過解題過程深入瞭解Frida的使用。

1. 題目描述:

尋一名可以拿到20000分的高手,在線等很急!

2. 尋找hook點:

MainActivity部分代碼如下: 靜態分析得到getScore()方法是記錄分數的關鍵。

public final void invoke(@NotNull Score arg6) {
    Intrinsics.checkParameterIsNotNull(arg6, "$receiver");
    if(arg6.getScore() > 20000) {
        Game.access$getView$p(Game.this).setScore(0xFFFFFFFF);
    }
    else {
        Game.access$getView$p(Game.this).setScore(arg6.getScore());
    }

    if(Game.access$getView$p(Game.this).getLevel() < arg6.getLevel() && Game.access$getView$p(Game.this).getLevel() != 0 && (Game.this.getSoundEnabled())) {
        DefaultImpls.play$default(Game.access$getSoundtrack$p(Game.this), Sound.LEVEL_UP, 0, 2, null);
    }

    Game.access$getView$p(Game.this).setLevel(arg6.getLevel());
}

Hook點:setScore方法值置爲-1,程序將就會自動爲我們解密flag。

public void setScore(int arg4) {
    if(arg4 == -1) {
        UtilsKt.errorhandler(this);
    }

    this.score = arg4;
    View v0 = this._$_findCachedViewById(id.scoreLabel);
    Intrinsics.checkExpressionValueIsNotNull(v0, "scoreLabel");
    ((TextView)v0).setText("Score: " + arg4);
}

3. 解題過程:

(請先閱讀Android逆向之靜態分析文章) 靜態分析完應用邏輯後可知只要將 MainActivity 中的 setScore方法參數值設爲-1,程序就會自動爲我們解密flag,所以可以通過Frida框架重寫setScore方法將值直接設爲-1。

用frida-ps -R發現應用進程。

Javascript腳本如下:

Java.perform(function() {
    var clz = Java.use("ds.tetris.android.MainActivity");
  clz.setScore.overload('int').implementation = function(args){
  args = -1
  clz.setScore.overload('int').call(this,args)
  }
  });

運行服務器frida-server,客戶端使用Frida運行以下命令:

點擊遊戲開始,程序會解密並彈窗。

完整的python代碼如下:

import frida, sys


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

jscode = """
Java.perform(function() {
    var clz = Java.use("ds.tetris.android.MainActivity");
  clz.setScore.overload('int').implementation = function(args){
  args = -1
  clz.setScore.overload('int').call(this,args)
  }
  });
"""
process = frida.get_usb_device().attach('ds.tetris.android')
script = process.create_script(jscode)
script.on('message', on_message)
script.load()
sys.stdin.read()

0X04小小總結

本期Android逆向之動態分析Frida篇就爲大家介紹到這裏啦!各位小夥伴如果在學習的過程中有疑問或者是其他的見解,都可以給鬥哥留言!我們下週見!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章