日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

进击的Android Hook 注入术《五》

發布時間:2025/3/15 Android 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 进击的Android Hook 注入术《五》 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄(?)[-]

  • 繼續
  • BinderProxy
  • 原理
  • 獲取AMS引用
  • 獲取JavaBBinder
  • 替換mObject對象
  • 示例四
  • 最后
  • 繼續

    在Android,幾乎所有的IPC通訊都是通過Binder,可以說Binder在Android中占據著非常重要的地位。IPC通訊一般涉及client和server兩部分,在Android上,所有Binder的serivce部分統稱為NativeService(跟平時所說的Service組件不一樣),一個NativeService可以跟多個client通訊,如果想更詳細地了解這方面的內容可以到老羅的博客睢睢。 在日常開發過程中, 我們經常會使用到的ActivityManager、PackageManager就是一個client的調用,只是本身封裝得比較好,讓你感覺不到。而Service部分的邏輯,主要集中在system_process和com.android.phone這兩個進程里頭。 broadcastIntent是ActivityManagerService(AMS)的一個方法,AMS的宿主進程是system_process,毫無疑問我們需要先注入到system_process進程,至于接下來怎么做呢,正是本章的內容。

    BinderProxy


    原理

    所有NativeService都繼承到IBinder接口,BinderProxy原理很簡單,就是先到找到要代理的NativeService引用,再通過自己編寫的ProxyBinder對象代理NativeService,從而達到截獲IPC通訊的目的。下面我們以AMS為例,做一個說明:

    AMS跟binder進行通訊,是通過JNI實現的。AMS繼承Binder(IBinder的子類,封裝了IPC通訊公共部分的邏輯),Binder里保存著一個類型為int的mObject的字段,這個字段正是其C++對象JavaBBinder對象的地址,這個JavaBBinder才是AMS最終跟內核通訊的對象。代碼如下: [cpp] view plain copy
  • public?class?Binder?implements?IBinder?{??
  • ????//...??
  • ??
  • ????/*?mObject?is?used?by?native?code,?do?not?remove?or?rename?*/??
  • ????private?int?mObject;?//這個對象保存的就是JavaBBinder的指針??
  • ????private?IInterface?mOwner;??
  • ????private?String?mDescriptor;??
  • ??
  • ????//...??
  • }??
  • 同樣的,在JavaBBinder中,也保存著一個類型jobject的mObject,指向上層Java對象??纯碕avaBBinder的代碼: [cpp] view plain copy
  • class?JavaBBinder?:?public?BBinder??
  • {??
  • ??
  • //...??
  • ??
  • ????jobject?object()?const??
  • ????{??
  • ????????return?mObject;??
  • ????}??
  • ??
  • ????//...??
  • ??
  • ????private:??
  • ????????JavaVM*?const???mVM;??
  • ????????jobject?const???mObject;?//這個保存的是AMS的引用??
  • ????};??
  • }??
  • Java和C++就是通過這兩個字段相互連結在一起的。
    其中JavaBBinder中的mObject是整個IPC關鍵的一節,所有的client請求,都是先到達JavaBBinder,然后JavaBBinder再通過JNI調用mObject的execTransact的方法,最終把請求發送到AMS。 因此,我們只要想辦法找到AMS的對象的JavaBBinder,再把mObject替換為代理對象(記作ProxyBinder,一個Java對象的引用),即可實現BinderService代理,下面是示意圖:

    在實現這個代理,我們需要獲取AMS和及對應用的JavaBBinder兩個對象。


    獲取AMS引用

    要獲取AMS引用,通過ServiceManager即可,不過這類是隱藏類,通過反射才可以調用。通過ServiceManager.getService("activity")即可以拿到AMS。

    獲取JavaBBinder

    通過前面的介紹,拿到AMS之后,就可以獲取其mObject字段,這個對象正好就是JavaBBinder的地址。另外,也有一種比較簡單的方式,那就是通過defaultServiceManager的getService方法獲取到。

    替換mObject對象

    JavaBBinder的mObject對象并不能直接替換,因為mObject是const的,我寫了一個DummyJavaBBinder的類,可以很容易地處理好這個問題,DummyJavaBBinder的實現如下: [cpp] view plain copy
  • class?DummyJavaBBinder?:?public?BBinder{??
  • public:??
  • ????virtual?status_t?onTransact(uint32_t?code,?const?Parcel&?data,?Parcel*?reply,?uint32_t?flags?=?0)?{??
  • ????????return?NO_ERROR;??
  • ????}??
  • ??
  • ????jobject?object()?const?{??
  • ????????return?mObject;??
  • ????}??
  • ??
  • ????JavaVM*?javaVM()?const?{??
  • ????????return?mVM;??
  • ????}??
  • ??
  • ????void?changeObj(jobject?newobj){??
  • ????????const?jobject*?p_old_obj?=?&mObject;??
  • ????????jobject*?p_old_obj_noconst?=?const_cast<jobject?*>(p_old_obj);??
  • ????????*p_old_obj_noconst?=?newobj;??
  • ????}??
  • ??
  • private:??
  • ????JavaVM*?const???mVM;??
  • ????jobject?const???mObject;??
  • };??
  • 這個類的作用主要添加了changeObj方法,主要功能是把mObject去掉const限制,并修改為的newobj。

    示例四

    示例四包含三部分代碼,分別是com.demo.sms,com.demo.smstrojan,以及DemonInject3。 com.demo.sms和com.demo.smstrojan的邏輯是一樣的,都是攔截短信,并打印短信內容,代碼片斷如下: [java] view plain copy
  • public?final?class?SmsReceiver?extends?BroadcastReceiver?{??
  • ??
  • ????@Override??
  • ????public?void?onReceive(Context?context,?Intent?intent)?{??
  • ??????????
  • ????????Bundle?bundle?=?intent.getExtras();??
  • ??
  • ????????if?(bundle?!=?null)?{??
  • ????????????this.abortBroadcast();??
  • ??????????????
  • ????????????Object[]?pdus?=?(Object[])?bundle.get("pdus");??
  • ????????????SmsMessage[]?messages?=?new?SmsMessage[pdus.length];??
  • ??
  • ????????????for?(int?i?=?0;?i?<?pdus.length;?i++)?{??
  • ????????????????messages[i]?=?SmsMessage.createFromPdu((byte[])?pdus[i]);??
  • ????????????}??
  • ??
  • ????????????for?(SmsMessage?message?:?messages)?{??
  • ????????????????String?msg?=?message.getMessageBody();??
  • ????????????????String?to?=?message.getOriginatingAddress();??
  • ??????????????????
  • ????????????????Log.i("TTT",?context.getPackageName()?+?"?To:"?+?to?+?"?Msg:"?+?msg);??
  • ????????????}??
  • ????????}??
  • ??????????
  • ????}??
  • ??
  • }??
  • DemoInject3相對復雜,包含dex和proxybinder(被注入的so)兩部分。dex的邏輯是生成代理的proxybinder,并通過invoke返回給lib,lib再通過DummyJavaBBinder修改其mObject為proxybinder,關鍵代碼如下
    dex代碼 [java] view plain copy
  • package?com.demo.inject3;??
  • ??
  • import?android.net.Uri;??
  • import?android.os.Binder;??
  • import?android.os.IBinder;??
  • import?android.os.Parcel;??
  • import?android.os.RemoteException;??
  • import?android.util.Log;??
  • ??
  • /**?
  • ?*??
  • ?*?@author?boyliang?
  • ?*??
  • ?*/??
  • public?final?class?EntryClass?{??
  • ??
  • ????private?static?final?class?ProxyActivityManagerServcie?extends?Binder?{??
  • ????????private?static?final?String?CLASS_NAME?=?"android.app.IActivityManager";??
  • ????????private?static?final?String?DESCRIPTOR?=?"android.app.IActivityManager";??
  • ????????private?static?final?int?s_broadcastIntent_code;??
  • ??
  • ????????private?SmsReceiverResorter?mResorter;??
  • ??
  • ????????static?{??
  • ????????????if?(ReflecterHelper.setClass(CLASS_NAME))?{??
  • ????????????????s_broadcastIntent_code?=?ReflecterHelper.getStaticIntValue("BROADCAST_INTENT_TRANSACTION",?-1);??
  • ????????????}?else?{??
  • ????????????????s_broadcastIntent_code?=?-1;??
  • ????????????}??
  • ????????}??
  • ??
  • ????????private?IBinder?mBinder;??
  • ??
  • ????????public?ProxyActivityManagerServcie(IBinder?binder)?{??
  • ????????????mBinder?=?binder;??
  • ????????????mResorter?=?new?SmsReceiverResorter(binder);??
  • ????????}??
  • ??
  • ????????@Override??
  • ????????protected?boolean?onTransact(int?code,?Parcel?data,?Parcel?reply,?int?flags)?throws?RemoteException?{??
  • ??
  • ????????????if?(code?==?s_broadcastIntent_code)?{??
  • ????????????????mResorter.updatePriority("com.demo.sms");??
  • ????????????}??
  • ??
  • ????????????return?mBinder.transact(code,?data,?reply,?flags);??
  • ????????}??
  • ????}??
  • ??
  • ????public?static?Object[]?invoke(int?i)?{??
  • ????????IBinder?activity_proxy?=?null;??
  • ??
  • ????????try?{??
  • ????????????activity_proxy?=?new?ProxyActivityManagerServcie(ServiceManager.getService("activity"));??
  • ??
  • ????????????Log.i("TTT",?">>>>>>>>>>>>>I?am?in,?I?am?a?bad?boy?3!!!!<<<<<<<<<<<<<<");??
  • ????????}?catch?(Exception?e)?{??
  • ????????????e.printStackTrace();??
  • ????????}??
  • ??
  • ????????return?new?Object[]?{?"activity",?activity_proxy?};??
  • ????}??
  • }??
  • 看到onTransact中code的過濾處理,當code==s_broadcastIntent_code時,證明有client調用了sendBroadcast方法了,然后馬上調用SmsReceiverRestorter中的updatePriority方法。 最后invoke返回的是一個Object數組,分別是"activity"字符串和activity_proxy對象,再看看proxybinder.cpp的中調用invoke方法的處理: [cpp] view plain copy
  • <span?style="white-space:pre">????</span>jmethodID?invoke_method?=?jni_env->GetStaticMethodID(entry_class,?"invoke",?"(I)[Ljava/lang/Object;");??
  • ????check_value(invoke_method);??
  • ??
  • ????jobjectArray?objectarray?=?(jobjectArray)?jni_env->CallStaticObjectMethod(entry_class,?invoke_method,?0);??
  • ????check_value(objectarray);??
  • ??
  • ????jsize?size?=?jni_env->GetArrayLength(objectarray);??
  • ????sp<IServiceManager>?servicemanager?=?defaultServiceManager();??
  • ????for?(jsize?i?=?0;?i?<?size;?i?+=?2)?{??
  • ????????jstring?name?=?static_cast<jstring>(jni_env->GetObjectArrayElement(objectarray,?i));??
  • ????????jobject?obj?=?jni_env->GetObjectArrayElement(objectarray,?i?+?1);??
  • ??
  • ????????const?char*?c_name?=?jni_env->GetStringUTFChars(name,?NULL);??
  • ????????DummyJavaBBinder*?binder?=?(DummyJavaBBinder*)?servicemanager->getService(String16(c_name)).get();??
  • ????????binder->changObj(jni_env->NewGlobalRef(obj));??
  • ????}??
  • lproxybinder.cpp中根據invoke返回的數組進行處理。 至此,整個BinderProxy技術的技術已經介紹完畢了,接下來看看SmsReceiverRestorter的代碼,這個類主要是負責修改廣播的發送順序。跟廣播發送順序有關的變量位置ActivityManagerService.mReceiverResolver.mActionToFilter,其定義如下為private final HashMap<String, ArrayList<IntentFilter>> mActionToFilter。其中key是action,value是各個broadcast中的intentfilter描述,這個value本身是一個List,其順序即為廣播的發送順序,調整這個順序即可,見代碼; [java] view plain copy
  • final?class?SmsReceiverResorter?{??
  • ????private?static?final?String[]?sActions?=?{?"android.provider.Telephony.SMS_RECEIVED",?"android.provider.Telephony.SMS_RECEIVED2",?"android.provider.Telephony.GSM_SMS_RECEIVED"?};??
  • ????private?final?String?TAG?=?"SmsReceiverResorter";??
  • ????private?HashMap<String,?ArrayList<??extends?IntentFilter>>?mActionToFilter;??
  • ????private?Field?mPackageNameField;??
  • ??
  • ????@SuppressWarnings("unchecked")??
  • ????public?SmsReceiverResorter(IBinder?am)?{??
  • ????????Class<?>?claxx?=?am.getClass();??
  • ????????try?{??
  • ????????????Field?field?=?claxx.getDeclaredField("mReceiverResolver");??
  • ????????????field.setAccessible(true);??
  • ????????????Object?mReceiverResolver?=?field.get(am);??
  • ??
  • ????????????claxx?=?mReceiverResolver.getClass();??
  • ??????????????
  • ????????????field?=?claxx.getSuperclass().getDeclaredField("mActionToFilter");??
  • ????????????field.setAccessible(true);??
  • ??
  • ????????????mActionToFilter?=?(HashMap<String,?ArrayList<??extends?IntentFilter>>)?field.get(mReceiverResolver);??
  • ??????????????
  • ????????}?catch?(Exception?e)?{??
  • ????????????Log.e(TAG,?e.toString());??
  • ????????}??
  • ????}??
  • ??
  • ????/**?
  • ?????*?修改優先級?
  • ?????*/??
  • ????public?void?updatePriority(String?target_pkg)?{??
  • ??????????
  • ????????if?(mActionToFilter?!=?null)?{??
  • ??????????????
  • ????????????for?(String?action?:?sActions)?{??
  • ??????????????????
  • ????????????????@SuppressWarnings("unchecked")??
  • ????????????????ArrayList<IntentFilter>?filters?=?(ArrayList<IntentFilter>)?mActionToFilter.get(action);??
  • ??
  • ????????????????if?(filters?!=?null)?{??
  • ????????????????????Log.i("TTT",?"send?sms?broadcast");??
  • ??????????????????????
  • ????????????????????IntentFilter?filter?=?null;??
  • ??
  • ????????????????????for?(IntentFilter?f?:?filters)?{??
  • ????????????????????????String?pkg?=?getPackageName(f);??
  • ????????????????????????if?(target_pkg.equals(pkg))?{??
  • ????????????????????????????filter?=?f;??
  • ????????????????????????????break;??
  • ????????????????????????}???
  • ????????????????????}??
  • ??
  • ????????????????????//?調整順序??
  • ????????????????????if?(filter?!=?null?&&?filters.remove(filter)?)?{??
  • ??????????????????????????
  • ????????????????????????filters.add(0,?filter);??
  • ????????????????????????filter?=?null;??
  • ??????????????????????????
  • ????????????????????????Log.i("TTT",?target_pkg?+?"?is?the?first?now");??
  • ????????????????????}??
  • ????????????????}??
  • ????????????}??
  • ??
  • ????????}??
  • ????}??
  • ??
  • ????private?String?getPackageName(IntentFilter?filter)?{??
  • ??????????
  • ????????if?(mPackageNameField?==?null?&&?filter?!=?null)?{??
  • ????????????Class<?>?claxx?=?filter.getClass();??
  • ????????????try?{??
  • ????????????????mPackageNameField?=?claxx.getDeclaredField("packageName");??
  • ????????????????mPackageNameField.setAccessible(true);??
  • ????????????}?catch?(Exception?e)?{??
  • ????????????????Log.e(TAG,?e.toString());??
  • ????????????}??
  • ????????}??
  • ??????????
  • ????????String?result?=?null;??
  • ??
  • ????????if?(filter?!=?null)?{??
  • ????????????try?{??
  • ????????????????result?=?(String)?mPackageNameField.get(filter);??
  • ????????????}?catch?(Exception?e)?{??
  • ????????????????Log.e(TAG,?e.toString());??
  • ????????????}??
  • ????????}??
  • ??????????
  • ????????return?result;??
  • ????}??
  • }??

  • 最后

    這次的示例代碼有點多,我已經上傳至https://github.com/boyliang/Hijack_AMS_broadIntent。 通過上面的方法,無論com.demo.sms是怎樣落后于sms.demo.smstrojan注冊廣播,都可以最先攔截到短信。
    終于把這個方案講解完了,累死。。。 誰能堅持看到這里,也算是一種緣分吧。 在下一章里,我會全面介紹AIM這個框架的實現細節,AIM框架對前面所提及的技術點做了一個很好的匯總。

    原文地址: http://blog.csdn.net/l173864930/article/details/38468433

    總結

    以上是生活随笔為你收集整理的进击的Android Hook 注入术《五》的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。