当前位置: 代码迷 >> 综合 >> 通过Xposed框架实现禁用手机录音摄像头功能(hook android 底层实现)
  详细解决方案

通过Xposed框架实现禁用手机录音摄像头功能(hook android 底层实现)

热度:56   发布时间:2023-11-27 00:30:30.0

    还是之前公司的那个需求,为满足客户需要,必须能够远程控制手下手机的相机和录音功能,之前能够使用设备管理器来禁用摄像头,但是毕竟需要手机使用者来手动点击确定激活的选项,这点就不是很美丽,虽然那个点击的操作可以使用自动化服务来实现,但是有点大题小做并且效果还是不理想,所以我使用的禁用android底层相机和录音的api,通过修改android底层代码实现 功能失效,而通过反编译手机自带的相机录音的apk虽然也能够实现失效的效果,但是毕竟这只是一个apk,人家在下载个其他的照相或录音的app,你还是拿人家没有办法,所有相关的应用都会使用Camera、AudioRecord或是MediaRecorder类实现的照相 和 录制语音的功能,让我们查询相关底层代码,修改部分代码就能够一举多得的让所有调用这三个类的所有app都失效啦~

    话不多说直接上代码~ 关于xposed模块配置方面我就不介绍了...不会的同学可以看我的其他帖子或是去google一下,关于那三个类可以在AS上引出这三个包,然后ctri + 左键 点击进去查看源码,里面API介绍的很全面,对于是英文看不懂的同学可以再AS里面装一个自动翻译的插件,我可以推荐一个AS翻译的插件你们可以试试~无网络无法使用哦~网址如下所示点击就能进入(安装教程也讲解的很详细):

点击打开链接


 private void hookCamera(XC_LoadPackage.LoadPackageParam loadPackageParam) {try {XposedHelpers.findAndHookMethod("android.hardware.Camera", loadPackageParam.classLoader, "open", new XC_MethodHook() {@Overrideprotected void afterHookedMethod(MethodHookParam param) throws Throwable {super.afterHookedMethod(param);if (ModelHelper.getGZipModel("Audio.qwer.com","disable").equals("disable")){param.setResult(null);Log.e("pptppt", "试试吧");}}});XposedHelpers.findAndHookMethod("android.hardware.Camera", loadPackageParam.classLoader, "open",int.class, new XC_MethodHook() {@Overrideprotected void afterHookedMethod(MethodHookParam param) throws Throwable {super.afterHookedMethod(param);if (ModelHelper.getGZipModel("Audio.qwer.com","disable").equals("disable")){param.setResult(null);Log.e("pptppt", "试试吧 啊哈哈");}}});} catch (Exception e) {}}

通过阅读Camera 的API 只要禁用掉open方法的返回值就能够实现无法开启摄像头操作,接下来是禁用语音录音功能:

private void hookRecord(XC_LoadPackage.LoadPackageParam loadPackageParam) {try {Class<?> aClass = XposedHelpers.findClass("android.media.MediaRecorder", loadPackageParam.classLoader);XposedBridge.hookAllMethods(aClass, "setOutputFile", new XC_MethodHook() {@Overrideprotected void beforeHookedMethod(MethodHookParam param) throws Throwable {super.beforeHookedMethod(param);if (ModelHelper.getGZipModel("Audio.qwer.com","disable").equals("disable")){param.args[0] = null;Log.e("pptppt", "lalala1");}}});/*********************************************************************************/XposedHelpers.findAndHookMethod("android.media.AudioRecord", loadPackageParam.classLoader, "getState", new XC_MethodHook() {@Overrideprotected void afterHookedMethod(MethodHookParam param) throws Throwable {super.afterHookedMethod(param);if (ModelHelper.getGZipModel("Audio.qwer.com","disable").equals("disable")){param.setResult(0);Log.e("pptppt", "getState");}}});}catch (Exception e){}}

以上是实现禁用录音功能的代码,通过禁用AudioRecord 和 MediaRecorder 类来实现禁用效果。


不知道你们观察出来了没有,在修改参数或返回值的时候,我在外侧都会加一个if判断,读取一个压缩文件中的string字符串,不满足条件的时候在禁止,这样做是为了能够更灵活的实现禁用效果,当不需要禁用的时候就重新写入压缩文件中的内容就可以了~~ 如下是ModelHelper类的代码:

import android.util.Log;import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;public final class ModelHelper {public static final String DIR = "/sdcard/";/*** by kevin 07-03* 解压文件 获得string数据* @param modelName 文件名* @param value 取不到或解压出错时 用来替代的默认数据* @return 返回数据 成功为modelName文件的内容 失败为value默认内容*/public static String getGZipModel(String modelName, String value) {try {File file = new File(DIR + modelName);if (!file.isFile() || !file.exists()) {return value;}byte [] buffer = new byte[10240];GZIPInputStream gis = new GZIPInputStream(new FileInputStream(file));int cnt = gis.read(buffer);gis.close();return new String(buffer, 0, cnt, "utf-8");} catch (Exception e) {e.printStackTrace();return value;}}/*** by kevin 07-03* set cloud.sv 设置数据内容* @param fileName 压缩文件名字* @param value 写入的内容*/public static void setGZipModel(String fileName,String value){try {FileOutputStream fos = new FileOutputStream(DIR + fileName);GZIPOutputStream gos = new GZIPOutputStream(fos);gos.write(value.getBytes());gos.flush();gos.finish();}catch (Exception e){Log.e("qswx", "写入文件内容出错或不存在");}}/*** by kevin 06-20* 读文件的方法* @param modelName 文件名* @param value 没有这个文件或这不是文件的时候 返回的String类型信息* @return 返回的是文件中的数据信息 为String类型*/public static String getModel(String modelName, String value) {try {File file = new File(DIR + modelName);if (!file.isFile() || !file.exists()) {return value;}Reader inputStreamReader = new InputStreamReader(new FileInputStream(file), "UTF-8");String str3 = new BufferedReader(inputStreamReader).readLine();inputStreamReader.close();return str3;} catch (Exception e) {e.printStackTrace();return value;}}/*** by kevin 06-20* 写入String字符串 写入到指定文件中* @param modelName 指定文件的文件名字* @param value 写入到文件的String字符串** BufferedWriter 写入到缓存区* .flush()清空提交 不要忘记写*/public static void setModel(String modelName, String value) {BufferedWriter bufferedWriter = null;try {bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(DIR + modelName), false), "UTF-8"));bufferedWriter.write(value);bufferedWriter.flush();bufferedWriter.close();} catch (Exception e3) {e3.printStackTrace();try {if(bufferedWriter != null) {bufferedWriter.close();}} catch (Exception e5) {}}}
}

比普通的写入文件内容的方式,这种通过加锁解压能够更好的增加文件程序的安全性,这点我就不过多的强调安全这点了,想必大家都知道安全的重要性。过多的xposed模块源码 没人愿意分享的太多,我这也是很小的功能想必有人会失望,hook的能力多少取决于阅读代码的能力,尤其是反编译的代码,多阅读api和反编译的他人项目最好在配上源码会很有作用,有同行的话可以加我qq:1114005726 一起进步  我也是小白~




  相关解决方案