微信語音通話并隨機(jī)寫入字節(jié)

首先需要知道微信語音通話過程中的字節(jié)是怎么輸入的,可以參考之前的微信保存并發(fā)送指定語音 那篇文章,發(fā)現(xiàn)語音通話的過程實(shí)際上跟語音聊天的字節(jié)輸入過程相似,只不過是AudioRecord的read方法在語音通話的全過程中一直不斷地在寫入字節(jié),所以我們的思路就是hook并修改read函數(shù)的寫入過程,同時(shí)為了兼容模擬器,需要hook AudioRecord的其他函數(shù)以維持整個(gè)過程。

核心代碼如下

 // hook  read 方法,當(dāng)發(fā)送指定語音時(shí)需要hook這個(gè)函數(shù)需要在before操作,當(dāng)錄入自己的語音文件時(shí)需要在after操作
            XposedHelpers.findAndHookMethod("android.media.AudioRecord",
                    loadPackageParam.classLoader, "read", byte[].class, int.class,
                    int.class, new XC_MethodHook() {
                        @Override
                        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                            Log.i(TAG, "AudioRecord#read beforeHookedMethod: ");

                            int seed = new Random().nextInt(10);
                            Log.i(TAG, "beforeHookedMethod: seed -- "+seed);
                            // 真機(jī)得4以上才有,模擬器1就可以了
                            if(seed > 1){
                                param.setResult(0);
                            }else {

                                byte[] buffer = (byte[]) param.args[0];
                                int off = (int) param.args[1];
                                int size = (int) param.args[2];

                                int min = Math.min(buffer.length - off, size);
                                byte[] bytes = new byte[min];
                                // 賦予隨機(jī)值
                                new Random().nextBytes(bytes);

                                for (int i = 0;i < bytes.length; i++) {
                                    buffer[off + i] = bytes[i];
                                }
                                param.setResult(bytes.length);

                            }
                        }

                    });

其他的hook相關(guān)函數(shù)是為了維持整個(gè)通話過程

   XposedHelpers.findAndHookConstructor("android.media.AudioRecord", loadPackageParam.classLoader,
                    int.class, int.class, int.class, int.class, int.class, new XC_MethodHook() {
                        @Override
                        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                            Log.i(TAG, "AudioRecord # 構(gòu)造方法beforeHookedMethod: ");

                            int audioSource = (int)param.args[0];
                            int sampleRateInHz = (int)param.args[1];
                            int channelConfig = (int)param.args[2];
                            int audioFormat = (int)param.args[3];
                            int bufferSizeInBytes = (int)param.args[4];

                            Log.i(TAG, "beforeHookedMethod: 構(gòu)造方法 audioSource -- "+audioSource);  // 1
                            Log.i(TAG, "beforeHookedMethod: 構(gòu)造方法 sampleRateInHz -- "+sampleRateInHz);// 16000
                            Log.i(TAG, "beforeHookedMethod: 構(gòu)造方法 channelConfig -- "+channelConfig); // 2
                            Log.i(TAG, "beforeHookedMethod: 構(gòu)造方法 audioFormat -- "+audioFormat); // 2
                            Log.i(TAG, "beforeHookedMethod: 構(gòu)造方法 bufferSizeInBytes -- "+bufferSizeInBytes);// 12800  模擬器15360

                            //  修改
                            param.args[0] = 1;
                            param.args[1] = 16000;
                            param.args[2] = 2;
                            param.args[3] = 2;
                            param.args[4] = 12800;

                        }

                    });

            XposedHelpers.findAndHookMethod("android.media.AudioRecord",
                    loadPackageParam.classLoader, "startRecording", new XC_MethodHook() {
                        @Override
                        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                            Log.i(TAG, "AudioRecord#startRecording beforeHookedMethod: ");

                            AudioRecord record = (AudioRecord) param.thisObject;
                            int flag = -1;

                            // 將錄音狀態(tài)置為RECORDSTATE_RECORDING狀態(tài)
                            if (mRecordingFlagMap.get(record) == null || mRecordingFlagMap.get(record) != AudioRecord.RECORDSTATE_RECORDING) {
                                flag = AudioRecord.RECORDSTATE_RECORDING;
                                mRecordingFlagMap.put(record, flag);
                            }

                            // 打斷微信的錄音過程
                            Object o = new Object();
                            param.setResult(o);

                        }

                    });

            // hook  getRecordingState 方法,當(dāng)發(fā)送指定語音時(shí)需要hook這個(gè)函數(shù)
            XposedHelpers.findAndHookMethod("android.media.AudioRecord",
                    loadPackageParam.classLoader, "getRecordingState", new XC_MethodHook() {
                        @Override
                        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                            Log.i(TAG, "AudioRecord#getRecordingState beforeHookedMethod: ");

                            // 獲取我們?cè)趕tartRecording和Stop中維護(hù)的state的值
                            AudioRecord record = (AudioRecord) param.thisObject;
                            int res = mRecordingFlagMap.get(record) == null ? AudioRecord.RECORDSTATE_STOPPED : mRecordingFlagMap.get(record);
                            // 將返回值給微信
                            param.setResult(res);
                            // 清理mRecordFlagMap
                            mRecordingFlagMap.remove(record);

                        }
                    });
   // hook  stop 方法,當(dāng)發(fā)送指定語音時(shí)需要hook這個(gè)函數(shù)需要在before操作,當(dāng)錄入自己的語音文件時(shí)需要在after操作
            XposedHelpers.findAndHookMethod("android.media.AudioRecord",
                    loadPackageParam.classLoader, "stop", new XC_MethodHook() {
                        @Override
                        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                            Log.i(TAG, "AudioRecord#stop beforeHookedMethod: ");

                            AudioRecord record = (AudioRecord) param.thisObject;

                            // 將錄音狀態(tài)設(shè)置為stopped
                            int flag = -1;
                            if (mRecordingFlagMap.get(record) == null || mRecordingFlagMap.get(record) != AudioRecord.RECORDSTATE_STOPPED) {
                                flag = AudioRecord.RECORDSTATE_STOPPED;
                                mRecordingFlagMap.put(record, flag);
                            }
                            //  打斷微信,完成發(fā)送指定的語音文件
                            Object o = new Object();
                            param.setResult(o);
                        }

                    });


            // hook  release 方法,當(dāng)發(fā)送指定語音時(shí)需要hook這個(gè)函數(shù),打斷微信
            XposedHelpers.findAndHookMethod("android.media.AudioRecord", loadPackageParam.classLoader,
                    "release", new XC_MethodHook() {
                        @Override
                        protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                            Log.i(TAG, "AudioRecord#release beforeHookedMethod: ");

                            Object o = new Object();
                            param.setResult(o);
                        }


                    });

     
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 最終目標(biāo): 1、保存發(fā)送的微信語音 2、發(fā)送指定的微信語音 思路: 因?yàn)橐猦ook的是微信語音功能,所以首先要知道...
    carrys17閱讀 5,038評(píng)論 3 7
  • 關(guān)于Mongodb的全面總結(jié) MongoDB的內(nèi)部構(gòu)造《MongoDB The Definitive Guide》...
    中v中閱讀 32,305評(píng)論 2 89
  • 在探討的過程中打亂對(duì)方的思路,讓他跟著我們的思路走,說到心坎里去并覺得有道理,這樣我們就成功了。
    Ding欣欣閱讀 262評(píng)論 0 0
  • 抬頭看天是一種方向,低頭看路是一種清醒;抬頭做事是一種勇氣,低頭做人是一種底氣;抬頭微笑是一種心態(tài),低頭看花是一種...
    風(fēng)雨獨(dú)行人在水一方閱讀 211評(píng)論 0 0

友情鏈接更多精彩內(nèi)容