詳解Hook框架frida,讓你在逆向工作中效率成倍提升

https://zhuanlan.zhihu.com/p/41662447

一、frida簡介

frida是一款基於python + javascript 的hook框架,可運行在androidioslinuxwinosx等各平臺,主要使用動態二進制插樁技術。本期“安仔課堂”,ISEC實驗室的彭老師爲大家詳解frida,認真讀完這篇文章會讓你在逆向工作中效率成倍提升哦!

 

 

 

 

1.插樁技術

插樁技術是指將額外的代碼注入程序中以收集運行時的信息,可分爲兩種:

(1)源代碼插樁[Source Code Instrumentation(SCI)]:額外代碼注入到程序源代碼中。

(2)二進制插樁(Binary Instrumentation):額外代碼注入到二進制可執行文件中。

 

●靜態二進制插樁[Static Binary Instrumentation(SBI)]:在程序執行前插入額外的代碼和數據,生成一個永久改變的可執行文件。

●動態二進制插樁[Dynamic Binary Instrumentation(DBI)]:在程序運行時實時地插入額外代碼和數據,對可執行文件沒有任何永久改變。

 

2.你能用DBI做些什麼呢

(1)訪問進程的內存

(2)在應用程序運行時覆蓋一些功能

(3)從導入的類中調用函數

(4)在堆上查找對象實例並使用這些對象實例

(5)Hook,跟蹤和攔截函數等等

 

二、frida的安裝

今天我們用到的frida框架分爲兩部分: 一部分是運行在系統上的交互工具frida CLI; 另一部分是運行在目標機器上的代碼注入工具 frida-server。

 

1.frida CLI

環境要求:

●系統環境 - Windows, macOS, or GNU/Linux

●Python – 最新的3.x版本

 

通過 pip 安裝frida

 

 

圖1

說明:

(1) 通過pip安裝的frida是可以跟python綁定的; 另外frida現在也已經有了跟nodeJs綁定的版本, 因此也可以直接通過 npm 進行安裝。

(2) frida CLI是安裝的frida的其中一個工具,也是最常用的一個工具。

 

2.frida server

frida-server需要我們單獨下載,在 frida項目的github上可以直接下載對應系統已經編譯好的frida server

 

 

圖2

 

我們需要下載的文件名的格式是: frida-server-(version)-(platform)-(cpu).xz

我試驗的手機是nexus6p, cpu爲arm64

 

所以我需要下載的是: frida-server-11.0.13-android-x86_64.xz;注意, frida-server 的版本一定要跟 frida CLI的版本一致。

 

將下載後的壓縮包解壓得到frida-server, 然後將該文件推送到Android設備上。

 

 

圖3

 

將Android設備上的frida-server添加執行權, 並運行該程序(需要root權限)

 

 

圖4

 

3.frida tools

前面說過, frida CLI只是frida的其中一個工具, frida 的工具共有6個:

(1) frida CLI: 是一個交互式解釋器(REPL),他的交互形式跟IPython很類似。

 

 

圖5

 

(2) frida-ps: 用於列出進程的一個命令行工具,當我們需要跟遠程系統進行交互的時候,這個是非常有用的。

 

 

圖6

 

另外還有四個分別是: frida-trace, frida-discover, frida-ls-devices, frida-kill

由於不是經常用到,這邊就不一一詳細介紹了, 感興趣的同學可以去frida的官網查看他們的詳細介紹和用法。

 

4.Java Api

在Hook開始之前,有必要對Java注入相關的api做一個簡單介紹, frida的注入腳本是JavaScript, 因此我們後面都是通過js腳本來操作設備上的Java代碼的。

 

 

圖7

 

當我們獲取到Java類之後,我們直通過接 <wrapper>.<method>.implementations = function() {}的方式來hook wrapper類的method方法,不管是實例方法還是靜態方法都可以。

 

由於js代碼注入時可能會出現超時的錯誤, 爲了防止這個問題,我們通常還需要在最外面包裝一層setImmediate(function(){})的代碼。

 

下面就是js的一個模板代碼:

 

 

圖8

 

三、 frida Hook實戰

接下來我將通過製作一個類似微信搶紅包的插件來演示frida的具體使用,由於本文的主旨是教大家如何使用強大的frida框架, 所以側重描述的是frida的使用, 而不會說明如何逆向微信。

 

1.信息持久化到本地的攔截

微信的每一條信息都會保存到本地數據庫,這個保存的方法就是 com.tencent.wcdb.database.SQLiteDatabase 類的 insert()方法:

 

 

圖9

 

我們先看看每條信息保存的內容是什麼:

 

 

圖10

 

我們將手機連接到電腦, 然後通過frida將腳本注入到微信中:

 

 

圖11

 

用微信發送任意消息,我們可以看到控制檯打印內容如下:

 

 

圖12

 

arg1就是要插入數據的表名, arg2是表的主鍵, arg3是要插入表的數據的字段名稱跟值的集合。這樣, 我們就可以輕鬆拿到每條消息的內容和發送者等相關信息。

 

這裏我們需要注意的是arg3裏面以下幾個值:

 

 

圖13

 

當我們接收到一條紅包消息的時候,我們可以看到紅包信息的具體內容如下:

 

 

圖14

 

 

圖15

 

那我們要怎樣通過這些信息來搶到紅包呢?

 

2

搶紅包流程分析

我們先來看一下,當我們點擊打開紅包之時發生了什麼呢? 下面是反編譯得到的打開紅包按鈕的點擊事件:

 

 

圖16

 

這行代碼其實就是發送搶紅包的請求, ad 就是一個網絡請求類, 那麼需要構成這個請求又需要哪些參數呢?

 

我們單獨看看 ad 類的創建:

 

 

圖17

 

其中第1,2,3,4,9個參數都是來自luckyMoneyReceiveUI.kRG, 第8個參數是固定的 "v1.0"

 

接下來我們來打印一下第5,6,7個參數是什麼:

 

圖18

 

重新加載這段js代碼, 然後我們打開一個紅包, 我們可以看到控制檯打印如下信息:

 

圖19

 

第5,6個參數其實是自己的頭像跟暱稱信息,第7個是發送者的信息,而第4個參數跟上面紅包內容裏面的nativeurl的值是一樣的。

 

那luckyMoneyReceiveUI.kRG 中的msgType,bxk,kLZ,ceR,kRC這些要怎麼得到呢?

 

luckyMoneyReceiveUI.kRG 這個字段的類型是: com.tencent.mm.plugin.luckymoney.b.ag,ag類跟之前提到的ad類一樣, 都是一個請求類, 他們都是繼承同一個類。其中, msgType是固定的 1,bxk,kLZ,ceR 是在ag的構造方法裏面就被初始化的:

 

 

圖20

 

而kRC則是在裏面的a方法裏面被賦值的:

 

 

圖21

……

 

 

圖22

 

這個a方法是請求類發起請求之後的一個回調,而在 LuckyMoneyReceiveUI的 OnCreate 方法裏面我們可以看到 com.tencent.mm.plugin.luckymoney.b.ag 是怎麼被構造出來的:

 

 

圖23

 

第一個參數是nativeurl中的channelid;

第二個參數是nativeurl中的sendid;

第三個參數是nativeurl本身;

第四個參數可以用0;

第五個參數是也是固定的 "v1.0"

 

經過上面的分析之後, 我們的思路就清晰了, 在收到紅包信息後我們解析出紅包信息裏面nativeurl, channelid, sendid, 根據這些參數發送一個com.tencent.mm.plugin.luckymoney.b.ag的請求, 之後得到timingIdentifier, 最後根據得到的timingIdentifier 再發送一個com.tencent.mm.plugin.luckymoney.b.ad的請求就可以搶到紅包了。

 

3

模擬請求

到這裏我們也就剩最後一個問題了, 那就是怎麼把請求發送出去?這個我們同樣可以看看微信, 我們跟蹤到紅包界面的請求都是通過下面的方法發送的:

 

 

圖24

 

上面的g.Eh().dpP得到的是一個專門發送請求的Network, 得到這個Network之後我們就可以調用他的a方法把這個請求發送出去。需要注意的是frida不支持直接通過.dpP的方式拿到屬性, 不過沒關係, 我們可以通過反射的方式來獲取:

 

圖25

 

得到Network之後我們就開始發送請求了:

第一步是收到紅包信息之後要解析出ContentValues裏面的信息,並根據解析出的內容發送ag請求。

 

圖26

 

我們單獨把紅包信息的content的解析拿出來:

 

圖27

 

nativeurl的具體內容如下:

 

 

圖28

 

通過上面的解析之後我們就可以得到如下的info:

 

圖29

 

第二步是Hook ag請求的a方法, 在裏面我們可以拿到timingIdentifier的值:

 

圖30

 

注意:當一個類裏面有重載的方法的時候, 我們需要用.overload(paramtype...)來表示我們hook的是哪個重載方法。

 

最後我們還需要改造一下之前Hook的SQL的insert方法, 我們需要過濾出表名爲message,類型爲436207665的消息:

 

圖31

 

接下來就可以開始體驗我們的搶紅包插件了!

 

圖32

 

最後請看效果:

 

 

圖33

 

四、附錄

本次試驗環境如下:

微信版本: 6.6.7

frida版本: 11.0.13

frida-server: frida-server-11.0.13-android-x86_64

Android: 7.0

 

 

 

互了個動

小夥伴們,

本期內容到這裏就結束啦,

你get到了嗎?

 

歡迎大家於文末留言,

分享你的寶貴見解、

疑問、補充~

 

與ISEC實驗室大神互動的機會來啦!

速速行動起來撒!

安勝作爲國內領先的網絡安全類產品及服務提供商,秉承“創新爲安,服務致勝”的經營理念,專注於網絡安全類產品的生產與服務;以“研發+服務+銷售”的經營模式,“裝備+平臺+服務”的產品體系,在技術研究、研發創新、產品化等方面已形成一套完整的流程化體系,爲廣大用戶提供量體裁衣的綜合解決方案!

 

ISEC實驗室作爲公司新技術和新產品的預研基地,秉承“我的安全,我做主”的理念,專注於網絡安全領域前沿技術研究,提供網絡安全培訓、應急響應、安全檢測等服務。

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