欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

AndroidHook機制之實戰(zhàn)模擬

簡介

什么是 Hook

Hook 又叫“鉤子”,它可以在事件傳送的過程中截獲并監(jiān)控事件的傳輸,將自身的代碼與系統(tǒng)方法進行融入。這樣當(dāng)這些方法被調(diào)用時,也就可以執(zhí)行我們自己的代碼,這也是面向切面編程的思想(AOP)。

創(chuàng)新互聯(lián)公司專注于企業(yè)成都營銷網(wǎng)站建設(shè)、網(wǎng)站重做改版、蔡家坡網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、html5、成都做商城網(wǎng)站、集團公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為蔡家坡等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。

Hook 分類

1.根據(jù)Android開發(fā)模式,Native模式(C/C++)和Java模式(Java)區(qū)分,在Android平臺上

  • Java層級的Hook;

  • Native層級的Hook;

2.根 Hook 對象與 Hook 后處理事件方式不同,Hook還分為:

  • 消息Hook;

  • API Hook;

3.針對Hook的不同進程上來說,還可以分為:

  • 全局Hook;

  • 單個進程Hook;

常見 Hook 框架

在Android開發(fā)中,有以下常見的一些Hook框架:

  • Xposed

    通過替換 /system/bin/app_process 程序控制 Zygote 進程,使得 app_process 在啟動過程中會加載 XposedBridge.jar 這個 Jar 包,從而完成對 Zygote 進程及其創(chuàng)建的 Dalvik 虛擬機的劫持。
    Xposed 在開機的時候完成對所有的 Hook Function 的劫持,在原 Function 執(zhí)行的前后加上自定義代碼。

  • Cydia Substrate

    Cydia Substrate 框架為蘋果用戶提供了越獄相關(guān)的服務(wù)框架,當(dāng)然也推出了 Android 版 。Cydia Substrate 是一個代碼修改平臺,它可以修改任何進程的代碼。不管是用 Java 還是 C/C++(native代碼)編寫的,而 Xposed 只支持 Hook app_process 中的 Java 函數(shù)。

  • Legend

    Legend 是 Android 免 Root 環(huán)境下的一個 Apk Hook 框架,該框架代碼設(shè)計簡潔,通用性高,適合逆向工程時一些 Hook 場景。大部分的功能都放到了 Java 層,這樣的兼容性就非常好。
    原理是這樣的,直接構(gòu)造出新舊方法對應(yīng)的虛擬機數(shù)據(jù)結(jié)構(gòu),然后替換信息寫到內(nèi)存中即可。

Hook 必須掌握的知識

  • 反射

如果你對反射還不是很熟悉的話,建議你先復(fù)習(xí)一下 java 反射的相關(guān)知識。

動態(tài)代理是指在運行時動態(tài)生成代理類,不需要我們像靜態(tài)代理那個去手動寫一個個的代理類。在 java 中,我們可以使用 InvocationHandler 實現(xiàn)動態(tài)代理。

本文的主要內(nèi)容是講解單個進程的 Hook,以及怎樣 Hook。


Hook 使用實例

Hook 選擇的關(guān)鍵點

  • Hook 的選擇點:盡量靜態(tài)變量和單例,因為一旦創(chuàng)建對象,它們不容易變化,非常容易定位。

  • Hook 過程:

    • 尋找 Hook 點,原則是盡量靜態(tài)變量或者單例對象,盡量 Hook public 的對象和方法。

    • 選擇合適的代理方式,如果是接口可以用動態(tài)代理。

    • 偷梁換柱——用代理對象替換原始對象。

  • Android 的 API 版本比較多,方法和類可能不一樣,所以要做好 API 的兼容工作。

簡單案例一: 使用 Hook 修改 View.OnClickListener 事件

首先,我們先分析 View.setOnClickListener 源碼,找出合適的 Hook 點。可以看到 OnClickListener 對象被保存在了一個叫做 ListenerInfo 的內(nèi)部類里,其中 mListenerInfo 是 View 的成員變量。ListeneInfo 里面保存了 View 的各種監(jiān)聽事件。因此,我們可以想辦法 hook ListenerInfo 的 mOnClickListener 。

public?void?setOnClickListener(@Nullable?OnClickListener?l)?{????if?(!isClickable())?{
????????setClickable(true);
????}
????getListenerInfo().mOnClickListener?=?l;
}static?class?ListenerInfo?{

?????---????ListenerInfo?getListenerInfo()?{????????if?(mListenerInfo?!=?null)?{????????????return?mListenerInfo;
????????}
????????mListenerInfo?=?new?ListenerInfo();????????return?mListenerInfo;
????}
????
????---
}

接下來,讓我們一起來看一下怎樣 Hook View.OnClickListener 事件?

大概分為三步:

  • 第一步:獲取 ListenerInfo 對象

從 View 的源代碼,我們可以知道我們可以通過 getListenerInfo 方法獲取,于是,我們利用反射得到 ListenerInfo 對象

  • 第二步:獲取原始的 OnClickListener事件方法

從上面的分析,我們知道 OnClickListener 事件被保存在 ListenerInfo 里面,同理我們利用反射獲取

  • 第三步:偷梁換柱,用 Hook代理類 替換原始的 OnClickListener

public?static?void?hookOnClickListener(View?view)?throws?Exception?{????//?第一步:反射得到?ListenerInfo?對象
????Method?getListenerInfo?=?View.class.getDeclaredMethod("getListenerInfo");
????getListenerInfo.setAccessible(true);
????Object?listenerInfo?=?getListenerInfo.invoke(view);????//?第二步:得到原始的?OnClickListener事件方法
????Class<?>?listenerInfoClz?=?Class.forName("android.view.View$ListenerInfo");
????Field?mOnClickListener?=?listenerInfoClz.getDeclaredField("mOnClickListener");
????mOnClickListener.setAccessible(true);
????View.OnClickListener?originOnClickListener?=?(View.OnClickListener)?mOnClickListener.get(listenerInfo);????//?第三步:用?Hook代理類?替換原始的?OnClickListener
????View.OnClickListener?hookedOnClickListener?=?new?HookedClickListenerProxy(originOnClickListener);
????mOnClickListener.set(listenerInfo,?hookedOnClickListener);
}
public?class?HookedClickListenerProxy?implements?View.OnClickListener?{????private?View.OnClickListener?origin;????public?HookedClickListenerProxy(View.OnClickListener?origin)?{????????this.origin?=?origin;
????}????@Override
????public?void?onClick(View?v)?{
????????Toast.makeText(v.getContext(),?"Hook?Click?Listener",?Toast.LENGTH_SHORT).show();????????if?(origin?!=?null)?{
????????????origin.onClick(v);
????????}
????}
????
}

執(zhí)行以下代碼,將會看到當(dāng)我們點擊該按鈕的時候,會彈出 toast “Hook Click Listener”

mBtn1?=?(Button)?findViewById(R.id.btn_1);
mBtn1.setOnClickListener(this);try?{
????HookHelper.hookOnClickListener(mBtn1);
}?catch?(Exception?e)?{
????e.printStackTrace();
}

簡單案例二: HooK Notification

發(fā)送消息到通知欄的核心代碼如下:

NotificationManager?notificationManager?=?(NotificationManager)?context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(id,?builder.build());

跟蹤 notify 方法發(fā)現(xiàn)最終會調(diào)用到 notifyAsUser 方法

public?void?notify(String?tag,?int?id,?Notification?notification){
????notifyAsUser(tag,?id,?notification,?new?UserHandle(UserHandle.myUserId()));
}

而在 notifyAsUser 方法中,我們驚喜地發(fā)現(xiàn) service 是一個單例,因此,我們可以想方法 hook 住這個 service,而 notifyAsUser 最終會調(diào)用到 service 的 enqueueNotificationWithTag 方法。因此 hook 住 service 的 enqueueNotificationWithTag 方法即可

public?void?notifyAsUser(String?tag,?int?id,?Notification?notification,?UserHandle?user){????//?
????INotificationManager?service?=?getService();
????String?pkg?=?mContext.getPackageName();????//?Fix?the?notification?as?best?we?can.
????Notification.addFieldsFromContext(mContext,?notification);????if?(notification.sound?!=?null)?{
????????notification.sound?=?notification.sound.getCanonicalUri();????????if?(StrictMode.vmFileUriExposureEnabled())?{
????????????notification.sound.checkFileUriExposed("Notification.sound");
????????}
????}
????fixLegacySmallIcon(notification,?pkg);????if?(mContext.getApplicationInfo().targetSdkVersion?>?Build.VERSION_CODES.LOLLIPOP_MR1)?{????????if?(notification.getSmallIcon()?==?null)?{????????????throw?new?IllegalArgumentException("Invalid?notification?(no?valid?small?icon):?"
????????????????????+?notification);
????????}
????}????if?(localLOGV)?Log.v(TAG,?pkg?+?":?notify("?+?id?+?",?"?+?notification?+?")");????final?Notification?copy?=?Builder.maybeCloneStrippedForDelivery(notification);????try?{
????????service.enqueueNotificationWithTag(pkg,?mContext.getOpPackageName(),?tag,?id,
????????????????copy,?user.getIdentifier());
????}?catch?(RemoteException?e)?{????????throw?e.rethrowFromSystemServer();
????}
}private?static?INotificationManager?sService;static?public?INotificationManager?getService(){????if?(sService?!=?null)?{????????return?sService;
????}
????IBinder?b?=?ServiceManager.getService("notification");
????sService?=?INotificationManager.Stub.asInterface(b);????return?sService;
}

綜上,要 Hook ?Notification,大概需要三步:

  • 第一步:得到 NotificationManager 的 sService

  • 第二步:因為 sService 是接口,所以我們可以使用動態(tài)代理,獲取動態(tài)代理對象

  • 第三步:偷梁換柱,使用動態(tài)代理對象 proxyNotiMng 替換系統(tǒng)的 sService

于是,我們可以寫出如下的代碼

public?static?void?hookNotificationManager(final?Context?context)?throws?Exception?{
????NotificationManager?notificationManager?=?(NotificationManager)?context.getSystemService(Context.NOTIFICATION_SERVICE);

????Method?getService?=?NotificationManager.class.getDeclaredMethod("getService");
????getService.setAccessible(true);????//?第一步:得到系統(tǒng)的?sService
????final?Object?sOriginService?=?getService.invoke(notificationManager);

????Class?iNotiMngClz?=?Class.forName("android.app.INotificationManager");????//?第二步:得到我們的動態(tài)代理對象
????Object?proxyNotiMng?=?Proxy.newProxyInstance(context.getClass().getClassLoader(),?new
????????????Class[]{iNotiMngClz},?new?InvocationHandler()?{????????@Override
????????public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)?throws?Throwable?{
????????????Log.d(TAG,?"invoke().?method:"?+?method);
????????????String?name?=?method.getName();
????????????Log.d(TAG,?"invoke:?name="?+?name);????????????if?(args?!=?null?&&?args.length?>?0)?{????????????????for?(Object?arg?:?args)?{
????????????????????Log.d(TAG,?"invoke:?arg="?+?arg);
????????????????}
????????????}
????????????Toast.makeText(context.getApplicationContext(),?"檢測到有人發(fā)通知了",?Toast.LENGTH_SHORT).show();????????????//?操作交由?sOriginService?處理,不攔截通知
????????????return?method.invoke(sOriginService,?args);????????????//?攔截通知,什么也不做
????????????//????????????????????return?null;
????????????//?或者是根據(jù)通知的?Tag?和?ID?進行篩選
????????}
????});????//?第三步:偷梁換柱,使用?proxyNotiMng?替換系統(tǒng)的?sService
????Field?sServiceField?=?NotificationManager.class.getDeclaredField("sService");
????sServiceField.setAccessible(true);
????sServiceField.set(notificationManager,?proxyNotiMng);

}

Hook 使用進階

Hook ClipboardManager

第一種方法

從上面的 hook NotificationManager 例子中,我們可以得知 NotificationManager 中有一個靜態(tài)變量 sService,這個變量是遠端的 service。因此,我們嘗試查找 ClipboardManager 中是不是也存在相同的類似靜態(tài)變量。

查看它的源碼發(fā)現(xiàn)它存在 mService 變量,該變量是在 ClipboardManager 構(gòu)造函數(shù)中初始化的,而 ClipboardManager 的構(gòu)造方法用 @hide 標(biāo)記,表明該方法對調(diào)用者不可見。

而我們知道 ClipboardManager,NotificationManager 其實這些都是單例的,即系統(tǒng)只會創(chuàng)建一次。因此我們也可以認(rèn)為
ClipboardManager 的 mService 是單例的。因此 mService 應(yīng)該是可以考慮 hook 的一個點。

public?class?ClipboardManager?extends?android.text.ClipboardManager?{????private?final?Context?mContext;????private?final?IClipboard?mService;????/**?{@hide}?*/
????public?ClipboardManager(Context?context,?Handler?handler)?throws?ServiceNotFoundException?{
????????mContext?=?context;
????????mService?=?IClipboard.Stub.asInterface(
????????????????ServiceManager.getServiceOrThrow(Context.CLIPBOARD_SERVICE));
????}
}

接下來,我們再來一個看一下 ClipboardManager 的相關(guān)方法 setPrimaryClip , getPrimaryClip

public?void?setPrimaryClip(ClipData?clip)?{????try?{????????if?(clip?!=?null)?{
????????????clip.prepareToLeaveProcess(true);
????????}
????????mService.setPrimaryClip(clip,?mContext.getOpPackageName());
????}?catch?(RemoteException?e)?{????????throw?e.rethrowFromSystemServer();
????}
}/**
?*?Returns?the?current?primary?clip?on?the?clipboard.
?*/public?ClipData?getPrimaryClip()?{????try?{????????return?mService.getPrimaryClip(mContext.getOpPackageName());
????}?catch?(RemoteException?e)?{????????throw?e.rethrowFromSystemServer();
????}
}

可以發(fā)現(xiàn)這些方法最終都會調(diào)用到 mService 的相關(guān)方法。因此,ClipboardManager 的 mService 確實是一個可以 hook 的一個點。

hook ClipboardManager.mService ?的實現(xiàn)

大概需要三個步驟

  • 第一步:得到 ClipboardManager 的 mService

  • 第二步:初始化動態(tài)代理對象

  • 第三步:偷梁換柱,使用 proxyNotiMng 替換系統(tǒng)的 mService

public?static?void?hookClipboardService(final?Context?context)?throws?Exception?{
????ClipboardManager?clipboardManager?=?(ClipboardManager)?context.getSystemService(Context.CLIPBOARD_SERVICE);
????Field?mServiceFiled?=?ClipboardManager.class.getDeclaredField("mService");
????mServiceFiled.setAccessible(true);????//?第一步:得到系統(tǒng)的?mService
????final?Object?mService?=?mServiceFiled.get(clipboardManager);????
????//?第二步:初始化動態(tài)代理對象
????Class?aClass?=?Class.forName("android.content.IClipboard");
????Object?proxyInstance?=?Proxy.newProxyInstance(context.getClass().getClassLoader(),?new
????????????Class[]{aClass},?new?InvocationHandler()?{????????@Override
????????public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)?throws?Throwable?{
????????????Log.d(TAG,?"invoke().?method:"?+?method);
????????????String?name?=?method.getName();????????????if?(args?!=?null?&&?args.length?>?0)?{????????????????for?(Object?arg?:?args)?{
????????????????????Log.d(TAG,?"invoke:?arg="?+?arg);
????????????????}
????????????}????????????if?("setPrimaryClip".equals(name))?{
????????????????Object?arg?=?args[0];????????????????if?(arg?instanceof?ClipData)?{
????????????????????ClipData?clipData?=?(ClipData)?arg;????????????????????int?itemCount?=?clipData.getItemCount();????????????????????for?(int?i?=?0;?i?<?itemCount;?i++)?{
????????????????????????ClipData.Item?item?=?clipData.getItemAt(i);
????????????????????????Log.i(TAG,?"invoke:?item="?+?item);
????????????????????}
????????????????}
????????????????Toast.makeText(context,?"檢測到有人設(shè)置粘貼板內(nèi)容",?Toast.LENGTH_SHORT).show();
????????????}?else?if?("getPrimaryClip".equals(name))?{
????????????????Toast.makeText(context,?"檢測到有人要獲取粘貼板的內(nèi)容",?Toast.LENGTH_SHORT).show();
????????????}????????????//?操作交由?sOriginService?處理,不攔截通知
????????????return?method.invoke(mService,?args);

????????}
????});????//?第三步:偷梁換柱,使用?proxyNotiMng?替換系統(tǒng)的?mService
????Field?sServiceField?=?ClipboardManager.class.getDeclaredField("mService");
????sServiceField.setAccessible(true);
????sServiceField.set(clipboardManager,?proxyInstance);

}

Android Hook 機制之實戰(zhàn)模擬

image

第二種方法

對 Android 源碼有基本了解的人都知道,Android 中的各種 Manager 都是通過 ServiceManager 獲取的。因此,我們可以通過 ServiceManager hook 所有系統(tǒng) Manager,ClipboardManager 當(dāng)然也不例外。

public?final?class?ServiceManager?{????/**
?????*?Returns?a?reference?to?a?service?with?the?given?name.
?????*?
?????*?@param?name?the?name?of?the?service?to?get
?????*?@return?a?reference?to?the?service,?or?<code>null</code>?if?the?service?doesn't?exist
?????*/
????public?static?IBinder?getService(String?name)?{????????try?{
????????????IBinder?service?=?sCache.get(name);????????????if?(service?!=?null)?{????????????????return?service;
????????????}?else?{????????????????return?getIServiceManager().getService(name);
????????????}
????????}?catch?(RemoteException?e)?{
????????????Log.e(TAG,?"error?in?getService",?e);
????????}????????return?null;
????}
}

老套路

  • 第一步:通過反射獲取剪切板服務(wù)的遠程Binder對象,這里我們可以通過 ServiceManager getService 方法獲得

  • 第二步:創(chuàng)建我們的動態(tài)代理對象,動態(tài)代理原來的Binder對象

  • 第三步:偷梁換柱,把我們的動態(tài)代理對象設(shè)置進去

public?static?void?hookClipboardService()?throws?Exception?{????//通過反射獲取剪切板服務(wù)的遠程Binder對象
????Class?serviceManager?=?Class.forName("android.os.ServiceManager");
????Method?getServiceMethod?=?serviceManager.getMethod("getService",?String.class);
????IBinder?remoteBinder?=?(IBinder)?getServiceMethod.invoke(null,?Context.CLIPBOARD_SERVICE);????//新建一個我們需要的Binder,動態(tài)代理原來的Binder對象
????IBinder?hookBinder?=?(IBinder)?Proxy.newProxyInstance(serviceManager.getClassLoader(),????????????new?Class[]{IBinder.class},?new?ClipboardHookRemoteBinderHandler(remoteBinder));????//通過反射獲取ServiceManger存儲Binder對象的緩存集合,把我們新建的代理Binder放進緩存
????Field?sCacheField?=?serviceManager.getDeclaredField("sCache");
????sCacheField.setAccessible(true);????Map<String,?IBinder>?sCache?=?(Map<String,?IBinder>)?sCacheField.get(null);
????sCache.put(Context.CLIPBOARD_SERVICE,?hookBinder);

}
public?class?ClipboardHookRemoteBinderHandler?implements?InvocationHandler?{????private?IBinder?remoteBinder;????private?Class?iInterface;????private?Class?stubClass;????public?ClipboardHookRemoteBinderHandler(IBinder?remoteBinder)?{????????this.remoteBinder?=?remoteBinder;????????try?{????????????this.iInterface?=?Class.forName("android.content.IClipboard");????????????this.stubClass?=?Class.forName("android.content.IClipboard$Stub");
????????}?catch?(Exception?e)?{
????????????e.printStackTrace();
????????}
????}????@Override
????public?Object?invoke(Object?proxy,?Method?method,?Object[]?args)?throws?Throwable?{
????????Log.d("RemoteBinderHandler",?method.getName()?+?"()?is?invoked");????????if?("queryLocalInterface".equals(method.getName()))?{????????????//這里不能攔截具體的服務(wù)的方法,因為這是一個遠程的Binder,還沒有轉(zhuǎn)化為本地Binder對象
????????????//所以先攔截我們所知的queryLocalInterface方法,返回一個本地Binder對象的代理
????????????return?Proxy.newProxyInstance(remoteBinder.getClass().getClassLoader(),????????????????????new?Class[]{this.iInterface},????????????????????new?ClipboardHookLocalBinderHandler(remoteBinder,?stubClass));
????????}????????return?method.invoke(remoteBinder,?args);
????}
}

標(biāo)題名稱:AndroidHook機制之實戰(zhàn)模擬
瀏覽地址:http://chinadenli.net/article20/gphejo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站、虛擬主機網(wǎng)站設(shè)計公司、網(wǎng)站收錄建站公司、搜索引擎優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)
亚洲精品黄色片中文字幕| 激情视频在线视频在线视频| 尹人大香蕉一级片免费看| 狠色婷婷久久一区二区三区| 又黄又色又爽又免费的视频| 国产丝袜美女诱惑一区二区| 久久热麻豆国产精品视频| 日韩欧美国产精品自拍| 亚洲在线观看福利视频| 99久久精品国产麻豆| 欧美黑人在线精品极品| 五月婷婷缴情七月丁香| 欧美日韩一区二区三区色拉拉| 久热人妻中文字幕一区二区| 丝袜诱惑一区二区三区| 亚洲欧洲精品一区二区三区| 欧美黄色黑人一区二区| 婷婷激情五月天丁香社区| 中文字幕日韩一区二区不卡| 久久99这里只精品热在线| 嫩呦国产一区二区三区av| 精品日韩中文字幕视频在线| 欧美黑人暴力猛交精品| 五月情婷婷综合激情综合狠狠 | 大香蕉精品视频一区二区| 国内尹人香蕉综合在线| 欧美一级不卡视频在线观看| 色综合久久中文综合网| 亚洲欧美日本国产有色| 国产一区二区熟女精品免费| 亚洲中文字幕人妻系列| 亚洲中文字幕在线视频频道| 欧美一级日韩中文字幕| 日本免费一区二区三女| 亚洲熟妇熟女久久精品 | 日本 一区二区 在线| 美女被后入视频在线观看| 久久国产精品熟女一区二区三区| 精品国产亚洲免费91| 婷婷基地五月激情五月| 婷婷一区二区三区四区|