Android 环境检测

环境检测:

一、HOOK环境


1、检测frida的特征:
进程/proc/self/fd/目录,寻找是否存在关键字 linjector
/data/local/tmp/下是否存在re.frida.server

    public static boolean isFridaInjected() {
        boolean back = false;
        try {
            String files = ToolUtil.getFiles("/proc/self/fd/");
            if (files != null && files.length() > 0 && files.contains("linjector")) {
                DeviceRiskMgr.sb.append("发现Frida特征: /proc/self/fd/ linjector");
                back = true;
            }
            files = ToolUtil.getFiles("/data/local/tmp/");
            if (files != null && files.length() > 0 && files.contains("re.frida.server")) {
                DeviceRiskMgr.sb.append("发现Frida特征: /data/local/tmp/ re.frida.server");
                back = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false; // 未发现Frida特征
    }
2、检测Xposed特征:

方法1:检测下列文件或文件路径是否存在:
"/sbin/.magisk/modules/riru_lsposed","/data/adb/lspd","/sbin/.magisk/modules/zygisk_lsposed","/sbin/.magisk/modules/riru_edxposed","/data/misc/riru/modules/edxp","/data/adb/riru/modules/edxp.prop","/sbin/.magisk/modules/taichi","/data/misc/taichi","/sbin/.magisk/modules/dreamland","/data/misc/riru/modules/dreamland","/data/adb/riru/modules/dreamland","/system/bin/app_process.orig","/system/xposed.prop","/system/framework/XposedBridge.jar","libxposed_art.so","libxposed_art.so",".no_orig","/system/lib64/","libxposed_art.so","/system/lib64/","libxposed_art.so",".no_orig","/system/bin/app_process_zposed","/system/framework/ZposedBridge.jar","/system/lib/","libzposed_art.so"

方法2:Hook loadClass加载类,检查程序加载的Class中是否包含名为de.robv.android.xposed.XposedBridge的类名路径。

方法3:遍历/data/data/目录,寻找有无以下包名:
de.robv.android.xposed.installer #Xposed框架 
org.meowcat.edxposed.manager #EdXposed框架
com.tsng.hidemyapplist #隐藏应用列表
com.tsng.hidemyroot #隐藏Root
org.lsposed.manager #LSPosed框架
me.weishu.exp #VirtualXposed 太极
top.canyie.dreamland.manager #VirtualXposed 夢境
io.va.exposed #VirtualXposed 夢境    
io.va.exposed64 #VirtualXposed 夢境    
io.virtualapp #VirtualApp    
io.virtualapp.sandvxposed64 #VirtualApp
   public static boolean isXposed() {
        boolean back = false;
        try {
            List<String> files = Arrays.asList("/sbin/.magisk/modules/riru_lsposed", "/data/adb/lspd", "/sbin/.magisk/modules/zygisk_lsposed", "/sbin/.magisk/modules/riru_edxposed", "/data/misc/riru/modules/edxp", "/data/adb/riru/modules/edxp.prop", "/sbin/.magisk/modules/taichi", "/data/misc/taichi", "/sbin/.magisk/modules/dreamland", "/data/misc/riru/modules/dreamland", "/data/adb/riru/modules/dreamland", "/system/bin/app_process.orig", "/system/xposed.prop", "/system/framework/XposedBridge.jar", "/system/lib/libxposed_art.so", "/system/lib/.no_orig", "/system/lib64/libxposed_art.so", "/system/lib64/.no_orig", "/system/bin/app_process_zposed", "/system/framework/ZposedBridge.jar", "/system/lib/libzposed_art.so");
            if (ToolUtil.checkFiles("xpose", files)) back = true;
            files = Arrays.asList("de.robv.android.xposed.installer", "org.meowcat.edxposed.manager", "com.tsng.hidemyapplist", "com.tsng.hidemyroot", "org.lsposed.manager", "me.weishu.exp", "top.canyie.dreamland.manager", "io.va.exposed", "io.va.exposed64", "io.virtualapp", "io.virtualapp.sandvxposed64");
            if (ToolUtil.isRunningApk(context, files)) back = true;
        } catch (Exception e) {
            ToolUtil.Log(e.getMessage());
        }
        return back;
    }

二、机型和系统判定


​​​​​​
1、检测是否是lineageOS系统,这个sdk主要的检测方法是:
  1、查找是否存在特征文件:
   /system/framework/org.lineageos.platform.jar
   /system/framework/org.lineageos.hardware.jar
  2、检测systemprop中是否存在:ro.lineage.build.version
2、检测是否是OpenHarmony系统,检测方法是:
  检测systemprop中是否存在:ro.build.ohos.devicetype
3、检测品牌机系统和设备能否对应,检测方法是:
  遍历/system/framework/下所有以.jar结尾的文件名称,与机型字符串进行比较(strcasestr比较,不区分大小写)
  例如在vivo手机内,/system/framework/下存在以下文件,文件名中包含vivo:

    public static boolean isModel_System() {
        boolean back = false;
        try {
            //1、检测是否是lineageOS系统,
            String files = ToolUtil.getFiles("/system/framework/");
            if (files != null && files.length() > 0 && files.contains("org.lineageos.platform.jar")) {
                sb.append("存在特征文件/system/framework/org.lineageos.platform.jar\n");
                sb.append("检测是lineageOS系统\n");
            }
            if (files != null && files.length() > 0 && files.contains("org.lineageos.hardware.jar")) {
                sb.append("存在特征文件/system/framework/org.lineageos.hardware.jar\n");
                sb.append("检测是lineageOS系统\n");
            }
            if (ToolUtil.isProp("device model identification", "ro.lineage.build.version"))
                back = true;
            //2、检测是否是OpenHarmony系统
            if (ToolUtil.isProp("system identification", "ro.build.ohos.devicetype"))
                back = true;
            //3.
            boolean isBrand = false;
            String brand = Build.MANUFACTURER.toLowerCase();
            List<String> jarFiles = ToolUtil.getJarFiles("/system/framework/");
            for (String jarFile : jarFiles) {
                if (ToolUtil.containsBrand(jarFile, brand)) {
                    isBrand = true;
                }
            }
            if (!isBrand) {
                DeviceRiskMgr.sb.append("机型:" + brand + "\n");
                DeviceRiskMgr.sb.append("未在/system/framework/下发现有关机型的以.jar结尾的文件名称\n");
                back = true;
            }
        } catch (Exception e) {
            ToolUtil.Log(e.getMessage());
        }
        return back;
    }
三、截图工具和模拟点击工具



  1.检测运行的服务中是否存在minicap、minitouch、stfservice、minitouchagent、stfagent、testminicap关键字。
  2.检查/data/local/tmp/有无以下文件或文件目录:

   "minicap.so","minicap","minitouch","mini","mini/minicap","oat/arm64/scrcpy-server.odex","vysor.pwd","mobile_info.properties","tc/mobileagent","tc/input3.sh","tc/mainputjar7","com.cyjh.mobileanjian.id","com.cyjh.mobileanjianen.id","juejinAzykb/","minicap.so","juejinAzykb/TouchService.jar","mqc-scrcpy.jar","uiautomator-stub.jar","cloudtestig/cloudscreen","cloudtesting/touchserver","txysvr.apk","yijianwanservice.apk","screen-shread10x64.so","screen-shread5x32.so","maxpresent.jar","libtxysvr.so"

  3.检查应用安装列表
    检查有没有安装下列模拟点击的应用:

"com.cygery.repetitouch.pro","com.cyjh.mobileanjian","com.touchsprite.android","com.cjzs123.zhushou","com.touchspriteent.android","com.zidongdianji","org.autojs.autojspro","org.autojs.autojs","com.zdanjian.zdanjian","com.zdnewproject","com.ifengwoo.zyjdkj","com.angel.nrzs","com.cyjh.mobileanjian.vip","com.shumai.shudaxia","fun.tooling.clicker.cn","com.dianjiqi","com.miaodong.autoactionssss","com.mxz.wxautojiafujinderen","com.touchelf.app","com.stardust.scriptdroid","com.adinall.autoclick","com.i_cool.auto_clicker","com.kongshan.aidianji","com.xptech.catclicker","com.tingniu.autoclick","com.yicu.yichujifa","com.smallyin.autoclick","com.ksxkq.autoclick","com.x2.clicker","com.scott.autoclickhelper","com.auyou.auyouwzs",

    检查有没有安装下列截图应用:
    "com.github.uiautomator","com.github.uiautomator2","com.sigma_rt.totalcontrol","com.genymobile.scrcpy"

  public static boolean isTool() {
        boolean Back = false;
        try {
            //1.检测运行的服务中是否存在minicap、minitouch、stfservice、minitouchagent、stfagent、testminicap关键字。
            List<String> packges = ToolUtil.getPackges(context);
            if (packges != null && packges.size() > 0) {
                String s = packges.toString();
                List<String> keywords = Arrays.asList("minicap", "minitouch", "stfservice", "minitouchagent", "stfagent", "testminicap");
                for (String re : keywords) {
                    if (s.contains(re)) {
                        sb.append("检测运行的服务中是否存在" + re + "关键字\n");
                        Back = true;
                    }
                }
            }
            //2.检查/data/local/tmp/有无以下文件或文件目录:
            List<String> file = Arrays.asList("minicap.so", "minicap", "minitouch", "mini", "mini/minicap", "oat/arm64/scrcpy-server.odex", "vysor.pwd", "mobile_info.properties", "tc/mobileagent", "tc/input3.sh", "tc/mainputjar7", "com.cyjh.mobileanjian.id", "com.cyjh.mobileanjianen.id", "juejinAzykb/", "minicap.so", "juejinAzykb/TouchService.jar", "mqc-scrcpy.jar", "uiautomator-stub.jar", "cloudtestig/cloudscreen", "cloudtesting/touchserver", "txysvr.apk", "yijianwanservice.apk", "screen-shread10x64.so", "screen-shread5x32.so", "maxpresent.jar", "libtxysvr.so");
            for (int i = 0; i < file.size(); i++)
                file.set(i, "/data/local/tmp/" + file.get(i));
            if (ToolUtil.checkFiles("tool", file))
                Back = true;
            //3.检查应用安装列表
            //检查有没有安装下列模拟点击的应用
            List<String> list = Arrays.asList("com.cygery.repetitouch.pro", "com.cyjh.mobileanjian", "com.touchsprite.android", "com.cjzs123.zhushou", "com.touchspriteent.android", "com.zidongdianji", "org.autojs.autojspro", "org.autojs.autojs", "com.zdanjian.zdanjian", "com.zdnewproject", "com.ifengwoo.zyjdkj", "com.angel.nrzs", "com.cyjh.mobileanjian.vip", "com.shumai.shudaxia", "fun.tooling.clicker.cn", "com.dianjiqi", "com.miaodong.autoactionssss", "com.mxz.wxautojiafujinderen", "com.touchelf.app", "com.stardust.scriptdroid", "com.adinall.autoclick", "com.i_cool.auto_clicker", "com.kongshan.aidianji", "com.xptech.catclicker", "com.tingniu.autoclick", "com.yicu.yichujifa", "com.smallyin.autoclick", "com.ksxkq.autoclick", "com.x2.clicker", "com.scott.autoclickhelper", "com.auyou.auyouwzs");
            if (ToolUtil.isRunningApk(context, list)) {
                sb.append("检测到模拟点击应用\n");
            }
            // 检查有没有安装下列截图应用:
            list = Arrays.asList("com.github.uiautomator", "com.github.uiautomator2", "com.sigma_rt.totalcontrol", "com.genymobile.scrcpy");
            if (ToolUtil.isRunningApk(context, list)) {
                sb.append("检测到截图应用\n");
            }
        } catch (Exception e) {
            ToolUtil.Log(e.getMessage());
        }
        return Back;
    }

 

四、模拟器

​​​​
   扫描常见的模拟器特征,主要检测的方法是:
   1、是否存在以下文件目录:
   "/system/bin/ldinit","/system/bin/ldmountsf","/system/lib/libldutils.so","/system/bin/microvirt-prop","/system/lib/libdroid4x.so","/system/bin/windroyed","/system/lib/libnemuVMprop.so","/system/bin/microvirtd","/system/bin/nox-prop","/system/lib/libnoxspeedup.so","/data/property/persist.nox.simulator_version","/data/misc/profiles/ref/com.bignox.google.installer","/data/misc/profiles/ref/com.bignox.app.store.hd","/system/bin/ttVM-prop","/system/bin/droid4x-prop","/system/bin/duosconfig","/system/etc/xxzs_prop.sh","/system/etc/mumu-configs/device-prop-configs/mumu.config","/boot/bstsetup.env","/boot/bstmods","/system/xbin/bstk","/data/bluestacks.prop","/data/data/com.anrovmconfig","/data/data/com.bluestacks.appmart","/data/data/com.bluestacks.home","/data/data/com.microvirt.market","/dev/nemuguest","/data/data/com.microvirt.toolst","/data/data/com.mumu.launcher","/data/data/com.mumu.store","/data/data/com.netease.mumu.cloner","/system/bin/bstshutdown","/sys/module/bstinput","/sys/class/misc/bstXqpb","/system/phoenixos","/xbin/phoenix_compat","/init.dundi.rc","/system/etc/init.dundi.sh","/data/data/com.ddmnq.dundidevhelper","/init.andy.cloud.rc","/system/bin/xiaopiVM-prop","/system/bin/XCPlayer-prop","/system/lib/liblybox_prop.so","/system/bin/tencent_virtual_input","/vendor/bin/init.tencent.sh","/data/youwave_id","/dev/vboxguest","/dev/vboxuser","/sys/bus/pci/drivers/vboxguest","/sys/class/bdi/vboxsf-c","/sys/class/misc/vboxguest","/sys/class/misc/vboxuser","/sys/devices/virtual/bdi/vboxsf-c","/sys/devices/virtual/misc/vboxguest","/sys/devices/virtual/misc/vboxuser","/sys/module/vboxguest","/sys/module/vboxsf","/sys/module/vboxvideo","/system/bin/androVM-vbox-sf","/system/bin/androVM_setprop","/system/bin/get_androVM_host","/system/bin/mount.vboxsf","/system/etc/init.androVM.sh","/system/etc/init.buildroid.sh","/system/lib/vboxguest.ko","/system/lib/vboxsf.ko","/system/lib/vboxvideo.ko","/system/xbin/mount.vboxsf","/dev/goldfish_pipe","/sys/devices/virtual/misc/goldfish_pipe","/sys/module/goldfish_audio","/sys/module/goldfish_battery","/sys/module/kvm_intel/","/sys/module/kvm_amd/","/init.android_x86_64.rc","/init.android_x86.rc","/init.androidVM_x86.rc","/init.intel.rc","/init.vbox2345_x86.rc"

   2、system.prop下是否存在以下字段特征:
   "init.svc.microvirtd","bst.version","ro.phoenix.version.code","ro.phoenix.version.codename","init.svc.droid4x","microvirt.memu_version","microvirt.imsi","microvirt.simserial","ro.px.version.build","ro.phoenix.os.branch","init.svc.su_kpbs_daemon","init.svc.noxd","init.svc.ttVM_x86-setup","init.svc.xxkmsg","ro.bild.remixos.version","microvirt.mut","init.svc.ldinit","sys.tencent.os_version","sys.tencent.android_id","ro.genymotion.version","init.svc.pkVM_x86-setup","ro.andy.version","ro.build.version.release","ro.product.model","ro.product.brand","ro.boot.bootloader","ro.build.version.securitypatch","ro.build.version.incremental","gsm.version.baseband","gsm.version.ril-impl","ro.build.fingerprint","ro.build.description","ro.build.product","ro.boot.vbmeta.digest","ro.hardware","ro.product.name","ro.product.board","ro.recovery_id","ro.expect.recovery_id","ro.board.platform","ro.product.manufacturer","ro.product.device","sys.usb.state","ro.setupwizard.mode","ro.build.id","ro.build.tags","ro.build.type","ro.debuggable",

   3.检查挂载点,是否存在以下目录:
   "/mnt/shared/Sharefolder","/tiantian.conf","/data/share1","/hardware_device.conf","/mnt/shared/products","/mumu_hardware.conf","/Andy.conf","/mnt/windows/BstSharedFolder","/bst.conf","/mnt/shared/Applications","/ld.conf"

   检查挂载点,检查/proc/mounts中是否存在vboxsf字段.
   4.检查是否安装了虚拟机软件:
   1.VMOS虚拟机
  方法1:运行服务查找:tomq_MANAGER_SERVICE
  方法2:ROOT_DIR查找VMOS_SYS_NUM
  方法3:/proc/self/root/data/data/查找包名:“com.vmos.app”、“com.vmos.pro”、     “com.vmos.ggp”
  方法4:props查找:vmprop.androidid、vmprop.dev_ashmem、vmprop.ip、ro.vmos.simplest.rom
  2.X8沙箱
  方法1:props查找:ro.x8.version、ro.x8.uuid
  方法2:查找文件目录:/x8/config/root.pkg.blacklist、/x8/config/full_vm是否存在
  3.51虚拟机
  /proc/self/root/data/data/查找包名:“com.f1player”、“com.f1player.play”
  4.虚拟精灵和虚拟大师
  /proc/self/root/data/data/查找包名:com.pspace.vandroid、com.yiqiang.xmaster

 public static boolean isSimulator() {
        boolean back = false;
        try {
            //是否存在以下文件目录:
            List<String> Mult_File = Arrays.asList("/x8/config/root.pkg.blacklist", "/x8/config/full_vm", "/system/bin/ldinit", "/system/bin/ldmountsf", "/system/lib/libldutils.so", "/system/bin/microvirt-prop", "/system/lib/libdroid4x.so", "/system/bin/windroyed", "/system/lib/libnemuVMprop.so", "/system/bin/microvirtd", "/system/bin/nox-prop", "/system/lib/libnoxspeedup.so", "/data/property/persist.nox.simulator_version", "/data/misc/profiles/ref/com.bignox.google.installer", "/data/misc/profiles/ref/com.bignox.app.store.hd", "/system/bin/ttVM-prop", "/system/bin/droid4x-prop", "/system/bin/duosconfig", "/system/etc/xxzs_prop.sh", "/system/etc/mumu-configs/device-prop-configs/mumu.config", "/boot/bstsetup.env", "/boot/bstmods", "/system/xbin/bstk", "/data/bluestacks.prop", "/data/data/com.anrovmconfig", "/data/data/com.bluestacks.appmart", "/data/data/com.bluestacks.home", "/data/data/com.microvirt.market", "/dev/nemuguest", "/data/data/com.microvirt.toolst", "/data/data/com.mumu.launcher", "/data/data/com.mumu.store", "/data/data/com.netease.mumu.cloner", "/system/bin/bstshutdown", "/sys/module/bstinput", "/sys/class/misc/bstXqpb", "/system/phoenixos", "/xbin/phoenix_compat", "/init.dundi.rc", "/system/etc/init.dundi.sh", "/data/data/com.ddmnq.dundidevhelper", "/init.andy.cloud.rc", "/system/bin/xiaopiVM-prop", "/system/bin/XCPlayer-prop", "/system/lib/liblybox_prop.so", "/system/bin/tencent_virtual_input", "/vendor/bin/init.tencent.sh", "/data/youwave_id", "/dev/vboxguest", "/dev/vboxuser", "/sys/bus/pci/drivers/vboxguest", "/sys/class/bdi/vboxsf-c", "/sys/class/misc/vboxguest", "/sys/class/misc/vboxuser", "/sys/devices/virtual/bdi/vboxsf-c", "/sys/devices/virtual/misc/vboxguest", "/sys/devices/virtual/misc/vboxuser", "/sys/module/vboxguest", "/sys/module/vboxsf", "/sys/module/vboxvideo", "/system/bin/androVM-vbox-sf", "/system/bin/androVM_setprop", "/system/bin/get_androVM_host", "/system/bin/mount.vboxsf", "/system/etc/init.androVM.sh", "/system/etc/init.buildroid.sh", "/system/lib/vboxguest.ko", "/system/lib/vboxsf.ko", "/system/lib/vboxvideo.ko", "/system/xbin/mount.vboxsf", "/dev/goldfish_pipe", "/sys/devices/virtual/misc/goldfish_pipe", "/sys/module/goldfish_audio", "/sys/module/goldfish_battery", "/sys/module/kvm_intel/", "/sys/module/kvm_amd/", "/init.android_x86_64.rc", "/init.android_x86.rc", "/init.androidVM_x86.rc", "/init.intel.rc", "/init.vbox2345_x86.rc");
            //sb.append("\n是否存在以下文件目录:");
            if (ToolUtil.checkFiles("simulator", Mult_File))
                back = true;
            //system.prop下是否存在以下字段特征:
            List<String> Mult_Prop = Arrays.asList("vmprop.androidid", "vmprop.dev_ashmem", "vmprop.ip", "ro.vmos.simplest.rom", "ro.x8.version", "ro.x8.uuid", "init.svc.microvirtd", "bst.version", "ro.phoenix.version.code", "ro.phoenix.version.codename", "init.svc.droid4x", "microvirt.memu_version", "microvirt.imsi", "microvirt.simserial", "ro.px.version.build", "ro.phoenix.os.branch", "init.svc.su_kpbs_daemon", "init.svc.noxd", "init.svc.ttVM_x86-setup", "init.svc.xxkmsg", "ro.bild.remixos.version", "microvirt.mut", "init.svc.ldinit", "sys.tencent.os_version", "sys.tencent.android_id", "ro.genymotion.version", "init.svc.pkVM_x86-setup", "ro.andy.version", "ro.build.version.release", "ro.product.model", "ro.product.brand", "ro.boot.bootloader", "ro.build.version.securitypatch", "ro.build.version.incremental", "gsm.version.baseband", "gsm.version.ril-impl", "ro.build.fingerprint", "ro.build.description", "ro.build.product", "ro.boot.vbmeta.digest", "ro.hardware", "ro.product.name", "ro.product.board", "ro.recovery_id", "ro.expect.recovery_id", "ro.board.platform", "ro.product.manufacturer", "ro.product.device", "sys.usb.state", "ro.setupwizard.mode", "ro.build.id", "ro.build.tags", "ro.build.type", "ro.debuggable");
            // sb.append("\nsystem.prop下是否存在以下字段特征:");
            if (ToolUtil.checkProps("simulator", Mult_Prop))
                back = true;
            //3.检查挂载点,是否存在以下目录:
            //检查挂载点,检查/proc/mounts中是否存在vboxsf字段.
            List<String> list = Arrays.asList("/mnt/shared/Sharefolder", "/tiantian.conf", "/data/share1", "/hardware_device.conf", "/mnt/shared/products", "/mumu_hardware.conf", "/Andy.conf", "/mnt/windows/BstSharedFolder", "/bst.conf", "/mnt/shared/Applications", "/ld.conf");
            if (ToolUtil.checkFiles("simulator", list)) back = true;
            String files1 = ToolUtil.getFiles("/proc/mounts");
            if (files1 != null && files1.length() > 0 && files1.contains("vboxsf")) {
                sb.append("检查/proc/mounts中是否存在vboxsf字段\n");
                back = true;

            }
            // 4.检查是否安装了虚拟机软件:
            String files = ToolUtil.getFiles("/proc/self/root/data/data/");
            if (files != null && files.length() > 0) {
                List<String> list1 = Arrays.asList("com.vmos.app", "com.vmos.pro", "com.vmos.ggp");
                for (String re : list1)
                    if (files.contains(re)) {
                        sb.append("发现与VMOS虚拟机相关包名:" + re + "\n");
                        back = true;
                    }
            }
            if (files != null && files.length() > 0) {
                List<String> list1 = Arrays.asList("com.f1player", "com.f1player.play");
                for (String re : list1)
                    if (files.contains(re)) {
                        sb.append("发现与51虚拟机相关包名:" + re + "\n");
                        back = true;
                    }
            }
            if (files != null && files.length() > 0) {
                List<String> list1 = Arrays.asList("com.pspace.vandroid", "com.yiqiang.xmaster");
                for (String re : list1)
                    if (files.contains(re)) {
                        sb.append("发现与虚拟精灵和虚拟大师相关包名:" + re + "\n");
                        back = true;
                    }
            }
        } catch (Exception e) {
            ToolUtil.Log(e.getMessage());
        }
        return back;
    }
五、改机软件 1.检测是否安装了改机软件: 检查包名是否存在:

"com.yztc.studio.plugin","com.soft.apk008v","com.uwish.app","zpp.wjy.xxsq","com.bigsing.changer","zap.fh.wipe","com.sollyu.xposed.hook.model","com.soft.apk008Tool","com.doubee.ig","com.variable.apkhook","com.addeasy.fastest","com.xenice.mask","com.shyl.artifact","com.android1500.androidfaker"

2.检查/dev/wgzs目录下的内容是否存在,若存在则获取值: "wg.cust.config.phone.id","wg.cust.s_android_id","wg.cust.sys.prop.filter","wg.cust.config.phone.imeimackey","wg.cust.config.phone.imei","wg.cust.config.pkg.name","wg.cust.destUids"

 public static boolean isModification() {
        boolean back = false;
        try {
            List<String> list = Arrays.asList("com.yztc.studio.plugin", "com.soft.apk008v", "com.uwish.app", "zpp.wjy.xxsq", "com.bigsing.changer", "zap.fh.wipe", "com.sollyu.xposed.hook.model", "com.soft.apk008Tool", "com.doubee.ig", "com.variable.apkhook", "com.addeasy.fastest", "com.xenice.mask", "com.shyl.artifact", "com.android1500.androidfaker");
            if (ToolUtil.isRunningApk(context, list)) {
                back = true;
            }
            list = Arrays.asList("wg.cust.config.phone.id", "wg.cust.s_android_id", "wg.cust.sys.prop.filter", "wg.cust.config.phone.imeimackey", "wg.cust.config.phone.imei", "wg.cust.config.pkg.name", "wg.cust.destUids");
            String files = ToolUtil.getFiles("/dev/wgzs/");
            if (files != null && files.length() > 0)
                for (String re : list) {
                    if (files.contains(re)) {
                        back = true;
                        sb.append("检查/dev/wgzs目录存在参数:" + re + "\n");
                    }
                }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return back;
    }
六、Root和Root工具 1.包名检测,遍历/data/data/目录,寻找有无以下包名:

"com.topjohnwu.magisk","eu.chainfire.supersu","com.noshufou.android.su","com.noshufou.android.su.elite","com.koushikdutta.superuser","com.thirdparty.superuser","com.yellowes.su","com.fox2code.mmm","io.github.vvb2060.magisk","com.kingroot.kinguser","com.kingo.root","com.smedialink.oneclickroot","com.zhiqupk.root.global","com.alephzain.framaroot","io.github.huskydg.magisk","me.weishu.kernelsu"

2.检查su文件是否存在 "/su/bin/su","/sbin/su","/data/local/xbin/su","/data/local/bin/su","/data/local/su","/system/xbin/su","/system/bin/su","/system/sd/xbin/su","/system/bin/failsafe/su","/system/bin/.ext/.su","/system/etc/.installed_su_daemon","/system/etc/.has_su_daemon","/system/xbin/sugote","/system/xbin/sugote-mksh","/system/xbin/supolicy","/system/etc/init.d/99SuperSUDaemon","/system/.supersu","/product/bin/su","/apex/com.android.runtime/bin/su","/apex/com.android.art/bin/su","/system_ext/bin/su","/system/xbin/bstk/su","/system/app/SuperUser/SuperUser.apk","/system/app/Superuser.apk","/system/xbin/mu_bak","/odm/bin/su","/vendor/bin/su","/vendor/xbin/su","/system/bin/.ext/su","/system/usr/we-need-root/su","/cache/su","/data/su","/dev/su","/system/bin/cph_su","/dev/com.koushikdutta.superuser.daemon","/system/xbin/daemonsu","/sbin/.mianju","/sbin/nvsu","/system/bin/.hid/su","/system/addon.d/99-magisk.sh"

3.检查magisk相关文件是否存在 "/cache/.disable_magisk","/dev/magisk/img","/sbin/.magisk","/cache/magisk.log","/data/adb/magisk","/system/etc/init/magisk","/system/etc/init/magisk.rc","/data/magisk.apk"

4.检测Android PATH环境变量,检测path路径下是否存在“/su”

5.检测 /proc/self/maps中的内容

1、检测 /proc/self/maps 是否存在名为“/memfd:/jit-cache”的段(加载zygisk模块时(也就是liblspd.so)的时候会讲其名称设置为jit-cache,这样的话so的内存段在maps中就是/memfd:/jit-cache)

2、通过检测map表是否存在匿名的并且具有可执行属性的内存判断是否存在lsposed

3、检测栈空间[stack]的权限是否为“rw-p”

6.检测ro.build.tags的值,读取 /system/build.prop并检测ro.build.tags的值是否为“test-keys”

7.检测seLinux安全上下文,cat /proc/%d/attr/prev检测app进程的selinux安全上下文是否为“u:r:zygote:s0”

8.检查/data/local/tmp/有无以下文件 shizuku shizuku_starter

  public static boolean isRoot() {
        boolean back = false;
        try {
            //1.包名检测,遍历/data/data/目录,寻找有无以下包名:
            List<String> list = Arrays.asList("com.topjohnwu.magisk", "eu.chainfire.supersu", "com.noshufou.android.su", "com.noshufou.android.su.elite", "com.koushikdutta.superuser", "com.thirdparty.superuser", "com.yellowes.su", "com.fox2code.mmm", "io.github.vvb2060.magisk", "com.kingroot.kinguser", "com.kingo.root", "com.smedialink.oneclickroot", "com.zhiqupk.root.global", "com.alephzain.framaroot", "io.github.huskydg.magisk", "me.weishu.kernelsu");
            if (ToolUtil.isRunningApk(context, list)) back = true;
            //2.检查su文件是否存在
            list = Arrays.asList("/su/bin/su", "/sbin/su", "/data/local/xbin/su", "/data/local/bin/su", "/data/local/su", "/system/xbin/su", "/system/bin/su", "/system/sd/xbin/su", "/system/bin/failsafe/su", "/system/bin/.ext/.su", "/system/etc/.installed_su_daemon", "/system/etc/.has_su_daemon", "/system/xbin/sugote", "/system/xbin/sugote-mksh", "/system/xbin/supolicy", "/system/etc/init.d/99SuperSUDaemon", "/system/.supersu", "/product/bin/su", "/apex/com.android.runtime/bin/su", "/apex/com.android.art/bin/su", "/system_ext/bin/su", "/system/xbin/bstk/su", "/system/app/SuperUser/SuperUser.apk", "/system/app/Superuser.apk", "/system/xbin/mu_bak", "/odm/bin/su", "/vendor/bin/su", "/vendor/xbin/su", "/system/bin/.ext/su", "/system/usr/we-need-root/su", "/cache/su", "/data/su", "/dev/su", "/system/bin/cph_su", "/dev/com.koushikdutta.superuser.daemon", "/system/xbin/daemonsu", "/sbin/.mianju", "/sbin/nvsu", "/system/bin/.hid/su", "/system/addon.d/99-magisk.sh");
            if (ToolUtil.checkFiles("root su", list))
                back = true;
            //3.检查magisk相关文件是否存在
            list = Arrays.asList("/cache/.disable_magisk", "/dev/magisk/img", "/sbin/.magisk", "/cache/magisk.ToolUtil.Log", "/data/adb/magisk", "/system/etc/init/magisk", "/system/etc/init/magisk.rc", "/data/magisk.apk");
            if (ToolUtil.checkFiles("root magisk", list))
                back = true;
            //4.检测Android PATH环境变量,检测path路径下是否存在“/su”
            if (new File("/path/su").exists()) {
                sb.append("检测path路径下存在/su\n");
                back = true;
            }
            // * 6.检测ro.build.tags的值,读取 /system/build.prop并检测ro.build.tags的值是否为“test-keys”
            String property = System.getProperty("ro.build.tags");
            if (property != null && "test-keys".equals(property)) {
                sb.append("检测检测ro.build.tags的值为test-keys\n");
                back = true;
            }
            //8.检查/data/local/tmp/有无以下文件
            list = Arrays.asList("/data/local/tmp/shizuku", "/data/local/tmp/shizuku");
            if (ToolUtil.checkFiles("root data", list))
                back = true;
        } catch (Exception e) {
            ToolUtil.Log(e.getMessage());
        }
        return back;
    }
检测手机是否刷了面具
  public static boolean isMagisk() {
        boolean back = false;
        try {
            ShellUtils.CommandResult commandResult = ShellUtils.execCommand("command -v magisk", true);
            System.out.println("isMagisk:" + commandResult.toString());
            back = (commandResult.successMsg != null && commandResult.successMsg.contains("magisk"));
            if (back) {
                sb.append("command -v magisk: " + commandResult.successMsg + "\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return back;
    }
检测是否解锁了BL锁
  public static boolean isBlOpen() {
        boolean back = false;
        try {
            //getprop ro.boot.flash.locked
            ShellUtils.CommandResult commandResult = ShellUtils.execCommand("getprop ro.boot.flash.locked", true);
            System.out.println("ro.boot.flash.locked:" + commandResult.toString());
            back = "0".equals(commandResult.successMsg);
            if (back) {
                sb.append("ro.boot.flash.locked=0\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return back;
    }
是否selinux处于宽容模式
    public static boolean isSELinuxInPermissiveMode() {
        boolean back = false;
        try {
            ShellUtils.CommandResult commandResult = ShellUtils.execCommand("getenforce", true);
            // "permissive" 表示 SELinux 处于宽容模式
            back = "Permissive".equals(commandResult.successMsg);
            if (back) {
                sb.append("getenforce-Permissive\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return back;
    }
VPN检测
 public static boolean
    isVPN() {
        boolean Back = false;
        try {
            Enumeration<NetworkInterface> niList = NetworkInterface.getNetworkInterfaces();
            if (niList != null) {
                Iterator it = Collections.list(niList).iterator();
                while (it.hasNext()) {
                    NetworkInterface intf = (NetworkInterface) it.next();
                    if (intf.isUp() && intf.getInterfaceAddresses().size() != 0 && ("tun0".equals(intf.getName()) || "ppp0".equals(intf.getName()))) {
                        ToolUtil.Log("Risk has been detected", "VPN InterfaceAddresses " + intf.getName());
                        sb.append("检测到可疑参数:" + intf.getName() + "\n");
                        return true;
                    }
                }
            }
            return false;
        } catch (Exception e) {
            ToolUtil.Log(e.getMessage());
            return false;
        }
    }
是否开启代理
 public static boolean isWifiProxy() {
        try {
            String proxyAddress;
            int proxyPort;
            boolean IS_ICS_OR_LATER = Build.VERSION.SDK_INT >= 14;
            if (IS_ICS_OR_LATER) {
                proxyAddress = System.getProperty("http.proxyHost");
                String portStr = System.getProperty("http.proxyPort");
                proxyPort = Integer.parseInt(portStr != null ? portStr : "-1");
            } else {
                proxyAddress = Proxy.getHost(context);
                proxyPort = Proxy.getPort(context);
            }
            boolean b = ((TextUtils.isEmpty(proxyAddress) || proxyPort == -1) ? false : true);
            if (b) {
                ToolUtil.Log("openProxy", "WifiProxy proxyAddress=" + proxyAddress + "\tproxyPort=" + proxyPort);
                sb.append("检测到可疑IP:" + String.format("ip=%s.prot=%s", proxyAddress, proxyPort) + "\n");
            }
            return b;
        } catch (Exception e) {
            ToolUtil.Log(e.getMessage());
            return false;
        }
    }
是否应用多开
public static boolean isMulti_Launching_Apps() {
        boolean Back = false;
        try {
            //uid=10000-19999
            String filesdir = context.getFilesDir().getPath();
            int uid = Process.myUid();
            if (!filesdir.startsWith("/data/user/0/")) {
                ToolUtil.Log("multi-launching apps", "filesdir error:" + filesdir);
                sb.append("检测到可疑应用地址:" + filesdir + "\n");
                Back = true;
            }
            if (!(uid >= 10000 && uid <= 19999)) {
                ToolUtil.Log("multi-launching apps", "uid error:" + uid);
                sb.append("检测到可疑进程id:" + uid + "\n");
                Back = true;
            }
        } catch (Exception e) {
            ToolUtil.Log(e.getMessage());
        }
        return Back;
    }
是否开启无障碍服务
  public static boolean isAccessibilitySettingsOn() {
        try {
            int accessibilityEnabled = Settings.Secure.getInt(context.getApplicationContext().getContentResolver(), "accessibility_enabled");
            boolean isopen = (accessibilityEnabled == 1);
            if (isopen) {
                sb.append("检测到accessibility_enabled=1\n");
                ToolUtil.Log("accessiblity", "open accessiblity");
            }
            return isopen;
        } catch (Exception e) {
            ToolUtil.Log(e.getMessage());
            return false;
        }
    }

全部代码如下:
package com.example.risk.util;

import android.content.Context;
import android.util.Log;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class RiskUtils {
    public static StringBuilder sb=new StringBuilder();
    //构造方法
    //com.example.risk.util.RiskUtils   getDeviceRisk  Context
    public static List<String> getDeviceRisk(Context context) {
       // Log.e("Xposed测试:","Xposed测试",new Throwable());
        DeviceRiskMgr.sb=RiskUtils.sb;
        ToolUtil.sb=RiskUtils.sb;
        DeviceRiskMgr.context=context;

        sb.append("检测详情:"+"\n\n");
        List<String> risks = new ArrayList<>();
        if (DeviceRiskMgr.isVPN()) {
            ToolUtil.Log("手机使用了VPN");
            risks.add("vpn");
        }
        if (DeviceRiskMgr.isWifiProxy()) {
            ToolUtil.Log("开启了网络代理");
            risks.add("openProxy");
        }
        if (DeviceRiskMgr.isSimulator()) {
            ToolUtil.Log("检测到模拟器");
            risks.add("simulator");
        }
        if (DeviceRiskMgr.isMulti_Launching_Apps()) {
            ToolUtil.Log("检测到应用多开");
            risks.add("multi-launching apps");
        }
        if (DeviceRiskMgr.isRoot()) {
            ToolUtil.Log("手机已root");
            risks.add("root");
        }
        if (DeviceRiskMgr.isXposed()) {
            ToolUtil.Log("安装了xpose");
            risks.add("xpose");
        }
        if (DeviceRiskMgr.isModel_System()) {
            ToolUtil.Log("机型和系统判定异常");
            risks.add("model_system");
        }
        if (DeviceRiskMgr.isTool()) {
            ToolUtil.Log("截图工具和模拟点击工具");
            risks.add("tool");
        }
        if (DeviceRiskMgr.isAccessibilitySettingsOn()) {
            ToolUtil.Log("开启了无障碍服务");
            risks.add("accessiblity");
        }
        if (DeviceRiskMgr.isFridaInjected()) {
            ToolUtil.Log("发现Frida特征");
            risks.add("frida");
        }
        if (DeviceRiskMgr.isSIM()) {
            ToolUtil.Log("发现SIM有异常");
            risks.add("sim");
        }

        if (DeviceRiskMgr.isModification()) {
            ToolUtil.Log("发现改机软件");
            risks.add("modification");
        }
        if (DeviceRiskMgr.isSELinuxInPermissiveMode()) {
            ToolUtil.Log("selinux处于宽容模式");
            risks.add("selinux");
        }
        if (DeviceRiskMgr.isBlOpen()) {
            ToolUtil.Log("BL已解锁");
            risks.add("blopen");
        }
        if (DeviceRiskMgr.isMagisk()) {
            ToolUtil.Log("找到Magisk");
            risks.add("magisk");
        }


        return risks;
    }
}
package com.example.risk.util;

import android.content.Context;
import android.net.Proxy;
import android.os.Build;
import android.os.Process;
import android.provider.Settings;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;

import com.example.risk.tool.ShellUtils;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class DeviceRiskMgr {
    public static Context context;
    public static StringBuilder sb;

    public DeviceRiskMgr() {
    }

    /**
     环境检测:
     一、HOOK环境
     在libNetHTProtect.so中主要检测了crc校验,还有frida和Xposed的一些特征:
     <p>
     1、检测frida的特征:
     进程/proc/self/fd/目录,寻找是否存在关键字 linjector
     /data/local/tmp/下是否存在re.frida.server
     */
    public static boolean isFridaInjected() {
        boolean back = false;
        try {
            String files = ToolUtil.getFiles("/proc/self/fd/");
            if (files != null && files.length() > 0 && files.contains("linjector")) {
                DeviceRiskMgr.sb.append("发现Frida特征: /proc/self/fd/ linjector");
                back = true;
            }
            files = ToolUtil.getFiles("/data/local/tmp/");
            if (files != null && files.length() > 0 && files.contains("re.frida.server")) {
                DeviceRiskMgr.sb.append("发现Frida特征: /data/local/tmp/ re.frida.server");
                back = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false; // 未发现Frida特征
    }

    /**
     2、检测Xposed特征:
     方法1:检测下列文件或文件路径是否存在:
     "/sbin/.magisk/modules/riru_lsposed","/data/adb/lspd","/sbin/.magisk/modules/zygisk_lsposed","/sbin/.magisk/modules/riru_edxposed","/data/misc/riru/modules/edxp","/data/adb/riru/modules/edxp.prop","/sbin/.magisk/modules/taichi","/data/misc/taichi","/sbin/.magisk/modules/dreamland","/data/misc/riru/modules/dreamland","/data/adb/riru/modules/dreamland","/system/bin/app_process.orig","/system/xposed.prop","/system/framework/XposedBridge.jar","libxposed_art.so","libxposed_art.so",".no_orig","/system/lib64/","libxposed_art.so","/system/lib64/","libxposed_art.so",".no_orig","/system/bin/app_process_zposed","/system/framework/ZposedBridge.jar","/system/lib/","libzposed_art.so"
     方法2:Hook loadClass加载类,检查程序加载的Class中是否包含名为de.robv.android.xposed.XposedBridge的类名路径。
     方法3:遍历/data/data/目录,寻找有无以下包名:
     de.robv.android.xposed.installer #Xposed框架 \\org.meowcat.edxposed.manager #EdXposed框架\\com.tsng.hidemyapplist #隐藏应用列表\\com.tsng.hidemyroot #隐藏Root//org.lsposed.manager #LSPosed框架\\ //me.weishu.exp #VirtualXposed 太极//top.canyie.dreamland.manager #VirtualXposed 夢境 //io.va.exposed #VirtualXposed 夢境    //io.va.exposed64 #VirtualXposed 夢境    //io.virtualapp #VirtualApp    //io.virtualapp.sandvxposed64 #VirtualApp
     */
    public static boolean isXposed() {
        boolean back = false;
        try {
            List<String> files = Arrays.asList("/sbin/.magisk/modules/riru_lsposed", "/data/adb/lspd", "/sbin/.magisk/modules/zygisk_lsposed", "/sbin/.magisk/modules/riru_edxposed", "/data/misc/riru/modules/edxp", "/data/adb/riru/modules/edxp.prop", "/sbin/.magisk/modules/taichi", "/data/misc/taichi", "/sbin/.magisk/modules/dreamland", "/data/misc/riru/modules/dreamland", "/data/adb/riru/modules/dreamland", "/system/bin/app_process.orig", "/system/xposed.prop", "/system/framework/XposedBridge.jar", "/system/lib/libxposed_art.so", "/system/lib/.no_orig", "/system/lib64/libxposed_art.so", "/system/lib64/.no_orig", "/system/bin/app_process_zposed", "/system/framework/ZposedBridge.jar", "/system/lib/libzposed_art.so");
            if (ToolUtil.checkFiles("xpose", files)) back = true;
            files = Arrays.asList("de.robv.android.xposed.installer", "org.meowcat.edxposed.manager", "com.tsng.hidemyapplist", "com.tsng.hidemyroot", "org.lsposed.manager", "me.weishu.exp", "top.canyie.dreamland.manager", "io.va.exposed", "io.va.exposed64", "io.virtualapp", "io.virtualapp.sandvxposed64");
            if (ToolUtil.isRunningApk(context, files)) back = true;
        } catch (Exception e) {
            ToolUtil.Log(e.getMessage());
        }
        return back;
    }

    /**
     * 3、libc的CRC校验
     * 拿到proc/self/maps中libc.so的基地址,并计算ELF文件中.text+.rodata+.eh_frame+.eh_frame_hdr 段的CRC校验值。
     * <p>
     二、机型和系统判定
     1、检测是否是lineageOS系统,这个sdk主要的检测方法是:
       1、查找是否存在特征文件:
        /system/framework/org.lineageos.platform.jar
        /system/framework/org.lineageos.hardware.jar
       2、检测systemprop中是否存在:ro.lineage.build.version
      2、检测是否是OpenHarmony系统,检测方法是:
       检测systemprop中是否存在:ro.build.ohos.devicetype
      3、检测品牌机系统和设备能否对应,检测方法是:
       遍历/system/framework/下所有以.jar结尾的文件名称,与机型字符串进行比较(strcasestr比较,不区分大小写)
       例如在vivo手机内,/system/framework/下存在以下文件,文件名中包含vivo:
     */
    //机型和系统判定
    public static boolean isModel_System() {
        boolean back = false;
        try {
            //1、检测是否是lineageOS系统,
            String files = ToolUtil.getFiles("/system/framework/");
            if (files != null && files.length() > 0 && files.contains("org.lineageos.platform.jar")) {
                sb.append("存在特征文件/system/framework/org.lineageos.platform.jar\n");
                sb.append("检测是lineageOS系统\n");
            }
            if (files != null && files.length() > 0 && files.contains("org.lineageos.hardware.jar")) {
                sb.append("存在特征文件/system/framework/org.lineageos.hardware.jar\n");
                sb.append("检测是lineageOS系统\n");
            }
            if (ToolUtil.isProp("device model identification", "ro.lineage.build.version"))
                back = true;
            //2、检测是否是OpenHarmony系统
            if (ToolUtil.isProp("system identification", "ro.build.ohos.devicetype"))
                back = true;
            //3.
            boolean isBrand = false;
            String brand = Build.MANUFACTURER.toLowerCase();
            List<String> jarFiles = ToolUtil.getJarFiles("/system/framework/");
            for (String jarFile : jarFiles) {
                if (ToolUtil.containsBrand(jarFile, brand)) {
                    isBrand = true;
                }
            }
            if (!isBrand) {
                DeviceRiskMgr.sb.append("机型:" + brand + "\n");
                DeviceRiskMgr.sb.append("未在/system/framework/下发现有关机型的以.jar结尾的文件名称\n");
                back = true;
            }
        } catch (Exception e) {
            ToolUtil.Log(e.getMessage());
        }
        return back;
    }

    /**
     * 三、Bootloader解锁状态
     * 检测bootloader是否已解锁。
     * <p>
     * 方法1:检测props,主要检测项:
     * 1、检测ro.boot.verifiedbootstate的值是否是orange
     * 2、检测ro.secureboot.lockstate的值是否是unlocked
     * 3、检测vendor.boot.vbmeta.device_state的值是否是unlocked
     * 4、检测vendor.boot.verifiedbootstate的值是否是orange
     * 5、检测ro.boot.vbmeta.device_state的值是否是unlocked
     * 6、检测ro.boot.flash.locked的值是否是unlocked
     * 方法2:获取sys.oem_unlock_allowed的值
     * <p>
     * 四、SIM卡
     * 这个可以检测SIM卡是否存在,获取SIM卡的网络类型,SIM卡的ICCID等。
     * <p>
     * 1.检测SIM卡是否存在,这个一般是读取props,获取gsm.sim.state这个的属性
     * <p>
     * 2.获取SIM卡的网络运营商,通过系统服务TELEPHONY_SERVICE,然后调用getSubscriberId获取IMSIString,然后判断前5位:
     * <p>
     * 中国地区的运营商以及对应的号段见下表:
     * 中国移动 :46000,46002,46004,46007,46008
     * 中国联通 :46001,46006,46009,46010
     * 中国电信 :46003,46005,46011,46012
     * 中国广电 :46015
     * 港澳地区:
     * 中国移动(香港) :45412,45413,45430
     * 中国电信(香港) :45407
     * 中国电信(澳门) :45502,45507
     */
    public static boolean isSIM() {
        boolean back = false;
        try {
            Map<String, String> map = new HashMap<String, String>() {
                {
                    put("46000", "中国移动");
                    put("46002", "中国移动");
                    put("46004", "中国移动");
                    put("46008", "中国移动");
                    put("46001", "中国联通");
                    put("46006", "中国联通");
                    put("46009", "中国联通");
                    put("46010", "中国联通");
                    put("46003", "中国电信");
                    put("46005", "中国电信");
                    put("46011", "中国电信");
                    put("46012", "中国电信");
                    put("45412", "中国移动(香港)");
                    put("45413", "中国移动(香港)");
                    put("45430", "中国移动(香港)");
                    put("45407", "中国电信(香港)");
                    put("45502", "中国电信(澳门)");
                    put("45507", "中国电信(澳门)");

                }
            };
            TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            boolean b = telephonyManager.hasIccCard();
            if (b) {
                String substring = telephonyManager.getSimSerialNumber();
                if (map.containsKey(substring)) {
                    DeviceRiskMgr.sb.append("国内运营商:" + substring + "--" + map.get(substring) + "\n");
                } else {
                    DeviceRiskMgr.sb.append("国外运营商:" + substring + "\n");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return back;

    }

    /**
     五、截图工具和模拟点击工具
       1.检测运行的服务中是否存在minicap、minitouch、stfservice、minitouchagent、stfagent、testminicap关键字。
       2.检查/data/local/tmp/有无以下文件或文件目录:
        "minicap.so","minicap","minitouch","mini","mini/minicap","oat/arm64/scrcpy-server.odex","vysor.pwd","mobile_info.properties","tc/mobileagent","tc/input3.sh","tc/mainputjar7","com.cyjh.mobileanjian.id","com.cyjh.mobileanjianen.id","juejinAzykb/","minicap.so","juejinAzykb/TouchService.jar","mqc-scrcpy.jar","uiautomator-stub.jar","cloudtestig/cloudscreen","cloudtesting/touchserver","txysvr.apk","yijianwanservice.apk","screen-shread10x64.so","screen-shread5x32.so","maxpresent.jar","libtxysvr.so"
       3.检查应用安装列表
         检查有没有安装下列模拟点击的应用:
         "com.cygery.repetitouch.pro","com.cyjh.mobileanjian","com.touchsprite.android","com.cjzs123.zhushou","com.touchspriteent.android","com.zidongdianji","org.autojs.autojspro","org.autojs.autojs","com.zdanjian.zdanjian","com.zdnewproject","com.ifengwoo.zyjdkj","com.angel.nrzs","com.cyjh.mobileanjian.vip","com.shumai.shudaxia","fun.tooling.clicker.cn","com.dianjiqi","com.miaodong.autoactionssss","com.mxz.wxautojiafujinderen","com.touchelf.app","com.stardust.scriptdroid","com.adinall.autoclick","com.i_cool.auto_clicker","com.kongshan.aidianji","com.xptech.catclicker","com.tingniu.autoclick","com.yicu.yichujifa","com.smallyin.autoclick","com.ksxkq.autoclick","com.x2.clicker","com.scott.autoclickhelper","com.auyou.auyouwzs",
         检查有没有安装下列截图应用:
         "com.github.uiautomator","com.github.uiautomator2","com.sigma_rt.totalcontrol","com.genymobile.scrcpy"
     */
    //截图工具和模拟点击工具
    public static boolean isTool() {
        boolean Back = false;
        try {
            //1.检测运行的服务中是否存在minicap、minitouch、stfservice、minitouchagent、stfagent、testminicap关键字。
            List<String> packges = ToolUtil.getPackges(context);
            if (packges != null && packges.size() > 0) {
                String s = packges.toString();
                List<String> keywords = Arrays.asList("minicap", "minitouch", "stfservice", "minitouchagent", "stfagent", "testminicap");
                for (String re : keywords) {
                    if (s.contains(re)) {
                        sb.append("检测运行的服务中是否存在" + re + "关键字\n");
                        Back = true;
                    }
                }
            }
            //2.检查/data/local/tmp/有无以下文件或文件目录:
            List<String> file = Arrays.asList("minicap.so", "minicap", "minitouch", "mini", "mini/minicap", "oat/arm64/scrcpy-server.odex", "vysor.pwd", "mobile_info.properties", "tc/mobileagent", "tc/input3.sh", "tc/mainputjar7", "com.cyjh.mobileanjian.id", "com.cyjh.mobileanjianen.id", "juejinAzykb/", "minicap.so", "juejinAzykb/TouchService.jar", "mqc-scrcpy.jar", "uiautomator-stub.jar", "cloudtestig/cloudscreen", "cloudtesting/touchserver", "txysvr.apk", "yijianwanservice.apk", "screen-shread10x64.so", "screen-shread5x32.so", "maxpresent.jar", "libtxysvr.so");
            for (int i = 0; i < file.size(); i++)
                file.set(i, "/data/local/tmp/" + file.get(i));
            if (ToolUtil.checkFiles("tool", file))
                Back = true;
            //3.检查应用安装列表
            //检查有没有安装下列模拟点击的应用
            List<String> list = Arrays.asList("com.cygery.repetitouch.pro", "com.cyjh.mobileanjian", "com.touchsprite.android", "com.cjzs123.zhushou", "com.touchspriteent.android", "com.zidongdianji", "org.autojs.autojspro", "org.autojs.autojs", "com.zdanjian.zdanjian", "com.zdnewproject", "com.ifengwoo.zyjdkj", "com.angel.nrzs", "com.cyjh.mobileanjian.vip", "com.shumai.shudaxia", "fun.tooling.clicker.cn", "com.dianjiqi", "com.miaodong.autoactionssss", "com.mxz.wxautojiafujinderen", "com.touchelf.app", "com.stardust.scriptdroid", "com.adinall.autoclick", "com.i_cool.auto_clicker", "com.kongshan.aidianji", "com.xptech.catclicker", "com.tingniu.autoclick", "com.yicu.yichujifa", "com.smallyin.autoclick", "com.ksxkq.autoclick", "com.x2.clicker", "com.scott.autoclickhelper", "com.auyou.auyouwzs");
            if (ToolUtil.isRunningApk(context, list)) {
                sb.append("检测到模拟点击应用\n");
            }
            // 检查有没有安装下列截图应用:
            list = Arrays.asList("com.github.uiautomator", "com.github.uiautomator2", "com.sigma_rt.totalcontrol", "com.genymobile.scrcpy");
            if (ToolUtil.isRunningApk(context, list)) {
                sb.append("检测到截图应用\n");
            }
        } catch (Exception e) {
            ToolUtil.Log(e.getMessage());
        }
        return Back;
    }

    /**
     六、模拟器
        扫描常见的模拟器特征,主要检测的方法是:
        1、是否存在以下文件目录:
        "/system/bin/ldinit","/system/bin/ldmountsf","/system/lib/libldutils.so","/system/bin/microvirt-prop","/system/lib/libdroid4x.so","/system/bin/windroyed","/system/lib/libnemuVMprop.so","/system/bin/microvirtd","/system/bin/nox-prop","/system/lib/libnoxspeedup.so","/data/property/persist.nox.simulator_version","/data/misc/profiles/ref/com.bignox.google.installer","/data/misc/profiles/ref/com.bignox.app.store.hd","/system/bin/ttVM-prop","/system/bin/droid4x-prop","/system/bin/duosconfig","/system/etc/xxzs_prop.sh","/system/etc/mumu-configs/device-prop-configs/mumu.config","/boot/bstsetup.env","/boot/bstmods","/system/xbin/bstk","/data/bluestacks.prop","/data/data/com.anrovmconfig","/data/data/com.bluestacks.appmart","/data/data/com.bluestacks.home","/data/data/com.microvirt.market","/dev/nemuguest","/data/data/com.microvirt.toolst","/data/data/com.mumu.launcher","/data/data/com.mumu.store","/data/data/com.netease.mumu.cloner","/system/bin/bstshutdown","/sys/module/bstinput","/sys/class/misc/bstXqpb","/system/phoenixos","/xbin/phoenix_compat","/init.dundi.rc","/system/etc/init.dundi.sh","/data/data/com.ddmnq.dundidevhelper","/init.andy.cloud.rc","/system/bin/xiaopiVM-prop","/system/bin/XCPlayer-prop","/system/lib/liblybox_prop.so","/system/bin/tencent_virtual_input","/vendor/bin/init.tencent.sh","/data/youwave_id","/dev/vboxguest","/dev/vboxuser","/sys/bus/pci/drivers/vboxguest","/sys/class/bdi/vboxsf-c","/sys/class/misc/vboxguest","/sys/class/misc/vboxuser","/sys/devices/virtual/bdi/vboxsf-c","/sys/devices/virtual/misc/vboxguest","/sys/devices/virtual/misc/vboxuser","/sys/module/vboxguest","/sys/module/vboxsf","/sys/module/vboxvideo","/system/bin/androVM-vbox-sf","/system/bin/androVM_setprop","/system/bin/get_androVM_host","/system/bin/mount.vboxsf","/system/etc/init.androVM.sh","/system/etc/init.buildroid.sh","/system/lib/vboxguest.ko","/system/lib/vboxsf.ko","/system/lib/vboxvideo.ko","/system/xbin/mount.vboxsf","/dev/goldfish_pipe","/sys/devices/virtual/misc/goldfish_pipe","/sys/module/goldfish_audio","/sys/module/goldfish_battery","/sys/module/kvm_intel/","/sys/module/kvm_amd/","/init.android_x86_64.rc","/init.android_x86.rc","/init.androidVM_x86.rc","/init.intel.rc","/init.vbox2345_x86.rc"
        2、system.prop下是否存在以下字段特征:
        "init.svc.microvirtd","bst.version","ro.phoenix.version.code","ro.phoenix.version.codename","init.svc.droid4x","microvirt.memu_version","microvirt.imsi","microvirt.simserial","ro.px.version.build","ro.phoenix.os.branch","init.svc.su_kpbs_daemon","init.svc.noxd","init.svc.ttVM_x86-setup","init.svc.xxkmsg","ro.bild.remixos.version","microvirt.mut","init.svc.ldinit","sys.tencent.os_version","sys.tencent.android_id","ro.genymotion.version","init.svc.pkVM_x86-setup","ro.andy.version","ro.build.version.release","ro.product.model","ro.product.brand","ro.boot.bootloader","ro.build.version.securitypatch","ro.build.version.incremental","gsm.version.baseband","gsm.version.ril-impl","ro.build.fingerprint","ro.build.description","ro.build.product","ro.boot.vbmeta.digest","ro.hardware","ro.product.name","ro.product.board","ro.recovery_id","ro.expect.recovery_id","ro.board.platform","ro.product.manufacturer","ro.product.device","sys.usb.state","ro.setupwizard.mode","ro.build.id","ro.build.tags","ro.build.type","ro.debuggable",
        3.检查挂载点,是否存在以下目录:
        "/mnt/shared/Sharefolder","/tiantian.conf","/data/share1","/hardware_device.conf","/mnt/shared/products","/mumu_hardware.conf","/Andy.conf","/mnt/windows/BstSharedFolder","/bst.conf","/mnt/shared/Applications","/ld.conf"
        检查挂载点,检查/proc/mounts中是否存在vboxsf字段.
        4.检查是否安装了虚拟机软件:
        1.VMOS虚拟机
       方法1:运行服务查找:tomq_MANAGER_SERVICE
       方法2:ROOT_DIR查找VMOS_SYS_NUM
       方法3:/proc/self/root/data/data/查找包名:“com.vmos.app”、“com.vmos.pro”、“com.vmos.ggp”
       方法4:props查找:vmprop.androidid、vmprop.dev_ashmem、vmprop.ip、ro.vmos.simplest.rom
       2.X8沙箱
       方法1:props查找:ro.x8.version、ro.x8.uuid
       方法2:查找文件目录:/x8/config/root.pkg.blacklist、/x8/config/full_vm是否存在
       3.51虚拟机
       /proc/self/root/data/data/查找包名:“com.f1player”、“com.f1player.play”
       4.虚拟精灵和虚拟大师
       /proc/self/root/data/data/查找包名:com.pspace.vandroid、com.yiqiang.xmaster
     */
//是否模拟器 OK
    public static boolean isSimulator() {
        boolean back = false;
        try {
            //是否存在以下文件目录:
            List<String> Mult_File = Arrays.asList("/x8/config/root.pkg.blacklist", "/x8/config/full_vm", "/system/bin/ldinit", "/system/bin/ldmountsf", "/system/lib/libldutils.so", "/system/bin/microvirt-prop", "/system/lib/libdroid4x.so", "/system/bin/windroyed", "/system/lib/libnemuVMprop.so", "/system/bin/microvirtd", "/system/bin/nox-prop", "/system/lib/libnoxspeedup.so", "/data/property/persist.nox.simulator_version", "/data/misc/profiles/ref/com.bignox.google.installer", "/data/misc/profiles/ref/com.bignox.app.store.hd", "/system/bin/ttVM-prop", "/system/bin/droid4x-prop", "/system/bin/duosconfig", "/system/etc/xxzs_prop.sh", "/system/etc/mumu-configs/device-prop-configs/mumu.config", "/boot/bstsetup.env", "/boot/bstmods", "/system/xbin/bstk", "/data/bluestacks.prop", "/data/data/com.anrovmconfig", "/data/data/com.bluestacks.appmart", "/data/data/com.bluestacks.home", "/data/data/com.microvirt.market", "/dev/nemuguest", "/data/data/com.microvirt.toolst", "/data/data/com.mumu.launcher", "/data/data/com.mumu.store", "/data/data/com.netease.mumu.cloner", "/system/bin/bstshutdown", "/sys/module/bstinput", "/sys/class/misc/bstXqpb", "/system/phoenixos", "/xbin/phoenix_compat", "/init.dundi.rc", "/system/etc/init.dundi.sh", "/data/data/com.ddmnq.dundidevhelper", "/init.andy.cloud.rc", "/system/bin/xiaopiVM-prop", "/system/bin/XCPlayer-prop", "/system/lib/liblybox_prop.so", "/system/bin/tencent_virtual_input", "/vendor/bin/init.tencent.sh", "/data/youwave_id", "/dev/vboxguest", "/dev/vboxuser", "/sys/bus/pci/drivers/vboxguest", "/sys/class/bdi/vboxsf-c", "/sys/class/misc/vboxguest", "/sys/class/misc/vboxuser", "/sys/devices/virtual/bdi/vboxsf-c", "/sys/devices/virtual/misc/vboxguest", "/sys/devices/virtual/misc/vboxuser", "/sys/module/vboxguest", "/sys/module/vboxsf", "/sys/module/vboxvideo", "/system/bin/androVM-vbox-sf", "/system/bin/androVM_setprop", "/system/bin/get_androVM_host", "/system/bin/mount.vboxsf", "/system/etc/init.androVM.sh", "/system/etc/init.buildroid.sh", "/system/lib/vboxguest.ko", "/system/lib/vboxsf.ko", "/system/lib/vboxvideo.ko", "/system/xbin/mount.vboxsf", "/dev/goldfish_pipe", "/sys/devices/virtual/misc/goldfish_pipe", "/sys/module/goldfish_audio", "/sys/module/goldfish_battery", "/sys/module/kvm_intel/", "/sys/module/kvm_amd/", "/init.android_x86_64.rc", "/init.android_x86.rc", "/init.androidVM_x86.rc", "/init.intel.rc", "/init.vbox2345_x86.rc");
            //sb.append("\n是否存在以下文件目录:");
            if (ToolUtil.checkFiles("simulator", Mult_File))
                back = true;
            //system.prop下是否存在以下字段特征:
            List<String> Mult_Prop = Arrays.asList("vmprop.androidid", "vmprop.dev_ashmem", "vmprop.ip", "ro.vmos.simplest.rom", "ro.x8.version", "ro.x8.uuid", "init.svc.microvirtd", "bst.version", "ro.phoenix.version.code", "ro.phoenix.version.codename", "init.svc.droid4x", "microvirt.memu_version", "microvirt.imsi", "microvirt.simserial", "ro.px.version.build", "ro.phoenix.os.branch", "init.svc.su_kpbs_daemon", "init.svc.noxd", "init.svc.ttVM_x86-setup", "init.svc.xxkmsg", "ro.bild.remixos.version", "microvirt.mut", "init.svc.ldinit", "sys.tencent.os_version", "sys.tencent.android_id", "ro.genymotion.version", "init.svc.pkVM_x86-setup", "ro.andy.version", "ro.build.version.release", "ro.product.model", "ro.product.brand", "ro.boot.bootloader", "ro.build.version.securitypatch", "ro.build.version.incremental", "gsm.version.baseband", "gsm.version.ril-impl", "ro.build.fingerprint", "ro.build.description", "ro.build.product", "ro.boot.vbmeta.digest", "ro.hardware", "ro.product.name", "ro.product.board", "ro.recovery_id", "ro.expect.recovery_id", "ro.board.platform", "ro.product.manufacturer", "ro.product.device", "sys.usb.state", "ro.setupwizard.mode", "ro.build.id", "ro.build.tags", "ro.build.type", "ro.debuggable");
            // sb.append("\nsystem.prop下是否存在以下字段特征:");
            if (ToolUtil.checkProps("simulator", Mult_Prop))
                back = true;
            //3.检查挂载点,是否存在以下目录:
            //检查挂载点,检查/proc/mounts中是否存在vboxsf字段.
            List<String> list = Arrays.asList("/mnt/shared/Sharefolder", "/tiantian.conf", "/data/share1", "/hardware_device.conf", "/mnt/shared/products", "/mumu_hardware.conf", "/Andy.conf", "/mnt/windows/BstSharedFolder", "/bst.conf", "/mnt/shared/Applications", "/ld.conf");
            if (ToolUtil.checkFiles("simulator", list)) back = true;
            String files1 = ToolUtil.getFiles("/proc/mounts");
            if (files1 != null && files1.length() > 0 && files1.contains("vboxsf")) {
                sb.append("检查/proc/mounts中是否存在vboxsf字段\n");
                back = true;

            }
            // 4.检查是否安装了虚拟机软件:
            String files = ToolUtil.getFiles("/proc/self/root/data/data/");
            if (files != null && files.length() > 0) {
                List<String> list1 = Arrays.asList("com.vmos.app", "com.vmos.pro", "com.vmos.ggp");
                for (String re : list1)
                    if (files.contains(re)) {
                        sb.append("发现与VMOS虚拟机相关包名:" + re + "\n");
                        back = true;
                    }
            }
            if (files != null && files.length() > 0) {
                List<String> list1 = Arrays.asList("com.f1player", "com.f1player.play");
                for (String re : list1)
                    if (files.contains(re)) {
                        sb.append("发现与51虚拟机相关包名:" + re + "\n");
                        back = true;
                    }
            }
            if (files != null && files.length() > 0) {
                List<String> list1 = Arrays.asList("com.pspace.vandroid", "com.yiqiang.xmaster");
                for (String re : list1)
                    if (files.contains(re)) {
                        sb.append("发现与虚拟精灵和虚拟大师相关包名:" + re + "\n");
                        back = true;
                    }
            }
        } catch (Exception e) {
            ToolUtil.Log(e.getMessage());
        }
        return back;
    }

    /**
       七、改机软件
       1.检测是否安装了改机软件:
       检查包名是否存在:
       "com.yztc.studio.plugin","com.soft.apk008v","com.uwish.app","zpp.wjy.xxsq","com.bigsing.changer","zap.fh.wipe","com.sollyu.xposed.hook.model","com.soft.apk008Tool","com.doubee.ig","com.variable.apkhook","com.addeasy.fastest","com.xenice.mask","com.shyl.artifact","com.android1500.androidfaker"
       2.检查/dev/wgzs目录下的内容是否存在,若存在则获取值:
       "wg.cust.config.phone.id","wg.cust.s_android_id","wg.cust.sys.prop.filter","wg.cust.config.phone.imeimackey","wg.cust.config.phone.imei","wg.cust.config.pkg.name","wg.cust.destUids"
     */
    public static boolean isModification() {
        boolean back = false;
        try {
            List<String> list = Arrays.asList("com.yztc.studio.plugin", "com.soft.apk008v", "com.uwish.app", "zpp.wjy.xxsq", "com.bigsing.changer", "zap.fh.wipe", "com.sollyu.xposed.hook.model", "com.soft.apk008Tool", "com.doubee.ig", "com.variable.apkhook", "com.addeasy.fastest", "com.xenice.mask", "com.shyl.artifact", "com.android1500.androidfaker");
            if (ToolUtil.isRunningApk(context, list)) {
                back = true;
            }
            list = Arrays.asList("wg.cust.config.phone.id", "wg.cust.s_android_id", "wg.cust.sys.prop.filter", "wg.cust.config.phone.imeimackey", "wg.cust.config.phone.imei", "wg.cust.config.pkg.name", "wg.cust.destUids");
            String files = ToolUtil.getFiles("/dev/wgzs/");
            if (files != null && files.length() > 0)
                for (String re : list) {
                    if (files.contains(re)) {
                        back = true;
                        sb.append("检查/dev/wgzs目录存在参数:" + re + "\n");
                    }
                }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return back;
    }

    /**
       八、Root和Root工具
       1.包名检测,遍历/data/data/目录,寻找有无以下包名:
       "com.topjohnwu.magisk","eu.chainfire.supersu","com.noshufou.android.su","com.noshufou.android.su.elite","com.koushikdutta.superuser","com.thirdparty.superuser","com.yellowes.su","com.fox2code.mmm","io.github.vvb2060.magisk","com.kingroot.kinguser","com.kingo.root","com.smedialink.oneclickroot","com.zhiqupk.root.global","com.alephzain.framaroot","io.github.huskydg.magisk","me.weishu.kernelsu"
       2.检查su文件是否存在
       "/su/bin/su","/sbin/su","/data/local/xbin/su","/data/local/bin/su","/data/local/su","/system/xbin/su","/system/bin/su","/system/sd/xbin/su","/system/bin/failsafe/su","/system/bin/.ext/.su","/system/etc/.installed_su_daemon","/system/etc/.has_su_daemon","/system/xbin/sugote","/system/xbin/sugote-mksh","/system/xbin/supolicy","/system/etc/init.d/99SuperSUDaemon","/system/.supersu","/product/bin/su","/apex/com.android.runtime/bin/su","/apex/com.android.art/bin/su","/system_ext/bin/su","/system/xbin/bstk/su","/system/app/SuperUser/SuperUser.apk","/system/app/Superuser.apk","/system/xbin/mu_bak","/odm/bin/su","/vendor/bin/su","/vendor/xbin/su","/system/bin/.ext/su","/system/usr/we-need-root/su","/cache/su","/data/su","/dev/su","/system/bin/cph_su","/dev/com.koushikdutta.superuser.daemon","/system/xbin/daemonsu","/sbin/.mianju","/sbin/nvsu","/system/bin/.hid/su","/system/addon.d/99-magisk.sh"
       3.检查magisk相关文件是否存在
       "/cache/.disable_magisk","/dev/magisk/img","/sbin/.magisk","/cache/magisk.log","/data/adb/magisk","/system/etc/init/magisk","/system/etc/init/magisk.rc","/data/magisk.apk"
       4.检测Android PATH环境变量,检测path路径下是否存在“/su”
       5.检测 /proc/self/maps中的内容
       1、检测 /proc/self/maps 是否存在名为“/memfd:/jit-cache”的段(加载zygisk模块时(也就是liblspd.so)的时候会讲其名称设置为jit-cache,这样的话so的内存段在maps中就是/memfd:/jit-cache)
       2、通过检测map表是否存在匿名的并且具有可执行属性的内存判断是否存在lsposed
       3、检测栈空间[stack]的权限是否为“rw-p”
       6.检测ro.build.tags的值,读取 /system/build.prop并检测ro.build.tags的值是否为“test-keys”
       7.检测seLinux安全上下文,cat /proc/%d/attr/prev检测app进程的selinux安全上下文是否为“u:r:zygote:s0”
       8.检查/data/local/tmp/有无以下文件
       shizuku
       shizuku_starter
     */

    //Root检测
    public static boolean isRoot() {
        boolean back = false;
        try {
            //1.包名检测,遍历/data/data/目录,寻找有无以下包名:
            List<String> list = Arrays.asList("com.topjohnwu.magisk", "eu.chainfire.supersu", "com.noshufou.android.su", "com.noshufou.android.su.elite", "com.koushikdutta.superuser", "com.thirdparty.superuser", "com.yellowes.su", "com.fox2code.mmm", "io.github.vvb2060.magisk", "com.kingroot.kinguser", "com.kingo.root", "com.smedialink.oneclickroot", "com.zhiqupk.root.global", "com.alephzain.framaroot", "io.github.huskydg.magisk", "me.weishu.kernelsu");
            if (ToolUtil.isRunningApk(context, list)) back = true;
            //2.检查su文件是否存在
            list = Arrays.asList("/su/bin/su", "/sbin/su", "/data/local/xbin/su", "/data/local/bin/su", "/data/local/su", "/system/xbin/su", "/system/bin/su", "/system/sd/xbin/su", "/system/bin/failsafe/su", "/system/bin/.ext/.su", "/system/etc/.installed_su_daemon", "/system/etc/.has_su_daemon", "/system/xbin/sugote", "/system/xbin/sugote-mksh", "/system/xbin/supolicy", "/system/etc/init.d/99SuperSUDaemon", "/system/.supersu", "/product/bin/su", "/apex/com.android.runtime/bin/su", "/apex/com.android.art/bin/su", "/system_ext/bin/su", "/system/xbin/bstk/su", "/system/app/SuperUser/SuperUser.apk", "/system/app/Superuser.apk", "/system/xbin/mu_bak", "/odm/bin/su", "/vendor/bin/su", "/vendor/xbin/su", "/system/bin/.ext/su", "/system/usr/we-need-root/su", "/cache/su", "/data/su", "/dev/su", "/system/bin/cph_su", "/dev/com.koushikdutta.superuser.daemon", "/system/xbin/daemonsu", "/sbin/.mianju", "/sbin/nvsu", "/system/bin/.hid/su", "/system/addon.d/99-magisk.sh");
            if (ToolUtil.checkFiles("root su", list))
                back = true;
            //3.检查magisk相关文件是否存在
            list = Arrays.asList("/cache/.disable_magisk", "/dev/magisk/img", "/sbin/.magisk", "/cache/magisk.ToolUtil.Log", "/data/adb/magisk", "/system/etc/init/magisk", "/system/etc/init/magisk.rc", "/data/magisk.apk");
            if (ToolUtil.checkFiles("root magisk", list))
                back = true;
            //4.检测Android PATH环境变量,检测path路径下是否存在“/su”
            if (new File("/path/su").exists()) {
                sb.append("检测path路径下存在/su\n");
                back = true;
            }
            // * 6.检测ro.build.tags的值,读取 /system/build.prop并检测ro.build.tags的值是否为“test-keys”
            String property = System.getProperty("ro.build.tags");
            if (property != null && "test-keys".equals(property)) {
                sb.append("检测检测ro.build.tags的值为test-keys\n");
                back = true;
            }
            //8.检查/data/local/tmp/有无以下文件
            list = Arrays.asList("/data/local/tmp/shizuku", "/data/local/tmp/shizuku");
            if (ToolUtil.checkFiles("root data", list))
                back = true;
        } catch (Exception e) {
            ToolUtil.Log(e.getMessage());
        }
        return back;
    }



    //也可用于检测手机是否刷了面具:
    //command -v magisk
    public static boolean isMagisk() {
        boolean back = false;
        try {
            ShellUtils.CommandResult commandResult = ShellUtils.execCommand("command -v magisk", true);
            System.out.println("isMagisk:" + commandResult.toString());
            back = (commandResult.successMsg != null && commandResult.successMsg.contains("magisk"));
            if (back) {
                sb.append("command -v magisk: " + commandResult.successMsg + "\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return back;
    }

    //检测是否解锁了BL锁:(0代表已解锁,1代表未解锁)
    //getprop ro.boot.flash.locked
    public static boolean isBlOpen() {
        boolean back = false;
        try {
            //getprop ro.boot.flash.locked
            ShellUtils.CommandResult commandResult = ShellUtils.execCommand("getprop ro.boot.flash.locked", true);
            System.out.println("ro.boot.flash.locked:" + commandResult.toString());
            back = "0".equals(commandResult.successMsg);
            if (back) {
                sb.append("ro.boot.flash.locked=0\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return back;
    }

    //是否selinux处于宽容模式
    public static boolean isSELinuxInPermissiveMode() {
        boolean back = false;
        try {
            ShellUtils.CommandResult commandResult = ShellUtils.execCommand("getenforce", true);
            // "permissive" 表示 SELinux 处于宽容模式
            back = "Permissive".equals(commandResult.successMsg);
            if (back) {
                sb.append("getenforce-Permissive\n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return back;
    }


    //VPN检测
    public static boolean
    isVPN() {
        boolean Back = false;
        try {
            Enumeration<NetworkInterface> niList = NetworkInterface.getNetworkInterfaces();
            if (niList != null) {
                Iterator it = Collections.list(niList).iterator();
                while (it.hasNext()) {
                    NetworkInterface intf = (NetworkInterface) it.next();
                    if (intf.isUp() && intf.getInterfaceAddresses().size() != 0 && ("tun0".equals(intf.getName()) || "ppp0".equals(intf.getName()))) {
                        ToolUtil.Log("Risk has been detected", "VPN InterfaceAddresses " + intf.getName());
                        sb.append("检测到可疑参数:" + intf.getName() + "\n");
                        return true;
                    }
                }
            }
            return false;
        } catch (Exception e) {
            ToolUtil.Log(e.getMessage());
            return false;
        }
    }

    //是否开启代理 OK
    public static boolean isWifiProxy() {
        try {
            String proxyAddress;
            int proxyPort;
            boolean IS_ICS_OR_LATER = Build.VERSION.SDK_INT >= 14;
            if (IS_ICS_OR_LATER) {
                proxyAddress = System.getProperty("http.proxyHost");
                String portStr = System.getProperty("http.proxyPort");
                proxyPort = Integer.parseInt(portStr != null ? portStr : "-1");
            } else {
                proxyAddress = Proxy.getHost(context);
                proxyPort = Proxy.getPort(context);
            }
            boolean b = ((TextUtils.isEmpty(proxyAddress) || proxyPort == -1) ? false : true);
            if (b) {
                ToolUtil.Log("openProxy", "WifiProxy proxyAddress=" + proxyAddress + "\tproxyPort=" + proxyPort);
                sb.append("检测到可疑IP:" + String.format("ip=%s.prot=%s", proxyAddress, proxyPort) + "\n");
            }
            return b;
        } catch (Exception e) {
            ToolUtil.Log(e.getMessage());
            return false;
        }
    }


    //是否多开
    public static boolean isMulti_Launching_Apps() {
        boolean Back = false;
        try {
            //uid=10000-19999
            String filesdir = context.getFilesDir().getPath();
            int uid = Process.myUid();
            if (!filesdir.startsWith("/data/user/0/")) {
                ToolUtil.Log("multi-launching apps", "filesdir error:" + filesdir);
                sb.append("检测到可疑应用地址:" + filesdir + "\n");
                Back = true;
            }
            if (!(uid >= 10000 && uid <= 19999)) {
                ToolUtil.Log("multi-launching apps", "uid error:" + uid);
                sb.append("检测到可疑进程id:" + uid + "\n");
                Back = true;
            }
        } catch (Exception e) {
            ToolUtil.Log(e.getMessage());
        }
        return Back;
    }


    //是否开启无障碍服务
    public static boolean isAccessibilitySettingsOn() {
        try {
            int accessibilityEnabled = Settings.Secure.getInt(context.getApplicationContext().getContentResolver(), "accessibility_enabled");
            boolean isopen = (accessibilityEnabled == 1);
            if (isopen) {
                sb.append("检测到accessibility_enabled=1\n");
                ToolUtil.Log("accessiblity", "open accessiblity");
            }
            return isopen;
        } catch (Exception e) {
            ToolUtil.Log(e.getMessage());
            return false;
        }
    }

}
package com.example.risk.tool;

import android.util.Log;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;


public class ShellUtils {
    private static final String TAG = "ShellAdbUtils";

 //   public static final String COMMAND_SU = "su"; bart
    public static final String COMMAND_SU = "su";
    public static final String COMMAND_SH = "sh";
    public static final String COMMAND_EXIT = "exit\n";
    public static final String COMMAND_LINE_END = "\n";

    private ShellUtils() {
        throw new AssertionError();
    }

    /**
     * execute shell command, default return result msg
     *
     * @param command command
     * @param isRoot  whether need to run with root
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public synchronized static CommandResult execCommand(String command, boolean isRoot) {
        return execCommand(new String[]{command}, isRoot, true);
    }

    /**
     * execute shell commands
     *
     * @param commands        command array
     * @param isRoot          whether need to run with root
     * @param isNeedResultMsg whether need result msg
     * @return <ul>
     * <li>if isNeedResultMsg is false, {@link CommandResult#successMsg} is null and
     * {@link CommandResult#errorMsg} is null.</li>
     * <li>if {@link CommandResult#result} is -1, there maybe some excepiton.</li>
     * </ul>
     */
    public static CommandResult execCommand(String[] commands, boolean isRoot, boolean isNeedResultMsg) {
        int result = -1;
        if (commands == null || commands.length == 0) {
            return new CommandResult(result, null, null);
        }

        Process process = null;
        BufferedReader successResult = null;
        BufferedReader errorResult = null;
        StringBuilder successMsg = null;
        StringBuilder errorMsg = null;

        DataOutputStream os = null;
        try {
            process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);
            os = new DataOutputStream(process.getOutputStream());
            for (String command : commands) {
                if (command == null) {
                    continue;
                }

                // donnot use os.writeBytes(commmand), avoid chinese charset error
                os.write(command.getBytes());
                os.writeBytes(COMMAND_LINE_END);
                os.flush();
            }
            os.writeBytes(COMMAND_EXIT);
            os.flush();

            result = process.waitFor();
            // dl command result
            if (isNeedResultMsg) {
                successMsg = new StringBuilder();
                errorMsg = new StringBuilder();
                successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
                errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
                String s;
                while ((s = successResult.readLine()) != null) {
                    successMsg.append(s);
                }
                while ((s = errorResult.readLine()) != null) {
                    errorMsg.append(s);
                }
            }
        } catch (Exception e) {
            Log.e(TAG, Log.getStackTraceString(e));
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (successResult != null) {
                    successResult.close();
                }
                if (errorResult != null) {
                    errorResult.close();
                }
            } catch (IOException e) {
                Log.e(TAG,Log.getStackTraceString(e));
            }

            if (process != null) {
                process.destroy();
            }
        }
        return new CommandResult(result, successMsg == null ? null : successMsg.toString(), errorMsg == null ? null
                : errorMsg.toString());
    }

    /**
     * result of command
     * <ul>
     * <li>{@link CommandResult#result} means result of command, 0 means normal, else means error, same to excute in
     * linux shell</li>
     * <li>{@link CommandResult#successMsg} means success message of command result</li>
     * <li>{@link CommandResult#errorMsg} means error message of command result</li>
     * </ul>
     *
     * @author <a href="http://www.trinea.cn" target="_blank">Trinea</a> 2013-5-16
     */
    public static class CommandResult {

        /**
         * result of command
         **/
        public int result;
        /**
         * success message of command result
         **/
        public String successMsg;
        /**
         * error message of command result
         **/
        public String errorMsg;

        public CommandResult(int result) {
            this.result = result;
        }

        public CommandResult(int result, String successMsg, String errorMsg) {
            this.result = result;
            this.successMsg = successMsg;
            this.errorMsg = errorMsg;
        }

        @Override
        public String toString() {
            return "CommandResult{" +
                    "result=" + result +
                    ", successMsg='" + successMsg + '\'' +
                    ", errorMsg='" + errorMsg + '\'' +
                    '}';
        }
    }
}

  • 25
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值