Principle of SMS Receiving
About the Android operating system text message receiving and sending the article online there are a lot of, but really clear not much, this blog is well written. In fact, to really understand the Android operating system text message flow, or Linus that sentence: Read the fucking source code. Oh
In the Android operating system, most of the sensitive information transfer process is based on the binder mechanism, of course, SMS is no exception. The description of the receive process for SMS is described from the two levels of the framework layer and the application layer.
- Framework Layer
When the text message arrives at the framework layer, the rilreceiver in Ril will be started to receive the text message, the Rilreceiver use Localsocket to read the text message, and then put the text read in a parcel object, Then call ProcessResponse (Parcel p) to handle the call processunsolicited (Parcel p) in ProcessResponse ().
The corresponding source code for Android OS is as follows:
class rilreceiver implements Runnable { byte[] buffer; Rilreceiver () {buffer =New byte[Ril_max_command_bytes]; } @Override Public voidRun () {intRetryCount =0;Try{ for(;;) {Localsocket s =NULL; Localsocketaddress l;Try{s =NewLocalsocket (); L =NewLocalsocketaddress (Socket_name_ril, LocalSocketAddress.Namespace.RESERVED); S.connect (l); }Catch(IOException ex) {Try{if(s! =NULL) {s.close (); } }Catch(IOException ex2) {//ignore failure to close after failure to connect}//don ' t print a error message after the first time //or after the 8th time if(RetryCount = =8) {RLOG.E (Rilj_log_tag,"couldn ' t find '"+ Socket_name_ril +"' Socket after"+ RetryCount +"Times, continuing to retry silently"); }Else if(RetryCount >0&& RetryCount <8) {RLOG.I (Rilj_log_tag,"couldn ' t find '"+ Socket_name_ril +"' socket; Retrying after timeout "); }Try{Thread.Sleep (Socket_open_retry_millis); }Catch(Interruptedexception er) {} retrycount++;Continue; } RetryCount =0; Msocket = s; RLOG.I (Rilj_log_tag,"Connected to '"+ Socket_name_ril +"' Socket ');intLength =0;Try{InputStream is = Msocket.getinputstream (); for(;;) {Parcel p; Length = Readrilmessage (is, buffer);if(Length <0) {//End-of-stream reached Break; } p = Parcel.obtain (); P.unmarshall (Buffer,0, length); P.setdataposition (0);//rlog.v (Rilj_log_tag, "Read packet:" + length + "bytes");ProcessResponse (P); P.recycle (); } }Catch(Java.io.IOException ex) {RLOG.I (Rilj_log_tag,"'"+ Socket_name_ril +"' Socket closed ', ex); }Catch(Throwable tr) {RLOG.E (Rilj_log_tag,"uncaught exception read length="+ length +"Exception:"+ tr.tostring ()); } rlog.i (Rilj_log_tag,"Disconnected from"+ Socket_name_ril +"' Socket '); Setradiostate (radiostate.radio_unavailable);Try{Msocket.close (); }Catch(IOException ex) {} Msocket =NULL; Rilrequest.resetserial ();//Clear request list on closeClearrequestlist (Radio_not_available,false); }}Catch(Throwable tr) {RLOG.E (Rilj_log_tag,"uncaught exception", TR); }/ * we ' re disconnected so We don ' t know the RIL version * /Notifyregistrantsrilconnectionchanged (-1); } }
- Application Layer
In the app layer, privilegedsmsreceiver after receiving the message to the broadcast, the Smsreceiver start Smsreceiverservice to do the specific processing. The ACTION to receive the text message is sms_received_action, so call handlesmsreceived () processing, use Insertmessage () to insert the text message into the database, here first will determine whether the text message is Class_0 SMS, If it is, it is displayed directly and does not insert the database. If the message is not replaced or inserted into the database, replace the use of smsmessaged Isreplace () method to judge, the principle is the SMS protocol identification Mprotocolidentifier judgment. If neither class_0 SMS nor need to be replaced, insert the SMS into the database and then use Messagingnotification to make a notification in StatusBar to notify the user of the SMS. This is not attached to the Android operating system related code, interested in, you can grepcode or androidxref on their own view.
Encoding implementation
The above has been made clear the principle, the study of the corresponding part of the Android operating system source code, not hard to find a corresponding solution. Here is a simple hook to intercept with the xposed frame. Of course, it is a more effective way to find out after many unsuccessful attempts. The idea is simple, that is, for the function called in the message receiving process, intercept the function, get the information flow at the receiving end, and deal with the information flow by bitwise XOR. The following is the core part of the source code:
PackageCom.example.receiver;ImportDe.robv.android.xposed.IXposedHookLoadPackage;ImportDe.robv.android.xposed.XC_MethodHook;ImportDe.robv.android.xposed.XposedBridge;ImportDe.robv.android.xposed.XposedHelpers;ImportDe.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;/** * @author Li jiansong * @date: 2015-7-27 Morning 11:15:48 * @version : * *server End SMS receiving end of interception, after excessive Attempts, the end result is the following scenario * intercepts the getUserDataUCS2 method of the inner class pduparser of Smsmessage, the method return type is String *string getUserDataUCS2 (int byteCount) * */ Public class recvhooker implements ixposedhookloadpackage{ Private Static FinalString Target_package ="Com.android.mms";@Override Public void Handleloadpackage(Loadpackageparam Lpparam)throwsThrowable {//TODO auto-generated method stub //xposedbridge.log ("--------Loaded app:" +lpparam.packagename);//if (!lpparam.packagename.equals ("Com.android.mms"))//return; if(! Target_package.equals (Lpparam.packagename)) {//XposedBridge.log ("sendrawsmsmod:ignoring package:" + //Lpparam.packagename); return; }// /**//* Intercept the Getuserdata method of Smsmessage's inner class Pduparser,//* byte[] Getuserdata () {}//* This method does not take parameters// *///Final class<?> Recvclazz=xposedhelpers.findclass ("com.android.internal.telephony.gsm"// +". Smsmessage$pduparser ", lpparam.classloader);// //XposedBridge.log ("========== begins to enter interception----");// //Xposedhelpers.findandhookmethod (Recvclazz, "Getuserdata",//New Xc_methodhook () {// //@Override//protected void Afterhookedmethod (Methodhookparam param)//throws Throwable {//// TODO auto-generated method Stub////super.beforehookedmethod (param);// //XposedBridge.log ("=========getuserdata is called");//byte[] recvbytesms= (byte[]) param.getresult ();//String strrecvsms= "";//Strrecvsms+=new String (recvbytesms);// ////byte[] Srtbyte = Strrecvsms.getbytes ();////string lsx= "6666666666666666666666666666666666";//Param.setresult (Strrecvsms.getbytes ());////smsmessage msg=new smsmessage ();// //XposedBridge.log ("======== received the SMS content:" +strrecvsms);//return;// }// // // }); //xposedbridge.log ("-------start interception");//Findandhookmethod ("Com.android.internal.telephony.gsm.SmsMessage", Lpparam.classloader,//"GETSUBMITPDU", String.class,//String.class, String.class, Boolean.class, Byte[].class,//Int.class, Int.class, Int.class, New Xc_methodhook () {// // /**//* Intercept Smsmessage's Getsubmitpdu method, which has 5 parameters//* String scaddress,//* String destinationaddress,//* String message,//* Boolean statusreportrequested,//* byte[] Header// * // */// // /**//* Get an sms-submit PDU for a destination address and a message// *//* @param scaddress Service Centre address. Null means use default.//* @return A <code>SubmitPdu</code> containing the encoded SC//* address, if applicable, and the encoded message.//* Returns null on encode error.// *///@Override//protected void Beforehookedmethod (Methodhookparam param)//throws Throwable {//// TODO auto-generated method Stub//// Super.beforehookedmethod (param);//XposedBridge.log ("GETSUBMITPDU is called");//if (param.args[2]==null) {//return;// }//String message= (String) param.args[2];//XposedBridge.log ("======before:sms message:" +message);//SimpleDateFormat df=new SimpleDateFormat ("Yyyy-mm-dd HH:mm:ss");//Message+=df.format (New Date ());//XposedBridge.log ("========after SMS message:" +message);//SUBMITPDU rawpdu=new SUBMITPDU ();////stringtokenizer stringtokenizer=new StringTokenizer (string, delimiters, returndelimiters)//Param.setresult (RAWPDU);//XposedBridge.log ("=============hook replacement Success");// //return;// // }// });//Final class<?> Recvclazz=xposedhelpers.findclass ("com.android.internal.telephony.gsm"// +". Smsmessage$pduparser ", lpparam.classloader);XposedBridge.log ("========= begins to intercept."); Xposedhelpers.findandhookmethod ("COM.ANDROID.INTERNAL.TELEPHONY.GSM"+". Smsmessage$pduparser ", Lpparam.classloader,"GetUserDataUCS2",int. class,NewXc_methodhook () {/** * Interprets the user data payload as UCS2 characters, and * decodes them into a String. * * @param byteCount The number of bytes in the User data payload * @retur N a String with the decoded characters * / /** * Intercepts the GetUserDataUCS2 method of Smsmessage's inner class Pduparser, which returns a type of String * string getUserDataUCS2 (int ByteCount) * * / @Override protected void Afterhookedmethod(Methodhookparam param)throwsThrowable {//TODO auto-generated method stub //Super.afterhookedmethod (param); Try{string strmms= (String) Param.getresult (); XposedBridge.log ("=========before:"+STRMMS);//string after= "666666666666666"; Char[] Recvarray=strmms.tochararray (); for(intI=0; i<recvarray.length;i++) {recvarray[i]= (Char) (recvarray[i]^20000); } String encodesms=NewString (Recvarray); Param.setresult (encodesms); XposedBridge.log ("=========after:"+param.getresult ());//return;}Catch(Exception e) {//TODO auto-generated catch block //e.printstacktrace ();XposedBridge.log (e); } } }); }}
Test
Here is a test example, send a text message to 10086, 10086 automatically give the response information. Because the response information is intercepted, so the display is garbled. From the background of the log can be seen complete the original normal text message information.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Block SMS reception of Android operating system with xposed framework