Binder proxy technical solution

Source: Internet
Author: User
Binder proxy technical solution

Author's low-end coders

Time:


0x0

Several friends tried to hook the ioctl of system_process to intercept the IPC communication of the system. The disadvantage of this method is that it is too low-layer. After successful interception, it is more difficult to parse the communication data. in addition, there are also a bunch of compatibility issues, because different Android firmware versions have some modifications to some parcelable structure fields. These changes are assumed to be resolved in IOCTL, all of them need to be taken into account, so I think this method is another step away from productization.

0x1

On Android, nativeservice of all systems is mainly stored in the system_process and COM. Android. Phone processes. For example, we often see activitymanagerservice (AMS ). Most of these nativeservice are Java objects inherited from the binder.

We know that most of IPC communication on Android is implemented through its unique binder module. Therefore, the above Java nativeservice needs to communicate with the kernel, because only C/C ++ can directly interact with the kernel, JNI communication must exist here. For example, the design of AMS:

AMS inherits the binder (a subclass of ibinder, which encapsulates the logic of the public part of IPC communication). In the binder, A mobject field of the int type is saved, this field is the address of the javabbinder object of the C ++ object. This javabbinder is the object that AMS finally communicates with the kernel. The Code is as follows:

Public class binder implements ibinder {//... /* mobject is used by native code, do not remove or rename */private int mobject; // This object stores the javabbinder pointer private iinterface mowner; private string mdescriptor; //...}

Similarly, in javabbinder, A moject of jobject type is also saved, pointing to the upper-layer Java object. Let's look at the javabbinder code:

Class javabbinder: Public bbinder {//... jobject object () const {return mobject ;}//... PRIVATE: JavaVM * const MVM; jobject const mobject; // This saves the reference of AMS };}

Java and C ++ are linked together through these two fields.

Among them, the mobject in javabbinder is a key section of the entire IPC. All client requests first reach javabbinder, then javabbinder calls the exectransact method of mobject through JNI, and finally sends the request to AMS.

Therefore, we only need to find the javabbinder of the AMS object and replace the mobject with the proxy object (recorded as proxybinder, which is the Java object we implement ), binder proxy can be implemented. The following is:

0x2

In the Java layer, to obtain the AMS reference, you can use servicemanager, but this class is a hidden class that can be called only through reflection. You can obtain AMS through servicemanager. getservice ("activity.

In native, to obtain the corresponding javabbinder address of AMS, The getservice method of defaservicservicemanager gets it.

The next step is to replace the mobject object. The mobject object of javabbinder cannot be directly replaced. Since the mobject is const, I wrote a dummyjavabbinder class to handle this problem very easily, the implementation of dummyjavabbinder is as follows:

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;};
0x3

Because binderproxy intercepts a higher level than accept, It is very convenient to parse the request data structure. Most of the interfaces used are framework interfaces, and the compatibility does not exist, the following is a demo I wrote. The demo mainly shows how to prevent a PKG from being killed:

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; static {If (reflecterhelper. setclass (class_name) {s_broadcastintent_code = reflecterhelper. getstaticintvalue ("broadcast_intent_tran Saction ",-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 {/***** public int broadcastintent (iapplicationthread caller, * intent, string re Solvedtype, iintentreceiver resulcode, * int resultcode, string resultdata, bundle map, * string requiredpermission, int appop, Boolean serialized, * Boolean sticky, int userid) throws RemoteException */If (code = s_broadcastintent_code) {pos = data. dataposition (); data. enforceinterface (descriptor); ibinder caller = data. readstrongbinder (); intent = intent. creator. createfromparcel (data ); String resolvedtype = data. readstring (); ibinder resultasks = data. readstrongbinder (); int resultcode = data. readint (); string resultdata = data. readstring (); bundle map = data. readbundle (); string requiredpermission = data. readstring (); int appop = data. readint (); Boolean serialized = data. readint ()! = 0; Boolean sticky = data. readint ()! = 0; int userid = data. readint (); // todo obtains the total number of shards, which are intercepted by the number of shards. // final data is obtained. setdataposition (POS);} return mbinder. transAct (Code, Data, reply, flags );}}
0x4

This technical solution involves injection and Dex loading. There are many online tutorials in this regard. So injection can be used to inject libinject from the archaeological gods, while Java injection can be used to test malokch's "injection android process, and hook the Java World method.

In addition, I can also test my previous series of articles "Attacking Android injection". This series details the entire technical details of so injection and Dex injection into binder proxy.

Demo sample source code I have uploaded to https://github.com/boyliang/Hijack_AMS_broadIntent

Binder proxy technical solution

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.