How high-version Android uses reflection to invoke system-hidden remote services to intercept incoming calls

Source: Internet
Author: User

To intercept Android calls, you have to talk about a method that Android provides to developers in the low version: Endcall (), but since Google later considered that the most important feature for a mobile phone is to call, if the function is simply blocked by people, The security is too poor, so this method is blocked in the higher version of Android and no longer exposes this method in Telephonemanager.


Then our goal is to find a way to call this method, of course, first of all we need to implement a broadcast receiver, to receive the call status change broadcast, which is used in the service to dynamically register the broadcast receiver method to achieve, the main advantage is to facilitate the control of the broadcast receiver's life cycle, Can also have higher permissions than static registrations

private static final String phone = "PHONE";p rivate static final String BOTH = "BOTH";p rivate static final String SMS = "S MS ";p rivate telephonymanager tm;private blacklistdao dao;private incommingcallreceiver callReceiver;private Phonestatelistener listener; @Overridepublic ibinder onbind (Intent Intent) {return null;} @Overridepublic void OnCreate () {super.oncreate (); tm = (Telephonymanager) getsystemservice (telephony_service);d ao = New Blacklistdao (this, 1); callreceiver = new Incommingcallreceiver (); intentfilter filter = new Intentfilter (); Filter.addaction ("Android.intent.action.PHONE_STATE"); Filter.addaction ("Android.provider.Telephony.SMS_ RECEIVED "); filter.setpriority (integer.max_value); listener = new Phonestatelistener () {Private Blacklistitem Blacklistitem; @Overridepublic void oncallstatechanged (int state, String incomingnumber) {super.oncallstatechanged ( State, Incomingnumber), and switch (state) {case telephonymanager.call_state_ringing://if the call is Blacklistitem = Dao.queryitem (IncomingnuMber); if (blacklistitem! = null) {String type = Blacklistitem.gettype (); if ((Both.equals (type) | | Phone.equals (type)) {System.out.println ("Hang Up the Phone"); <strong>hangupcallfromblacklist (incomingnumber);// How to hang up the phone}}break;default:break;}}; Registerreceiver (callreceiver, filter);//Register broadcast recipient}

Unregister the broadcast recipient in the OnDestroy () method of the service:


@Overridepublic void OnDestroy () {Super.ondestroy (); System.out.println ("Close blacklist service"); Unregisterreceiver (callreceiver);//Cancel monitoring Tm.listen (listener, Phonestatelistener.listen_none);//listener = NULL;}


An internal class broadcast receiver that is used to receive broadcast of a phone status change:

/** * Monitor Incoming calls *  * @author Alex *  */private class Incommingcallreceiver extends Broadcastreceiver {private blacklistit EM blacklistitem; @Overridepublic void OnReceive (context context, Intent Intent) {if ("android.intent.action.PHONE_ State ". Equals (Intent.getaction ())) {//If you receive a change in the phone status Tm.listen (Listener, phonestatelistener.listen_call_state);}}


Here we focus on hangupcallfromblacklist (Incomingnumber), which implements the method of suspending the call, where Incomingnumber is the phone number of the caller.

According to my practice, or from the source code of the Android system, because the Endcall method was originally in the telephonemanager, so we might as well from the Telephonemanager method of instantiation Getsystemservice start:



We can find that this method is defined in the Contextwrapper, and Contextwrapper is inherited from the context, we might as well enter into the context of the source to explore:


In the context, we have only found a Getsystemservice abstract method, then how to find the implementation method, in Java, abstract class implementation class general name is the abstract class name after adding a "Impl", So we go to search the source of the Contextimpl.java, found after open discovery:


We find that Getsystemservice actually returns the result of a GetService method for a Servicefetcher object, and let's take a look at the GetService method of Servicefetcher:



Here we can see that in defining a static block, many different service services are registered, and these gerservice methods are called by ServiceManager, and the return value is a IBinder object. Next we can find the ServiceManager location in the file's import package under Android/os:


Since GetService is returning a IBinder object, we can just find the implementation of this getservice method to pass in Telepony_service to get the real Telephonymanager proxy of the remote service binding object , which calls the Endcall method hidden in it.

Fortunately, in Servicemnager.java, we found the implementation of the GetService method:



We can see that the ServiceManager class is also a hidden class, and we can't get the class directly in our code to invoke the GetService method to get the IBinder object, so what do we do?

The only way to handle this is by using reflection:

Class clazz = CallSmsSafeService.class.getClassLoader (). LoadClass ("Android.os.ServiceManager"); method = Clazz.getmethod ("GetService", String.class); IBinder binder = (ibinder) method.invoke (null, Telephony_ SERVICE);
with the above reflection practice, we get the IBinder object corresponding to Telephonymanager, and we need to make use of aidl to invoke the remote method, since it is the IBinder object of the Telephonymanager used, Let's go into the source code of Telephonymanager to see:


We find that in Telephonymanager, a method similar to Getcallstate () basically returns the method called by the return value of Getitelephony (), what is this getitelephy ()?


We find that the return is actually a Itelephony object, and is returned in the form of a call to a remote service method;

We found the location of Itelephony in the head of the file:


Open the above directory, we find that Itelephony is a aidl file, into which we can find the Endcall method:


Since the head of ITELEPHONY.AIDL has the following information:


We want to call the remote service telephony method Endcall () through Aidl, We need to copy the Telehpony.aidl to the new Com.android.internal.telephony package in our project and copy the Android.telephony.NeighboringCellInfo.aidl file to the new Droid.telephony package so that a corresponding Itelephony.java file is automatically generated in Gen. At this point, we can use the following statement to invoke the Endcall method of the remote service:

ITelephony.Stub.asInterface (binder). Endcall ();

Finally, don't forget to include the appropriate permissions in the manifest file:

<!--grant this app control call rights--    <uses-permission android:name= "Android.permission.CALL_PHONE" >      <!-- Grant the app the ability to read the call status--    <uses-permission android:name= "Android.permission.READ_PHONE_STATE" >



How high-version Android uses reflection to invoke system-hidden remote services to intercept incoming calls

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.