微信语音通话并随机写入字节

2018-07-02  本文已影响0人  carrys17

首先需要知道微信语音通话过程中的字节是怎么输入的,可以参考之前的微信保存并发送指定语音 那篇文章,发现语音通话的过程实际上跟语音聊天的字节输入过程相似,只不过是AudioRecord的read方法在语音通话的全过程中一直不断地在写入字节,所以我们的思路就是hook并修改read函数的写入过程,同时为了兼容模拟器,需要hook AudioRecord的其他函数以维持整个过程。

核心代码如下

 // hook  read 方法,当发送指定语音时需要hook这个函数需要在before操作,当录入自己的语音文件时需要在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);
                            // 真机得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];
                                // 赋予随机值
                                new Random().nextBytes(bytes);

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

                            }
                        }

                    });

其他的hook相关函数是为了维持整个通话过程

   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 # 构造方法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: 构造方法 audioSource -- "+audioSource);  // 1
                            Log.i(TAG, "beforeHookedMethod: 构造方法 sampleRateInHz -- "+sampleRateInHz);// 16000
                            Log.i(TAG, "beforeHookedMethod: 构造方法 channelConfig -- "+channelConfig); // 2
                            Log.i(TAG, "beforeHookedMethod: 构造方法 audioFormat -- "+audioFormat); // 2
                            Log.i(TAG, "beforeHookedMethod: 构造方法 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;

                            // 将录音状态置为RECORDSTATE_RECORDING状态
                            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 方法,当发送指定语音时需要hook这个函数
            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: ");

                            // 获取我们在startRecording和Stop中维护的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 方法,当发送指定语音时需要hook这个函数需要在before操作,当录入自己的语音文件时需要在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;

                            // 将录音状态设置为stopped
                            int flag = -1;
                            if (mRecordingFlagMap.get(record) == null || mRecordingFlagMap.get(record) != AudioRecord.RECORDSTATE_STOPPED) {
                                flag = AudioRecord.RECORDSTATE_STOPPED;
                                mRecordingFlagMap.put(record, flag);
                            }
                            //  打断微信,完成发送指定的语音文件
                            Object o = new Object();
                            param.setResult(o);
                        }

                    });


            // hook  release 方法,当发送指定语音时需要hook这个函数,打断微信
            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);
                        }


                    });

     
上一篇下一篇

猜你喜欢

热点阅读