Hook技術


hook鈎子:

使用技術手段在運行時動態的將額外代碼依附現進程,從而實現替換現有處理邏輯或插入額外功能的目的。

它的技術實現要點有兩個:

1)如何注入代碼(如何將額外代碼依附於現有代碼中)。

2)如何確定目標函數的地址及替換。

 

要素:

1)現有功能;

2)目標功能;

3)替換技術。

 

http://www.epubit.com.cn/book/onlinechapter/33620?utm_source=tuicool&utm_medium=referral

8.1 什么是Hook技術

還沒有接觸過Hook技術讀者一定會對Hook一詞感覺到特別的陌生,Hook英文翻譯過來就是“鈎子”的意思,那我們在什么時候使用這個“鈎子”呢?我們知道,在Android操作系統中系統維護着自己的一套事件分發機制。應用程序,包括應用觸發事件和后台邏輯處理,也是根據事件流程一步步地向下執行。而“鈎子”的意思,就是在事件傳送到終點前截獲並監控事件的傳輸,像個鈎子鈎上事件一樣,並且能夠在鈎上事件時,處理一些自己特定的事件。較為形象的流程如圖8-1所示。

Hook的這個本領,使它能夠將自身的代碼“融入”被勾住(Hook)的程序的進程中,成為目標進程的一個部分我們也知道,在Android系統中使用了沙箱機制,普通用戶程序的進程空間都是獨立的,程序的運行彼此間都不受干擾。這就使我們希望通過一個程序改變其他程序的某些行為的想法不能直接實現,但是Hook的出現給我們開拓了解決此類問題的道路。當然,根據Hook對象與Hook后處理的事件方式不同,Hook還分為不同的種類,如消息Hook、API Hook等。

圖8-1 Hook原理圖

8.1.1 Hook原理

Hook技術無論對安全軟件還是惡意軟件都是十分關鍵的一項技術,其本質就是劫持函數調用。但是由於處於Linux用戶態,每個進程都有自己獨立的進程空間,所以必須先注入到所要Hook的進程空間,修改其內存中的進程代碼,替換其過程表的符號地址。在Android中一般是通過ptrace函數附加進程,然后向遠程進程注入so庫,從而達到監控以及遠程進程關鍵函數掛鈎。

Hook技術的難點,並不在於Hook技術,初學者借助於資料“照葫蘆畫瓢”能夠很容易就掌握Hook的基本使用方法。如何找到函數的入口點、替換函數,這就涉及了理解函數的連接與加載機制。

從Android的開發來說,Android系統本身就提供給了我們兩種開發模式,基於Android SDK的Java語言開發,基於AndroidNDK的Native C/C++語言開發。所以,我們在討論Hook的時候就必須在兩個層面上來討論。對於Native層來說Hook的難點其實是在理解ELF文件與學習ELF文件上,特別是對ELF文件不太了解的讀者來說;對於Java層來說,Hook就需要了解虛擬機的特性與Java上反射的使用。

8.1.1.1 Hook工作流程

之前我們介紹過Hook的原理就是改變目標函數的指向,原理看起來並不復雜,但是實現起來卻不是那么的簡單。這里我們將問題細分為兩個,一個是如何注入代碼,另一個是如何注入動態鏈接庫。

注入代碼我們就需要解決兩個問題。

  • 需要注入的代碼我們存放在哪里?
  • 如何注入代碼?

注入動態共享庫我們也需要解決兩個問題:

  • 我們不能只在自己的進程載入動態鏈接庫,如何使進程附着上目標進程?
  • 如何讓目標進程調用我們的動態鏈接庫函數?

這里我也不賣關子了,說一下目前對上述問題的解決方案吧。對於進程附着,Android的內核中有一個函數叫ptrace,它能夠動態地attach(跟蹤一個目標進程)、detach(結束跟蹤一個目標進程)、peektext(獲取內存字節)、poketext(向內存寫入地址)等,它能夠滿足我們的需求。而Android中的另一個內核函數dlopen,能夠以指定模式打開指定的動態鏈接庫文件。對於程序的指向流程,我們可以調用ptrace讓PC指向LR堆棧。最后調用,對目標進程調用dlopen則能夠將我們希望注入的動態庫注入至目標進程中。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM