Android之hook簡單認識


一、Hook技術 

1.Hook英文翻譯為“鈎子”,而鈎子就是在事件傳送到終點前截獲並監控事件的傳輸,像個鈎子鈎上事件一樣,並且能夠在鈎上事件時,處理一些自己特定的事件; 
2.Hook使它能夠將自己的代碼“融入”被勾住(Hook)的進程中,成為目標進程的一部分; 
3.在Andorid沙箱機制下,Hook是我們能通過一個程序改變其他程序某些行為得以實現; 

二、Hook分類 


1.根據Android開發模式,Native模式(C/C++)和Java模式(Java)區分,在Android平台上 
  Java層級的Hook; 
  Native層級的Hook; 
2.根Hook對象與Hook后處理事件方式不同,Hook還分為: 
  消息Hook; 
  API Hook; 
3.針對Hook的不同進程上來說,還可以分為: 
  全局Hook; 
  單個進程Hook; 


三、Hook原理 

Hook技術本質是函數調用,由於處於Linux用戶狀態,每個進程有自己獨立的進程控件,所以必須先注入所要Hook的進程空間,修改其內存中進程代碼,替換過程表的符號地址,通過ptrace函數附加進程,向遠程進程注入so庫,從而達到監控以及遠程進程關鍵函數掛鈎; 

 

四、Hook工作流程 

1.Android相關內核函數: 
  ptrace函數:跟蹤一個目標進程,結束跟蹤一個目標進程,獲取內存字節,像內存寫入地址; 
  dlopen函數:以指定模式打開指定的動態鏈接庫文件; 
  mmap函數:分配一段臨時的內存來完成代碼的存放; 
2.向目標進程注入代碼總結后的步驟分為以下幾步: 
  用ptrace函數attch上目標進程; 
  發現裝載共享庫so函數; 
  裝載指定的.so; 
  讓目標進程的執行流程跳轉到注入的代碼執行; 
  使用ptrace函數的detach釋放目標集成; 


五、常用Hook工具-Xposed框架 

1.Xposed框架是一款可以在不修改APK的情況下影響程序運行(修改系統)的框架服務; 
2.通過替換/system/bin/app_process程序控制zygote進程,使app_process在啟動過程中加載XposedBridge.jar這個jar包,從而完成對Zygote進程及其創建的Dalvik虛擬機的劫持; 

 

六、Xposed框架安裝 

1.從官方網站(http://repo.xposed.info/module/de.robv.android.xposed.installer),下載de.robv.android.xposed.installer_v33_36570c.apk,安裝本地服務XposedInstaller;

 

 

 

 
2.安裝進入到XposedInstaller應用程序,“框架”模塊出現“未激活”提示; 

3.點擊“框架”,進入到需要激活框架的界面,我們點擊“安裝/更新”就能完成框架的激活了,因為安裝時會需要Root權限(下載相關工具如“Root精靈”),安裝后會啟動Xposed的app_process,所以安裝過程會存在設備多次重啟(安裝過程如下圖); 

 

 

 

 

 

 


正在安裝(下載): 

獲取Root權限(授權Root權限提示,並確定): 

 

 

 



安裝完成(安裝完成提示重啟): 

 

 

 



安裝成功(框架模塊激活提示消失,即安裝成功): 


七、Xposed框架模塊安裝 

1.Xposed框架內置了下載功能,我們只需要在下載模塊點擊之后,進行瀏覽、下載、搜索即可; 

 

 

 



2.默認按照時間排序,你可以點擊放大鏡圖標,進行搜索如(XuiMod,一款專門用於狀態欄和置頂電池模塊); 

搜索XuiMod模塊: 

 

 

 



3.點擊搜索到的模塊,可以查看到該模塊的描述信息,版本信息。在版本信息模塊下進行模塊的下載安裝; 
XuiMod描述信息: 

 

 

 



XuiMod版本信息,點擊下載相關模塊: 

下載完成,點擊“安裝”進行安裝: 

 

 

 



安裝完成后,進入“模塊”,激活下載安裝的模塊,重啟生效: 

 

 

 



重啟后,長按XuiMod進入到模塊運行界面,進行相關的操作,重啟生效(如下圖,手機頂部打開電源充電,居中,充電動畫功能): 

 

 

八、Xposed自定義模塊開發 

上個段落,我們講解下如何下載、安裝和使用Xposed模塊。那么我們如何根據自己的需求,自己開發一個Xposed模塊,下面我們就介紹下相關流程: 
1.下載XposedBridgeApi-<version>.jar(http://forum.xda-developers.com/xposed/xposed-api-changelog-developer-news-t2714067)文件,用戶提供Hook相關的API,如下:  

/** 
*包裝加載時的回調 
*/ 
public void handleLoadPackage(final LoadPackageParam lpparam)  
/** 
*Xposed提供的Hook方法 
*@param className 待Hook的Class 
*@param classLoader ClassLoader 
*@param methodName 待Hook的Method 
*@param paramterTypesAndClassback hook回調 
*/ 
Unhook findAndHookMethod(String className,ClassLoader classLoader,String methodName,Object... parameterTypesAndCallback)

 

2.創建一個Android Project HookDemo,在項目app目錄下創建lib目錄(如果將jar包放置到libs目錄下,可能會產生錯誤,估計Xposed作者在其框架內部也引用了BrideApi,這樣操作能避免重復),將jar包放置到lib目錄(不是項目本身的libs目錄)下,選擇jar包->右鍵->Add As Library將這個jar包添加到BuildPATH; 

 

 


3.創建一個InputDemo項目(該項目使用輸入框提示用戶輸入信息,點擊按鈕獲取用戶的信息並做相關的邏輯),用於模擬Hook目標,通過Xposed獲取用戶輸入信息(關鍵代碼和運行如下); 

 

 

OK.setOnClickListener(new View.OnClickListener() { 
            @Override 
            public void onClick(View v) { 
                String inPut = Input.getText() + ""; 
                //獲取用戶輸入,並驗證是否輸入正確 
                if (isInputOK(inPut)) { 
                    Toast.makeText(MainActivity.this, "Input Success", Toast.LENGTH_SHORT).show(); 
                } else { 
                    Toast.makeText(MainActivity.this, "Input Faild", Toast.LENGTH_SHORT).show(); 
                } 
            } 
        }); 
… …  
 private boolean isInputOK(String inPut) { 
        if ("123456".equals(inPut)) { 
            return true; 
        } else { 
            return false; 
        } 
    }

 


4.在HookDemo項目中,修改AndroidManifest.xml文件中配置插件的名稱和Api版本號; 

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.pengchengxiang.hookdemo"> 
    <application> 
        … … 
        <meta-data 
            android:name="xposedmodule" 
            android:value="true" /> 
        <!--模塊描述--> 
        <meta-data 
            android:name="xposeddescription" 
            android:value="a hook demo" /> 
        <!--模塊版本--> 
        <meta-data 
            android:name="xposedminversion" 
            android:value="30" /> 
    </application> 
</manifest>

 

5.創建一個入口類繼承並實現IXposedHookLoadPackage接口,使用findAndHookMethod方法Hook輸入信息;  

public class Main implements IXposedHookLoadPackage { 
    @Override 
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { 
        if (!loadPackageParam.packageName.equals("com.example.pengchengxiang.inputdemo")) { 
            return; 
        } 
 
 
        XposedBridge.log("Loaded app:" + loadPackageParam.packageName); 
        //Hook MainActivity類的isInputOK方法,並將該方法的參數輸出至Xposed工具中 
        findAndHookMethod("com.example.pengchengxiang.inputdemo.MainActivity", loadPackageParam.classLoader, "isInputOK", String.class, new XC_MethodHook() { 
            @Override 
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 
                XposedBridge.log("hook start"); 
                XposedBridge.log("param1:" + param.args[0]); 
            } 
 
            @Override 
            protected void afterHookedMethod(MethodHookParam param) throws Throwable { 
                XposedBridge.log("hook end"); 
                XposedBridge.log("param1:" + param.args[0]); 
            } 
        }); 
    } 
}

 

注意:在實際應用過程中,你Hook的方法參數可能是目標程序自定義的類,非Android SDK提供,如"com.example.pengchengxiang.inputdemo.Test"。這里我們可以使用方法XposedHelpers.findClass來獲取參數類型的class對象,如下:

XposedHelpers.findAndHookMethod("com.example.pengchengxiang.inputdemo.MainActivity", loadPackageParam.classLoader, "isInputOK", String.class,
                XposedHelpers.findClass("com.example.pengchengxiang.inputdemo.Test", loadPackageParam.classLoader), new XC_MethodHook() {...}

 

6.聲明主入口路徑,在assets文件夾中創建xposed_init文件,並在其中聲明主入口類; 

 

com.example.pengchengxiang.hookdemo.Main

 

7.完成InputDemo和HookDemo並安裝在手機中,在XposedInstaller中啟動我們的自己開發的模塊; 

 

 



8.重新啟動手機,在XposedInstaller中日志模塊,查看在InputDemo中使用XposedBridge.log輸出的日志; 

 

 




提示1:查看日志模塊,如果報錯如下圖: 

 

 



處理1:第一,檢查XposedBridgeApi-54.jar是否防在新建的lib目錄下;第二,估計Xposed作者在其框架內部也使用了BridgeApi,使用Provided依賴避免重復引用; 

 

 

轉載於:https://blog.csdn.net/p106786860/article/details/52213695?


免責聲明!

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



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