xposed伪造收到短信
Android 4.4 之后,開發者不能直接往短信數據庫添加短信了,只有系統默認的短信應用才能在收件箱中添加短信,除非將自己的應用設置為默認短信應用,當這種方法不太實用,因為沒有那個用戶愿意修改自己的默認短信應用,即便是臨時的也不靠譜。爬了一堆坑之后勉強找到一個行之有效的方法。
思路
在不改變默認短信的情況下,通過發送廣播,告訴短信應用收到短信了,然后再通過xposed劫持短信內容intent里的參數,將參數修改為系統接收到短信時的參數格式,這樣便能成功偽造短信了。當然,你也可以直接在發送廣播時將系統接收到短信時的參數格式帶進去,但這樣得事先編輯好參數,而且參數內容會非常長,很麻煩,尤其是在終端直接發送廣播時,這種方法就不適用了。
發送廣播
下面開始具體的過程
首先,發送廣播必須通過命令行來發送,直接通過代碼會出現沒有權限的錯誤,并且通過命令行發送前,必須先輸入“su”來獲取root權限,否則短信會接收不到廣播
am broadcast -a android.provider.Telephony.SMS_DELIVER -n com.android.messaging/.receiver.SmsDeliverReceiver //后面接具體參數我這里是先發送廣播給SmsDeliverReceiver 類,因為短信最先接收到廣播的就是這個類,然后才會發送給 receiver.SmsReceiver 類。參數有三個:sender、receiver、message,參數名可以自己定義,分別代表發送人手機號,接收人手機號和短信內容。
xposed劫持
finalClass aClass = XposedHelpers.findClass("com.android.messaging.receiver.SmsReceiver", lpparam.classLoader);XposedBridge.hookAllMethods(aClass,"deliverSmsIntent",newXC_MethodHook() {@Overrideprotected voidbeforeHookedMethod(MethodHookParam param)throwsThrowable {super.beforeHookedMethod(param);Log.e("hock_sms","hookAllMethods--------開始劫持接收到的短信");Intent it = (Intent) param.args[1];byte[] pdu =new byte[0];try{String sender =null;try{sender = it.getStringExtra("sender");}catch(Exception e) {e.printStackTrace();}String receiver =null;try{receiver = it.getStringExtra("receiver");}catch(Exception e) {e.printStackTrace();}String message =null;try{message = it.getStringExtra("message");}catch(Exception e) {return;}pdu = SmsUtils.createPduSms(sender, receiver, message);//將參數轉換為pdu byte數組}catch(Exception e) {e.printStackTrace();}Intent intent =newIntent();intent.setAction(ACTION);Bundle bundle =newBundle();byte[][] b =new byte[1][1];b[0] = pdu;bundle.putString("format","3gpp");bundle.putSerializable("pdus", b);bundle.putString("slot","0");bundle.putString("phone","0");bundle.putString("subscription","2");intent.putExtras(bundle);param.args[1] = intent;}});短信的參數中 "format","slot","phone","subscription" 一般沒什么變化,具體作用沒細究,可以寫死。而最重要的一個參數便是 "pdus",它是一個二維byte數組,其中每個數組代表一條短信,pdus里包含一個或多個pdu byte數組。偽造短信最核心的就是如何將發送人、接收人和短信內容轉化成固定格式的byte數組了,直接采用getByte() 方法是行不通的,必須采用特定格式的方法才行。轉化方式如下:
public static byte[] createPduSms(String sender,String receiver, String body) {//Source: http://stackoverflow.com/a/12338541//Source: http://blog.dev001.net/post/14085892020/android-generate-incoming-sms-from-within-your-appsender =phoneTpye(sender);receiver =phoneTpye(receiver);byte[] pdu =null;byte[] scBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD(receiver);byte[] senderBytes = PhoneNumberUtils.networkPortionToCalledPartyBCD(sender);intlsmcs = scBytes.length;byte[] dateBytes =new byte[7];Calendar calendar =newGregorianCalendar();dateBytes[0] =reverseByte((byte) (calendar.get(Calendar.YEAR)));dateBytes[1] =reverseByte((byte) (calendar.get(Calendar.MONTH) +1));dateBytes[2] =reverseByte((byte) (calendar.get(Calendar.DAY_OF_MONTH)));dateBytes[3] =reverseByte((byte) (calendar.get(Calendar.HOUR_OF_DAY)));dateBytes[4] =reverseByte((byte) (calendar.get(Calendar.MINUTE)));dateBytes[5] =reverseByte((byte) (calendar.get(Calendar.SECOND)));dateBytes[6] =reverseByte((byte) ((calendar.get(Calendar.ZONE_OFFSET) + calendar.get(Calendar.DST_OFFSET)) / (60*1000*15)));try{ByteArrayOutputStream bo =newByteArrayOutputStream();bo.write(lsmcs);bo.write(scBytes);bo.write(0x04);bo.write((byte) sender.length());bo.write(senderBytes);bo.write(0x00);try{String sReflectedClassName ="com.android.internal.telephony.GsmAlphabet";Class cReflectedNFCExtras = Class.forName(sReflectedClassName);Method stringToGsm7BitPacked = cReflectedNFCExtras.getMethod("stringToGsm7BitPacked",newClass[] { String.class});stringToGsm7BitPacked.setAccessible(true);byte[] bodybytes = (byte[]) stringToGsm7BitPacked.invoke(null, body);bo.write(0x00);// encoding: 0 for default 7bitbo.write(dateBytes);bo.write(bodybytes);}catch(Exception e) {try{// try UCS-2byte[] bodybytes =encodeUCS2(body,null);bo.write(0x08);// encoding: 0x08 (GSM_UCS2) for UCS-2bo.write(dateBytes);bo.write(bodybytes);}catch(UnsupportedEncodingException uex) {Log.e(TAG, String.format("String '%s' encode unknow", body));}}pdu = bo.toByteArray();}catch(IOException e) {}returnpdu;}private static bytereverseByte(byteb) {return(byte) ((b &0xF0) >>4| (b &0x0F) <<4);} private staticString phoneTpye(String phone){if(TextUtils.isEmpty(phone)){return"00000000000";}returnphone.length()==11?"+86"+phone:phone;} private static byte[] encodeUCS2(String message,byte[] header)throwsUnsupportedEncodingException {byte[] userData, textPart;textPart = message.getBytes("utf-16be");if(header !=null) {// Need 1 byte for UDHLuserData =new byte[header.length+ textPart.length+1];userData[0] = (byte)header.length;System.arraycopy(header,0, userData,1, header.length);System.arraycopy(textPart,0, userData, header.length+1, textPart.length);}else{userData = textPart;}byte[] ret =new byte[userData.length+1];ret[0] = (byte) (userData.length&0xff);System.arraycopy(userData,0, ret,1, userData.length);returnret;}具體怎么實現的我就不多說了,直接套用就行,只要調用createPduSms() 就可以成功轉化,其他幾個方法只是輔助方法而已。
結束
到此,便可以成功偽造短信了,插件安裝重啟手機后,就可以通過在終端發送廣播或者在應用中通過命令行發送廣播就可以實現偽造接收到短信了。
總結
以上是生活随笔為你收集整理的xposed伪造收到短信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: G1 GC
- 下一篇: 移相全桥变换器参数设计