<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                我們介紹過Cydiasubstrate框架提供在Java層Hook的能力,其中主要是提供了三個比較重要的方法, * MS.hookClassLoad * MS.hookMethod * MS.moveUnderClassLoader。 三個方法的具體介紹如下圖1 所示 ![](https://box.kancloud.cn/7b1d343c8ce60e721c7fe41dba9ab164_763x264.png) ~~~ /** Hook一個指定的Class * * @paramname Class的包名+類名,如android.content.res.Resources * @paramhook 成功Hook一個Class后的回調 */ void hookClassLoad(String name, MS.ClassLoadHook hook); /** * Hook一個指定的方法,并替換方法中的代碼 * * @param_class Hook的calss * @parammember Hook class的方法參數 * @paramhook 成功Hook方法后的回調 * @paramold Hook前方法,類似C中的方法指針 */ void hookMethod(Class _class, Member member, MS.MethodHook hook, MS.MethodPointer old); /** * Hook一個指定的方法,并替換方法中的代碼 * * @param_class Hook的calss * @parammember Hook class的方法參數 * @paramalteration */ void hookMethod(Class _class, Member member, MS.MethodAlteration alteration); /** * 使用一個ClassLoader重載一個對象 * * @paramloader 使用的ClassLoader * @paramobject 待重載的對象 * @return重載后的對象 */ <T>TmoveUnderClassLoader(ClassLoader loader, T object); ~~~ #### **嘗試Hook系統API** **實戰**:如我們希望Hook Android系統中的Resources類,并將系統中的顏色都改為紫羅蘭色。思路很簡單,我們只需要拿到系統中Resources類的getColor方法,將其返回值做修改即可。 使用substrate來實現分為以下幾步。 **1. 在AndroidManifest.xml文件中配置主入口** 需要在AndroidManifest.xml中聲明cydia.permission.SUBSTRATE權限,聲明substrate的主入口。具體代碼如下所示 ~~~ <!-- 加入substrate權限 --> <uses-permission android:name="cydia.permission.SUBSTRATE" /> <application     android:allowBackup="true"     android:icon="@drawable/ic_launcher"     android:label="@string/app_name"     android:theme="@style/AppTheme" > <!-- 聲明substrate的注入口味Main類 --> <meta-data        android:name="com.saurik.substrate.main"        android:value=".Main" /> </application> ~~~ **2.新創建主入口Main.Java類** 上一步中已經聲明了主入口為Main類,所以我們需要在對應的目錄下新建一個Main類,且需要實現其initialize方法。具體實現如下: ~~~ public class {    /**    * substrate 初始化后的入口    */ static void initialize() {   } } ~~~ **3.Hook系統的Resources,Hook其getColor方法,修改為紫羅蘭** 使用MS.hookClassLoad方法Hook系統的Resources類,并使用MS.hookMethod方法hook其getColor方法,替換其方法。具體實現如下所示。 ~~~ import Java.lang.reflect.Method; import com.saurik.substrate.MS; public class {    /**    * substrate 初始化后的入口    */ static void initialize() {     // hook 系統的 Resources類     MS.hookClassLoad("android.content.res.Resources", newMS.ClassLoadHook() {       // 成功hook resources類 public void classLoaded(Class<?> resources) {         // 獲取 Resources類中的 getColor方法         Method getColor; try{           getColor = resources.getMethod("getColor", Integer.TYPE);         } catch(NoSuchMethodException e) {           getColor = null;         } if(getColor != null) {           // Hook前的原方法 final MS.MethodPointer old = newMS.MethodPointer();           // hook Resources類中的getColor方法           MS.hookMethod(resources, getColor, newMS.MethodHook() { public Object invoked(Object resources, Object...args) throws Throwable { intcolor = (Integer) old.invoke(resources, args);               // 將所有綠色修改成了紫羅蘭色 return color & ~0x0000ff00 | 0x00ff0000;             }           }, old);         }       }    });   } } ~~~ **4.安裝、重啟、驗證** 因為我們的應用是沒有Activity,只存在substrate的,所以安裝后substrate就會自動地執行了。重啟后,我們打開瀏覽器引用,發現顏色已經改變了,如圖8-11所示。 ![](https://box.kancloud.cn/1d10f75dfba7185b88d11fc5da9db7ef_616x399.png) 閱讀了本例之后,讀者們是不是發現使用了CydiaSubstrate框架后我們Hook系統中的一些Java API并不是什么難事?上面的例子我們只是簡單地修改了Resources中的getColor方法,并沒有涉及到系統與應用的安全。但是,如果開發者直接Hook系統安全方面比較敏感的方法,如TelephonyManager 類中getDeviceId方法、短信相關的方法或一些關鍵的系統服務中的方法,那么后果是不堪想象的。 #### **Hook指定應用注入廣告** 從上面的例子我們可以看出來,使用Cydiasubstrate框架我們能夠任意地Hook系統中的Java API,當然其中也用到了很多的反射機制,那么除了系統中給開發者提供的API以外,我們能否也Hook應用程序中的一些方法呢?答案是肯定的。下面我們就以一個實際的例子講解一下如何Hook一個應用程序。 下面我們針對Android操作系統的瀏覽器應用,Hook其首頁Activity的onCreate方法(其他方法不一定存在,但是onCreate方法一定會有),并在其中注入我們的廣告。根據上面對Cydiasubstrate的介紹,我們有了一個簡單的思路。 首先,我們根據某廣告平臺的規定,在我們的AndroidManifest.xml文件中填入一些廣告相關的ID,并且在AndroidManifest.xml文件中填寫一些使用Cydiasubstrate相關的配置與權限。當然,我們還會聲明一個廣告的Activity,并設置此Activity為背景透明的Activity,為什么設置為透明背景的Activity,原理如圖8-12所示。 :-: ![](https://box.kancloud.cn/79619d137d3331f34014eb12336b7446_331x283.png) 其AndroidManifest.xml文件的部分內容如下所示 ~~~ <!-- 廣告相關的權限 --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.GET_TASKS" /> <!-- 加入substrate權限 --> <uses-permission android:name="cydia.permission.SUBSTRATE" /> <application   android:allowBackup="true"   android:icon="@drawable/ic_launcher"   android:label="@string/app_name"   android:theme="@style/AppTheme" > <!-- 廣告相關參數 --> <meta-data     android:name="App_ID"     android:value="c62bd976138fa4f2ec853bb408bb38af" /> <meta-data     android:name="App_PID"     android:value="DEFAULT" /> <!-- 聲明substrate的注入口為Main類 --> <meta-data     android:name="com.saurik.substrate.main"     android:value="com.example.hookad.Main" /> <!-- 透明無動畫的廣告Activity --> <activity     android:name="com.example.hookad.MainActivity"     android:theme="@android:style/Theme.Translucent.NoTitleBar" > <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <!-- 廣告的action --> <action android:name="com.example.hook.AD" /> </intent-filter> </activity> </application> ~~~ 對于Cydiasubstrate的主入口Main類,依照之前的步驟新建一個包含有initialize方法的Main類。這個時候我們希望使用MS.hookClassLoad方式找到瀏覽器主頁的Activity名稱,這里我們在adb shell下使用dumpsys activity命令找到瀏覽器主頁的Activity名稱為com.android.browser.BrowserActivity,如圖8-13所示 :-: ![](https://box.kancloud.cn/35be908d46ba39e1af2a0311c47be4fc_635x143.png) 使用MS.hookClassLoad方法獲取了BrowserActivity之后再hook其onCreate方法,在其中啟動一個含有廣告的Activity。Main類的代碼如下所示。 ~~~ public class {   /**    * substrate 初始化后的入口    */ static void initialize() {     //Hook 瀏覽器的主Activity,BrowserActivity     MS.hookClassLoad("com.android.browser.BrowserActivity", new MS.ClassLoadHook() { public void class Loaded(Class<?> resources) {         Log.e("test", "com.android.browser.BrowserActivity");         // 獲取BrowserActivity的onCreate方法         Method onCreate; try{           onCreate = resources.getMethod("onCreate", Bundle.class);         } catch(NoSuchMethodException e) {           onCreate = null;         } if(onCreate != null) { final MS.MethodPointer old = newMS.MethodPointer();           // hook onCreate方法           MS.hookMethod(resources, onCreate, new MS.MethodHook() { public Object invoked(Object object, Object...args) throws Throwable {               Log.e("test", "show ad"); // 執行Hook前的onCreate方法,保證瀏覽器正常啟動               Object result = old.invoke(object, args); // 沒有Context               //執行一個shell啟動我們的廣告Activity               CMD.run("am start -a com.example.hook.AD"); return result;             }           }, old);         }       }    });   } } ~~~ 對于啟動的廣告MainActivity,在其中會彈出一個插屏廣告,當然也可以是其他形式的廣告或者浮層,內容比較簡單這里不做演示了。對整個項目進行編譯,運行。這個時候我們重新啟動Android自帶的瀏覽器的時候發現,瀏覽器會彈出一個廣告彈框,如圖下圖8-14所示。 :-: ![](https://box.kancloud.cn/adc9f0d67afdc357cac065eb7ba23f2e_371x462.png) 從上面的圖片我們可以看出來了,之前我們設置插屏廣告MainActivity為無標題透明(**Theme.Translucent.NoTitleBar**)就是為了使彈出來的廣告與瀏覽器融為一體,讓用戶感覺是瀏覽器彈出的廣告。這也是惡意廣告程序為了防止自身被卸載掉的一些通用隱藏手段。 這里演示的注入廣告是通過Hook指定的Activity中的onCreate方法來啟動一個廣告Activity的。當然,這里我們演示的Activity只是簡單地彈出了一個廣告。如果啟動的Activity帶有惡意性,如將Activity做成與原Activity一模一樣的釣魚Activity,那么對于移動設備用戶來說是極具欺騙性的。 #### **App登錄劫持** 看了上面的兩個Hook例子,很多讀者應該都能夠了解了Hook所帶來的巨大危害性,特別是針對一些有目的性的Hook。例如我們常見的登錄劫持,就是使用到了Hook技術來完成的。那么這個登錄劫持是如何完成的呢?下面我們就具體來看看,一個我們在開發中常見到的登錄例子。首先我們看看一個常見的登錄界面是什么樣子的,圖8-15所示是一個常見的登錄頁面。 :-: ![](https://box.kancloud.cn/1eae2c07d53eb6fe2fc6cd6a84f26a32_269x209.png) 其對應的登錄流程代碼如下所示。 ~~~ // 登錄按鈕的onClick事件 mLoginButton.setOnClickListener(new OnClickListener() {   @Override   public void onClick(View v) {    // 獲取用戶名     String username = mUserEditText.getText() + ""; //獲取密碼     String password = mPasswordEditText.getText() + ""; if(isCorrectInfo(username, password)) {       Toast.makeText(MainActivity.this, "登錄成功!", Toast.LENGTH_LONG).show();     } else{       Toast.makeText(MainActivity.this, "登錄失敗!", Toast.LENGTH_LONG).show();     }   } }); ~~~ 我們會發現,登錄界面上面的用戶信息都存儲在EditText控件上,然后通過用戶手動點擊“登錄”按鈕才會將上面的信息發送至服務器端去驗證賬號與密碼是否正確。這樣就很簡單了,黑客們只需要找到開發者在使用EditText控件的getText方法后進行網絡驗證的方法,Hook該方法,就能劫持到用戶的賬戶與密碼了。具體流程如圖8-16所示。 :-: ![](https://box.kancloud.cn/d84ae75f15771b0066191ecaa9bce571_411x354.png) >[info] 當然,我們也可以仿照上一個例子,做一個一模一樣的Activity,再劫持原Activity優先彈出來,達到欺騙用戶獲取密碼的目的。 明白了原理下面我們就實際地操作一次,這里我們選擇使用Xposed框架來操作。使用Xposed進行Hook操作主要就是使用到了Xposed中的兩個比較重要的方法,handleLoadPackage獲取包加載時的回調并拿到其對應的classLoader,findAndHookMethod對指定類的方法進行Hook。它們的詳細定義如下所示。 ~~~ /**   * 包加載時的回調    */   public void handleLoadPackage(final LoadPackageParam lpparam)   /**    * Xposed提供的Hook方法    *    * @paramclassName 待Hook的Class    * @paramclassLoader classLoader    * @parammethodName 待Hook的Method    * @paramparameterTypesAndCallback hook回調    * @return    */ ~~~ Unhook findAndHookMethod(String className, ClassLoader classLoader, String methodName, Object... parameterTypesAndCallback) 當然,我們使用Xposed進行Hook也分為如下幾個步驟。 **1.在AndroidManifest.xml文件中配置插件名稱與Api版本號** ~~~ <application     android:allowBackup="true"     android:icon="@drawable/ic_launcher"     android:label="@string/app_name"     android:theme="@style/AppTheme" > <meta-data       android:name="xposedmodule"       android:value="true" /> <!-- 模塊描述 --> <meta-data       android:name="xposeddescription"       android:value="一個登錄劫持的樣例" /> <!-- 最低版本號 --> <meta-data       android:name="xposedminversion"       android:value="30" /> </application> ~~~ **2.新創建一個入口類繼承并實現IXposedHookLoadPackage接口** 如下操作,我們新建了一個com.example.loginhook.Main的類,并實現IXposedHookLoadPackage接口中的handleLoadPackage方法,將非com.example.login包名的應用過濾掉,即我們只操作包名為com.example.login的應用,如下所示。 ~~~ public class Main implements IXposedHookLoadPackage {   /**    * 包加載時的回調    */ public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {     // 將包名不是 com.example.login 的應用剔除掉 if(!lpparam.packageName.equals("com.example.login")) return;     XposedBridge.log("Loaded app: " + lpparam.packageName);   } } ~~~ **3.聲明主入口路徑** 需要在assets文件夾中新建一個xposed_init文件,并在其中聲明主入口類。如這里我們的主入口類為com.example.loginhook.Main,查看其內容截圖如圖8-17所示。 :-: ![](https://box.kancloud.cn/c3e81ec505540eea60bde5fa23db9051_368x105.png) **4.使用findAndHookMethod方法Hook劫持登錄信息** 這是最重要的一步,我們之前所分析的都需要到這一步進行操作。如我們之前所分析的登錄程序,我們需要劫持就是需要Hook其com.example.login.MainActivity中的isCorrectInfo方法。我們使用Xposed提供的findAndHookMethod直接進行MethodHook操作(與Cydia很類似)。在其Hook回調中使用XposedBridge.log方法,將登錄的賬號密碼信息打印至Xposed的日志中。具體操作如下所示。 ~~~ import static de.robv.android.xposed.XposedHelpers.findAndHookMethod; public class Main implements IXposedHookLoadPackage { /** * 包加載時候的回調 */ public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable { // 將包名不是 com.example.login 的應用剔除掉 if (!lpparam.packageName.equals("com.example.login")) return; XposedBridge.log("Loaded app: " + lpparam.packageName); // Hook MainActivity中的isCorrectInfo(String,String)方法 findAndHookMethod("com.example.login.MainActivity", lpparam.classLoader, "isCorrectInfo", String.class, String.class, new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { XposedBridge.log("開始劫持了~"); XposedBridge.log("參數1 = " + param.args[0]); XposedBridge.log("參數2 = " + param.args[1]); } @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { XposedBridge.log("劫持結束了~"); XposedBridge.log("參數1 = " + param.args[0]); XposedBridge.log("參數2 = " + param.args[1]); } }); } } ~~~ **5.在XposedInstaller中啟動我們自定義的模塊** 編譯后安裝在Android設備上的模塊應用程序不會立即生效,我們需要在XpasedInstaller模塊選項中勾選待啟用的模塊才能讓其正常地生效,如圖8-18所示。 :-: ![](https://box.kancloud.cn/9bb243aa705cbf4ef68686d031b4473f_406x203.png) **6.重啟驗證** 重啟Android設備,進入XposedInstaller查看日志模塊,因為我們之前使用的是XposedBridge.log方法打印log,所以log都會顯示在此處。如圖8-19所示,我們發現我們需要劫持的賬號密碼都顯示在此處。 :-: ![](https://box.kancloud.cn/26b42527183935e3f391d765a79d1e33_406x212.png) >[info] 這里我們是通過逆向分析該登錄頁面的登錄判斷調用函數來完成Hook與劫持工作的。有些讀者應該想出來了,我們能不能直接對系統中提供給我們的控件EditText(輸入框控件)中的getText()方法進行Hook呢?這樣我們就能夠對系統中所有的輸入進行監控劫持了。這里留給大家一個思考,感興趣的讀者可以嘗試一下。 #### **參考文章:** [《Android安全技術揭秘與防范》—第8章8.3節HookAndroid應用](https://yq.aliyun.com/articles/99846?spm=5176.100239.blogcont99909.20.6fd616147MOkdC) [Android Hook神器——XPosed入門(登陸劫持演示)](http://blog.csdn.net/yzzst/article/details/47659479)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看