美文网首页
VirtualApp 沙箱环境检测

VirtualApp 沙箱环境检测

作者: that_is_this | 来源:发表于2018-09-07 18:25 被阅读273次

    upupupuuup

    对于 PS 命令检查返回的进程信息,在平行大师、360多开分身等应用是行不通的,因为 ps 只显示了 一个进程相关的信息,所以,可以检测当不存在主进程相关的条目信息时,就判断为多开应用。

    public class VA_check {
        private static String TAG = "Wooo_VA";
    
        /*
        * https://github.com/ysrc/AntiVirtualApp
        * https://github.com/ZaratustraN/Check_VirtualAPK   ->   https://www.jianshu.com/p/216d65d9971e , C++ 代码壳参考~
        *
        *
        *
        * */
    
        public static void checkVA(Context ctx) {
            checkPid(ctx);
            checkFilesDir(ctx);
            checkInstalledPKG(ctx);
            checkUID();
            checkELF();
        }
    
        private static void checkELF() {
            // in native
            // 同检测 uid -> "ps | grep libmainNative.so" -> 查看路径
        }
    
        private static void checkPid(Context ctx) {     // 没用
            int pid = android.os.Process.myPid();
            String proName = getProcessName(ctx, pid);
            Log.i(TAG, "pid -> " + pid + " , processName -> " + proName);
            String pkgName = ctx.getPackageName();
            Log.i(TAG, "pkg name -> " + pkgName);
        }
    
        private static String getProcessName(Context ctx, int pid) {
            try {
                ActivityManager am = (ActivityManager) ctx.getSystemService(Context.ACTIVITY_SERVICE);
                List<ActivityManager.RunningAppProcessInfo> runn = am.getRunningAppProcesses();
                if (runn != null && !runn.isEmpty()) {
                    for (ActivityManager.RunningAppProcessInfo amr : runn) {
                        if (amr.pid == pid) {
                            return amr.processName;
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        private static void checkFilesDir(Context ctx) {
            String fdir = ctx.getFilesDir().getAbsolutePath();
            Log.i(TAG, "filesDir -> " + fdir);
            int num = fdir.length() - fdir.replace("/", "").length();
            if (num > 8) {
                Log.i(TAG, "May in VA .. slipyer num -> " + num);
            } else {
                Log.i(TAG, "May not in VA .. slipyer num -> " + num);
            }
        }
    
        private static void checkInstalledPKG(Context ctx) {    // 没用
            int count = 0;
            String pkgName = ctx.getPackageName();
            PackageManager pm = ctx.getPackageManager();
            List<PackageInfo> piL = pm.getInstalledPackages(0);
            for (PackageInfo pi : piL) {
                if (pkgName.equals(pi.packageName)) {
                    count++;
                }
            }
            if (count > 1) {
                Log.i(TAG, "May In VA BOX  PKG-> " + count);
            }
            Log.i(TAG, "May not In VA BOX  PKG-> " + count);
        }
    
        private static void checkUID() {
            String filter = getUidStrFormat();
    
            if (filter == null) {
                return;
            }
            String result = exec("ps");
            if (result == null || result.isEmpty()) {
                return;
            }
    
            String[] lines = result.split("\n");
            if (lines.length <= 0) {
                return;
            }
    
            int exitDirCount = 0;
    
            for (int i = 0; i < lines.length; i++) {
                if (lines[i].contains(filter)) {
                    int pkgStartIndex = lines[i].lastIndexOf(" ");
                    String processName = lines[i].substring(pkgStartIndex <= 0 ? 0 : pkgStartIndex + 1, lines[i].length());
                    File dataFile = new File(String.format("/data/data/%s", processName, Locale.CHINA));
                    if (dataFile.exists()) {
                        exitDirCount++;
                    }
    
                }
            }
            if (exitDirCount > 1) {
                Log.i(TAG, "is IN Virtual App. Dir count -> " + exitDirCount);
            } else {
                Log.i(TAG, "not IN Virtual App. Dir count -> " + exitDirCount);
            }
        }
    /*
        same uid processName 0 -> u0_a114
        same uid processName 1 -> 7
        same uid processName 2 -> USER      PID   PPID  VSIZE  RSS   WCHAN            PC  NAME
        same uid processName 2 -> u0_a114   18188 4528  1144388 61428 SyS_epoll_ a945a514 S io.virtualapp:x
        same uid processName 3 -> io.virtualapp:x
        same uid processName 2 -> u0_a114   21331 4528  1544560 161864 SyS_epoll_ a945a514 S io.virtualapp
        same uid processName 3 -> io.virtualapp
        same uid processName 2 -> u0_a114   21485 4528  1193680 75264 futex_wait a942941c S com.saliey.twobutton
        same uid processName 3 -> com.saliey.twobutton
        same uid processName 2 -> u0_a114   21508 4528  1139324 56740 SyS_epoll_ a945a514 S com.saliey.twobutton:ss
        same uid processName 3 -> com.saliey.twobutton:ss
        same uid processName 2 -> u0_a114   21597 21485 3544   1204  sigsuspend b5a0985c S sh
        same uid processName 3 -> sh
        same uid processName 2 -> u0_a114   21598 21597 4532   1272           0 ad04c6a8 R ps
        same uid processName 3 -> ps
    */
    
    
        private static String getUidStrFormat() {
            String filter = exec("cat /proc/self/cgroup");
            if (filter == null || filter.length() == 0) {
                return null;
            }
    
            int uidStartIndex = filter.lastIndexOf("uid");
            int uidEndIndex = filter.lastIndexOf("/pid");
            if (uidStartIndex < 0) {
                return null;
            }
            if (uidEndIndex <= 0) {
                uidEndIndex = filter.length();
            }
    
            filter = filter.substring(uidStartIndex + 4, uidEndIndex);
            try {
                String strUid = filter.replaceAll("\n", "");
                if (isNumber(strUid)) {
                    int uid = Integer.valueOf(strUid);
                    filter = String.format("u0_a%d", uid - 10000);
                    return filter;
                }
                return null;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
        private static boolean isNumber(String str) {
            if (str == null || str.length() == 0) {
                return false;
            }
            for (int i = 0; i < str.length(); i++) {
                if (!Character.isDigit(str.charAt(i))) {
                    return false;
                }
            }
            return true;
        }
    
        private static String exec(String command) {
            BufferedOutputStream bufferedOutputStream = null;
            BufferedInputStream bufferedInputStream = null;
            Process process = null;
            String outputStr;
            try {
                process = Runtime.getRuntime().exec("sh");
                bufferedOutputStream = new BufferedOutputStream(process.getOutputStream());
    
                bufferedInputStream = new BufferedInputStream(process.getInputStream());
                bufferedOutputStream.write(command.getBytes());
                bufferedOutputStream.write('\n');
                bufferedOutputStream.flush();
                bufferedOutputStream.close();
    
                process.waitFor();
    
                outputStr = getStrFromBufferInputSteam(bufferedInputStream);
                return outputStr;
            } catch (Exception e) {
                return null;
            } finally {
                if (bufferedOutputStream != null) {
                    try {
                        bufferedOutputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (bufferedInputStream != null) {
                    try {
                        bufferedInputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (process != null) {
                    process.destroy();
                }
            }
        }
    
        private static String getStrFromBufferInputSteam(BufferedInputStream bufferedInputStream) {
            if (null == bufferedInputStream) {
                return "";
            }
            int BUFFER_SIZE = 512;
            byte[] buffer = new byte[BUFFER_SIZE];
            StringBuilder result = new StringBuilder();
            try {
                while (true) {
                    int read = bufferedInputStream.read(buffer);
                    if (read > 0) {
                        result.append(new String(buffer, 0, read));
                    }
                    if (read < BUFFER_SIZE) {
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return result.toString();
        }
    }
    
    

    改正后,根据包名判断。

        private static void checkUID(Context ctx) {
            String pkgName = ctx.getPackageName();
            String filter = getUidStrFormat();
            Log.i(TAG, "checkUID uid is -> " + filter);
    
            if (filter == null) {
                return;
            }
            String result = exec("ps");
            if (result == null || result.isEmpty()) {
                return;
            }
    
            String[] lines = result.split("\n");
            if (lines.length <= 0) {
                return;
            }
    
            int exitDirCount = 0;
            int exitRawProcess = 0;
    
            Log.i(TAG, "checkUID size : " + lines.length);
            for (int i = 0; i < lines.length; i++) {
                Log.i(TAG, "checkUID is -> " + lines[i]);
                if (lines[i].contains(filter)) {
                    int pkgStartIndex = lines[i].lastIndexOf(" ");
                    String processName = lines[i].substring(pkgStartIndex <= 0 ? 0 : pkgStartIndex + 1, lines[i].length());
                    File dataFile = new File(String.format("/data/data/%s", processName, Locale.CHINA));
                    if (dataFile.exists()) {
                        exitDirCount++;
                    }
                    if (processName.contains(pkgName)) {
                        exitRawProcess++;
                    }
                }
            }
            if (exitDirCount > 1 || exitRawProcess == 0) {
                Log.i(TAG, "is IN Virtual App. Dir count -> " + exitDirCount + " , rawPro -> " + exitRawProcess);
            } else {
                Log.i(TAG, "not IN Virtual App. Dir count -> " + exitDirCount + " , rawPro -> " + exitRawProcess);
            }
        }
    

    相关文章

      网友评论

          本文标题:VirtualApp 沙箱环境检测

          本文链接:https://www.haomeiwen.com/subject/amxhgftx.html