精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

檢測Android虛擬機的方法和代碼實現

云計算 虛擬化 Android
剛剛看了一些關于Detect Android Emulator的開源項目/文章/論文,我看的這些其實都是13年14年提出的方法,方法里大多是檢測一些環境屬性,檢查一些文件這樣,但實際上檢測的思路并不局限于此。

剛剛看了一些關于Detect Android Emulator的開源項目/文章/論文,我看的這些其實都是13年14年提出的方法,方法里大多是檢測一些環境屬性,檢查一些文件這樣,但實際上檢測的思路并不局限于此。有的是很直接了當去檢測qemu,而其它的方法則是旁敲側擊比如檢測adb,檢測ptrace之類的。思路也很靈活。

***看到有提出通過利用QEMU這樣的模擬CPU與物理CPU之間的實際差異(任務調度差異), 模擬傳感器和物理傳感器的差異,緩存的差異等方法來檢測。相比檢測環境屬性,檢測效果會提升很多。

[[228598]]

下面我就列出各個資料中所提出的一些方法/思路/代碼供大家交流學習。

QEMU Properties

  1. public class Property { 
  2.    public String name
  3.    public String seek_value; 
  4.  
  5.    public Property(String name, String seek_value) { 
  6.        this.name = name
  7.        this.seek_value = seek_value; 
  8.    } 
  9. /** 
  10. * 已知屬性, 格式為 [屬性名, 屬性值], 用于判定當前是否為QEMU環境 
  11. */ 
  12. private static Property[] known_props = {new Property("init.svc.qemud"null), 
  13.        new Property("init.svc.qemu-props"null), new Property("qemu.hw.mainkeys"null), 
  14.        new Property("qemu.sf.fake_camera"null), new Property("qemu.sf.lcd_density"null), 
  15.        new Property("ro.bootloader""unknown"), new Property("ro.bootmode""unknown"), 
  16.        new Property("ro.hardware""goldfish"), new Property("ro.kernel.android.qemud"null), 
  17.        new Property("ro.kernel.qemu.gles"null), new Property("ro.kernel.qemu""1"), 
  18.        new Property("ro.product.device""generic"), new Property("ro.product.model""sdk"), 
  19.        new Property("ro.product.name""sdk"), 
  20.        new Property("ro.serialno"null)}; 
  21. /** 
  22. * 一個閾值, 因為所謂"已知"的模擬器屬性并不完全準確, 有可能出現假陽性結果, 因此保持一定的閾值能讓檢測效果更好 
  23. */ 
  24. private static int MIN_PROPERTIES_THRESHOLD = 0x5; 
  25. /** 
  26. * 嘗試通過查詢指定的系統屬性來檢測QEMU環境, ***跟閾值比較得出檢測結果. 
  27. * @param context A {link Context} object for the Android application. 
  28. * @return {@code true} if enough properties where found to exist or {@code false} if not
  29. */ 
  30. public boolean hasQEmuProps(Context context) { 
  31.    int found_props = 0; 
  32.  
  33.    for (Property property : known_props) { 
  34.        String property_value = Utilities.getProp(context, property.name); 
  35.        // See if we expected just a non-null 
  36.        if ((property.seek_value == null) && (property_value != null)) { 
  37.            found_props++; 
  38.        } 
  39.        // See if we expected a value to seek 
  40.        if ((property.seek_value != null) && (property_value.indexOf(property.seek_value) != -1)) { 
  41.            found_props++; 
  42.        } 
  43.  
  44.    } 
  45.  
  46.    if (found_props >= MIN_PROPERTIES_THRESHOLD) { 
  47.        return true
  48.    } 
  49.  
  50.    return false

這些都是基于一些經驗和特征來比對的屬性, 這里的屬性以及之后的一些文件呀屬性啊之類的我就不再多作解釋。

Device ID

  1. private static String[] known_device_ids = {"000000000000000", // Default emulator id 
  2.        "e21833235b6eef10", // VirusTotal id 
  3.        "012345678912345"}; 
  4. public static boolean hasKnownDeviceId(Context context) { 
  5.    TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 
  6.  
  7.    String deviceId = telephonyManager.getDeviceId(); 
  8.  
  9.    for (String known_deviceId : known_device_ids) { 
  10.        if (known_deviceId.equalsIgnoreCase(deviceId)) { 
  11.            return true
  12.        } 
  13.  
  14.    } 
  15.    return false

Default Number

  1. private static String[] known_numbers = { 
  2.        "15555215554", // 模擬器默認電話號碼 + VirusTotal 
  3.        "15555215556""15555215558""15555215560""15555215562""15555215564""15555215566"
  4.        "15555215568""15555215570""15555215572""15555215574""15555215576""15555215578"
  5.        "15555215580""15555215582""15555215584",}; 
  6. public static boolean hasKnownPhoneNumber(Context context) { 
  7.    TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 
  8.  
  9.    String phoneNumber = telephonyManager.getLine1Number(); 
  10.  
  11.    for (String number : known_numbers) { 
  12.        if (number.equalsIgnoreCase(phoneNumber)) { 
  13.            return true
  14.        } 
  15.  
  16.    } 
  17.    return false

IMSI

  1. private static String[] known_imsi_ids = {"310260000000000" // 默認IMSI編號 
  2. }; 
  3. public static boolean hasKnownImsi(Context context) { 
  4.    TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 
  5.    String imsi = telephonyManager.getSubscriberId(); 
  6.  
  7.    for (String known_imsi : known_imsi_ids) { 
  8.        if (known_imsi.equalsIgnoreCase(imsi)) { 
  9.            return true
  10.        } 
  11.    } 
  12.    return false

Build類

  1. public static boolean hasEmulatorBuild(Context context) { 
  2.    String BOARD = android.os.Build.BOARD; // The name of the underlying board, like "unknown"
  3.    // This appears to occur often on real hardware... that's sad 
  4.    // String BOOTLOADER = android.os.Build.BOOTLOADER; // The system bootloader version number. 
  5.    String BRAND = android.os.Build.BRAND; // The brand (e.g., carrier) the software is customized for, if any
  6.    // "generic" 
  7.    String DEVICE = android.os.Build.DEVICE; // The name of the industrial design. "generic" 
  8.    String HARDWARE = android.os.Build.HARDWARE; // The name of the hardware (from the kernel command line or 
  9.    // /proc). "goldfish" 
  10.    String MODEL = android.os.Build.MODEL; // The end-user-visible name for the end product. "sdk" 
  11.    String PRODUCT = android.os.Build.PRODUCT; // The name of the overall product. 
  12.    if ((BOARD.compareTo("unknown") == 0) /* || (BOOTLOADER.compareTo("unknown") == 0) */ 
  13.            || (BRAND.compareTo("generic") == 0) || (DEVICE.compareTo("generic") == 0) 
  14.            || (MODEL.compareTo("sdk") == 0) || (PRODUCT.compareTo("sdk") == 0) 
  15.            || (HARDWARE.compareTo("goldfish") == 0)) { 
  16.        return true
  17.    } 
  18.    return false

運營商名

  1. public static boolean isOperatorNameAndroid(Context paramContext) { 
  2.    String szOperatorName = ((TelephonyManager) paramContext.getSystemService(Context.TELEPHONY_SERVICE)).getNetworkOperatorName(); 
  3.    boolean isAndroid = szOperatorName.equalsIgnoreCase("android"); 
  4.    return isAndroid; 

QEMU驅動

  1. private static String[] known_qemu_drivers = {"goldfish"}; 
  2. /** 
  3. * 讀取驅動文件, 檢查是否包含已知的qemu驅動 
  4. * @return {@code true} if any known drivers where found to exist or {@code false} if not
  5. */ 
  6. public static boolean hasQEmuDrivers() { 
  7.    for (File drivers_file : new File[]{new File("/proc/tty/drivers"), new File("/proc/cpuinfo")}) { 
  8.        if (drivers_file.exists() && drivers_file.canRead()) { 
  9.            // We don't care to read much past things since info we care about should be inside here 
  10.            byte[] data = new byte[1024]; 
  11.            try { 
  12.                InputStream is = new FileInputStream(drivers_file); 
  13.                is.read(data); 
  14.                is.close(); 
  15.            } catch (Exception exception) { 
  16.                exception.printStackTrace(); 
  17.            } 
  18.  
  19.            String driver_data = new String(data); 
  20.            for (String known_qemu_driver : FindEmulator.known_qemu_drivers) { 
  21.                if (driver_data.indexOf(known_qemu_driver) != -1) { 
  22.                    return true
  23.                } 
  24.            } 
  25.        } 
  26.    } 
  27.  
  28.    return false

QEMU文件

  1. private static String[] known_files = {"/system/lib/libc_malloc_debug_qemu.so""/sys/qemu_trace"
  2.        "/system/bin/qemu-props"}; 
  3. /** 
  4. * 檢查是否存在已知的QEMU環境文件 
  5. * @return {@code true} if any files where found to exist or {@code false} if not
  6. */ 
  7. public static boolean hasQEmuFiles() { 
  8.    for (String pipe : known_files) { 
  9.        File qemu_file = new File(pipe); 
  10.        if (qemu_file.exists()) { 
  11.            return true
  12.        } 
  13.    } 
  14.  
  15.    return false

Genymotion文件

  1. private static String[] known_geny_files = {"/dev/socket/genyd""/dev/socket/baseband_genyd"}; 
  2. /** 
  3. * 檢查是否存在已知的Genemytion環境文件 
  4. * @return {@code true} if any files where found to exist or {@code false} if not
  5. */ 
  6. public static boolean hasGenyFiles() { 
  7.    for (String file : known_geny_files) { 
  8.        File geny_file = new File(file); 
  9.        if (geny_file.exists()) { 
  10.            return true
  11.        } 
  12.    } 
  13.  
  14.    return false

QEMU管道

  1. private static String[] known_pipes = {"/dev/socket/qemud""/dev/qemu_pipe"}; 
  2. /** 
  3. * 檢查是否存在已知的QEMU使用的管道 
  4. * @return {@code true} if any pipes where found to exist or {@code false} if not
  5. */ 
  6. public static boolean hasPipes() { 
  7.    for (String pipe : known_pipes) { 
  8.        File qemu_socket = new File(pipe); 
  9.        if (qemu_socket.exists()) { 
  10.            return true
  11.        } 
  12.    } 
  13.  
  14.    return false

設置斷點

  1. static { 
  2.    // This is only valid for arm 
  3.    System.loadLibrary("anti"); 
  4. public native static int qemuBkpt(); 
  5.  
  6. public static boolean checkQemuBreakpoint() { 
  7.    boolean hit_breakpoint = false
  8.  
  9.    // Potentially you may want to see if this is a specific value 
  10.    int result = qemuBkpt(); 
  11.  
  12.    if (result > 0) { 
  13.        hit_breakpoint = true
  14.    } 
  15.  
  16.    return hit_breakpoint; 

以下是對應的c++代碼

  1. void handler_sigtrap(int signo) { 
  2.  exit(-1); 
  3.  
  4. void handler_sigbus(int signo) { 
  5.  exit(-1); 
  6.  
  7. int setupSigTrap() { 
  8.  // BKPT throws SIGTRAP on nexus 5 / oneplus one (and most devices) 
  9.  signal(SIGTRAP, handler_sigtrap); 
  10.  // BKPT throws SIGBUS on nexus 4 
  11.  signal(SIGBUS, handler_sigbus); 
  12.  
  13. // This will cause a SIGSEGV on some QEMU or be properly respected 
  14. int tryBKPT() { 
  15.  __asm__ __volatile__ ("bkpt 255"); 
  16.  
  17. jint Java_diff_strazzere_anti_emulator_FindEmulator_qemuBkpt(JNIEnv* env, jobject jObject) { 
  18.  
  19.  pid_t child = fork(); 
  20.  int child_status, status = 0; 
  21.  
  22.  if(child == 0) { 
  23.    setupSigTrap(); 
  24.    tryBKPT(); 
  25.  } else if(child == -1) { 
  26.    status = -1; 
  27.  } else { 
  28.  
  29.    int timeout = 0; 
  30.    int i = 0; 
  31.    while ( waitpid(child, &child_status, WNOHANG) == 0 ) { 
  32.      sleep(1); 
  33.      // Time could be adjusted here, though in my experience if the child has not returned instantly 
  34.      // then something has gone wrong and it is an emulated device 
  35.      if(i++ == 1) { 
  36.        timeout = 1; 
  37.        break; 
  38.      } 
  39.    } 
  40.  
  41.    if(timeout == 1) { 
  42.      // Process timed out - likely an emulated device and child is frozen 
  43.      status = 1; 
  44.    } 
  45.  
  46.    if ( WIFEXITED(child_status) ) { 
  47.      // 子進程正常退出 
  48.      status = 0; 
  49.    } else { 
  50.      // Didn't exit properly - very likely an emulator 
  51.      status = 2; 
  52.    } 
  53.  
  54.    // Ensure child is dead 
  55.    kill(child, SIGKILL); 
  56.  } 
  57.  
  58.  return status; 

這里我的描述可能并不準確, 因為并沒有找到相關的資料. 我只能以自己的理解來解釋一下:

SIGTRAP是調試器設置斷點時發生的信號, 在nexus5或一加手機等大多數手機都可以觸發. SIGBUS則是在一個總線錯誤, 指針也許訪問了一個有效地址, 但總線會因為數據未對齊等原因無法使用, 在nexus4手機上可以觸發. 而bkpt則是arm的斷點指令, 這是曾經qemu被提出來的一個issue, qemu會因為SIGSEGV信號而崩潰, 作者想利用這個崩潰來檢測qemu. 如果程序沒有正常退出或被凍結, 那么就可以認定很可能是在模擬器里.

ADB

  1. public static boolean hasEmulatorAdb() { 
  2.    try { 
  3.        return FindDebugger.hasAdbInEmulator(); 
  4.    } catch (Exception exception) { 
  5.        exception.printStackTrace(); 
  6.        return false
  7.    } 

isUserAMonkey()

  1. public static boolean hasEmulatorAdb() { 
  2.    try { 
  3.        return FindDebugger.hasAdbInEmulator(); 
  4.    } catch (Exception exception) { 
  5.        exception.printStackTrace(); 
  6.        return false
  7.    } 

這個其實是用于檢測當前操作到底是用戶還是腳本在要求應用執行。

isDebuggerConnected()

  1. /** 
  2. * 你信或不信, 還真有許多加固程序使用這個方法... 
  3. */ 
  4. public static boolean isBeingDebugged() { 
  5.    return Debug.isDebuggerConnected(); 

這個方法是用來檢測調試,判斷是否有調試器連接。

ptrace

  1. private static String tracerpid = "TracerPid"
  2. /** 
  3. * 阿里巴巴用于檢測是否在跟蹤應用進程 
  4. * 容易規避, 用法是創建一個線程每3秒檢測一次, 如果檢測到則程序崩潰 
  5. * @return 
  6. * @throws IOException 
  7. */ 
  8. public static boolean hasTracerPid() throws IOException { 
  9.    BufferedReader reader = null
  10.    try { 
  11.        reader = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/self/status")), 1000); 
  12.        String line; 
  13.  
  14.        while ((line = reader.readLine()) != null) { 
  15.            if (line.length() > tracerpid.length()) { 
  16.                if (line.substring(0, tracerpid.length()).equalsIgnoreCase(tracerpid)) { 
  17.                    if (Integer.decode(line.substring(tracerpid.length() + 1).trim()) > 0) { 
  18.                        return true
  19.                    } 
  20.                    break; 
  21.                } 
  22.            } 
  23.        } 
  24.  
  25.    } catch (Exception exception) { 
  26.        exception.printStackTrace(); 
  27.    } finally { 
  28.        reader.close(); 
  29.    } 
  30.    return false

這個方法是通過檢查 /proc/self/status 的TracerPid項,這個項在沒有跟蹤的時候默認為0,當有程序在跟蹤時會修改為對應的pid。因此如果TracerPid不等于0,那么就可以認為是在模擬器環境。

TCP連接

  1. public static boolean hasAdbInEmulator() throws IOException { 
  2.    boolean adbInEmulator = false
  3.    BufferedReader reader = null
  4.    try { 
  5.        reader = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/net/tcp")), 1000); 
  6.        String line; 
  7.        // Skip column names 
  8.        reader.readLine(); 
  9.  
  10.        ArrayList<tcp> tcpList = new ArrayList<tcp>(); 
  11.  
  12.        while ((line = reader.readLine()) != null) { 
  13.            tcpList.add(tcp.create(line.split("\\W+"))); 
  14.        } 
  15.  
  16.        reader.close(); 
  17.  
  18.        // Adb is always bounce to 0.0.0.0 - though the port can change 
  19.        // real devices should be != 127.0.0.1 
  20.        int adbPort = -1; 
  21.        for (tcp tcpItem : tcpList) { 
  22.            if (tcpItem.localIp == 0) { 
  23.                adbPort = tcpItem.localPort; 
  24.                break; 
  25.            } 
  26.        } 
  27.  
  28.        if (adbPort != -1) { 
  29.            for (tcp tcpItem : tcpList) { 
  30.                if ((tcpItem.localIp != 0) && (tcpItem.localPort == adbPort)) { 
  31.                    adbInEmulator = true
  32.                } 
  33.            } 
  34.        } 
  35.    } catch (Exception exception) { 
  36.        exception.printStackTrace(); 
  37.    } finally { 
  38.        reader.close(); 
  39.    } 
  40.  
  41.    return adbInEmulator; 
  42.  
  43. public static class tcp { 
  44.  
  45.    public int id; 
  46.    public long localIp; 
  47.    public int localPort; 
  48.    public int remoteIp; 
  49.    public int remotePort; 
  50.  
  51.    static tcp create(String[] params) { 
  52.        return new tcp(params[1], params[2], params[3], params[4], params[5], params[6], params[7], params[8], 
  53.                        params[9], params[10], params[11], params[12], params[13], params[14]); 
  54.    } 
  55.  
  56.    public tcp(String id, String localIp, String localPort, String remoteIp, String remotePort, String state, 
  57.                    String tx_queue, String rx_queue, String tr, String tm_when, String retrnsmt, String uid, 
  58.                    String timeout, String inode) { 
  59.        this.id = Integer.parseInt(id, 16); 
  60.        this.localIp = Long.parseLong(localIp, 16); 
  61.        this.localPort = Integer.parseInt(localPort, 16); 
  62.    } 

這個方法是通過讀取/proc/net/tcp的信息來判斷是否存在adb,比如真機的的信息為0: 4604D20A:B512 A3D13AD8...,而模擬器上的對應信息就是 0: 00000000:0016 00000000:0000,因為adb通常是反射到0.0.0.0這個ip上,雖然端口有可能改變,但確實是可行的。

TaintDroid

  1. public static boolean hasPackageNameInstalled(Context context, String packageName) { 
  2.    PackageManager packageManager = context.getPackageManager(); 
  3.  
  4.    // In theory, if the package installer does not throw an exception, package exists 
  5.    try { 
  6.        packageManager.getInstallerPackageName(packageName); 
  7.        return true
  8.    } catch (IllegalArgumentException exception) { 
  9.        return false
  10.    } 
  11. public static boolean hasAppAnalysisPackage(Context context) { 
  12.    return Utilities.hasPackageNameInstalled(context, "org.appanalysis"); 
  13. public static boolean hasTaintClass() { 
  14.    try { 
  15.        Class.forName("dalvik.system.Taint"); 
  16.        return true
  17.    } 
  18.    catch (ClassNotFoundException exception) { 
  19.        return false
  20.    } 

這個比較單純了。就是通過檢測包名,檢測Taint類來判斷是否安裝有TaintDroid這個污點分析工具。另外也還可以檢測TaintDroid的一些成員變量。

eth0

  1. private static boolean hasEth0Interface() { 
  2.    try { 
  3.        for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) { 
  4.            NetworkInterface intf = en.nextElement(); 
  5.            if (intf.getName().equals("eth0")) 
  6.                return true
  7.        } 
  8.    } catch (SocketException ex) { 
  9.    } 
  10.    return false

檢測是否存在eth0網卡。

傳感器

手機上配備了各式各樣的傳感器, 但它們實質上都是基于從環境收集的信息輸出值, 因此想要模擬傳感器是非常具有挑戰性的. 這些傳感器為識別手機和模擬器提供了新的機會。

比如在論文 Rage Against the Virtual Machine: Hindering Dynamic Analysis of Android Malware 中,作者對Android模擬器的加速器進行測試,作者發現Android模擬器上的傳感器會在相同的時間間隔內(觀測結果是0.8s, 標準偏差為0.003043)產生相同的值。顯然對于現實世界的傳感器,這是不可能的。

于是我們可以先注冊一個傳感器監聽器,如果注冊失敗,就可能是在模擬器中(排除實際設備不支持傳感器的可能性)。如果注冊成功,那么檢查onSensorChanged回調方法,如果在連續調用這個方法的過程所觀察到的傳感器值或時間間隔相同,那么就可以認定是在模擬器環境中。

QEMU任務調度

出于性能優化的原因, QEMU在每次執行指令時都不會主動更新程序計數器(PC), 由于翻譯指令在本地執行, 而增加PC需要額外的指令帶來開銷. 所以QEMU只在執行那些從線性執行過程里中斷的指令(例如分支指令)時才會更新程序計數器。

這也就導致在執行一些基本塊的期間如果發生了調度事件, 那么也沒有辦法恢復調度前的PC,也是出于這個原因,QEMU僅在執行基本塊后才發生調度事件,絕不會執行的過程中發生。

如上圖,因為調度可能在任意時間發生,所以在非模擬器環境下,會觀察到大量的調度點. 而在模擬器環境中,只能看到特定的調度點。

SMC識別

因為QEMU會跟蹤代碼頁的改動,于是存在一種新穎的方法來檢測QEMU--使用自修改代碼(Self-Modifying Code, SMC)引起模擬器和實際設備之間的執行流變化。

ARM處理器包含有兩個不同的緩沖Cache, 一個用于指令訪問(I-Cache),而另一個用于數據訪問(D-Cache)。但如ARM這樣的哈佛架構并不能保證I-Cache和D-Cache之間的一致性。因此CPU有可能在新代碼片已經寫入主存后執行舊的代碼片(也許是無效的)。

這個問題可以通過強迫兩個緩存一致得到解決, 這有兩步:

  1. 清理主存, 以便將D-Cache中新寫入的代碼移入主存
  2. 使I-Cache無效, 以便它可以用主存的新內容重新填充

在原生Android代碼中,可以使用cacheflush函數,該函數通過系統調用完成上述操作。

識別代碼,使用一個具有讀寫權限的內存, 其中包含兩個不同函數f1和f2的代碼,這兩個函數其實很簡單,只是單純在一個全局字符串變量的末尾附加各自的函數名稱, 這兩個函數會在循環里交錯執行,這樣就可以通過結果的字符串推斷出函數調用序列。

如前所述,我們調用cacheflush來同步緩存. 在實際設備和模擬器上運行代碼得到的結果是相同的--每次執行都會產生一致的函數調用序列。

接下來我們移除調用cacheflush,執行相同的操作。那么在實際設備中, 我們每次運行都會觀察到一個隨機的函數調用序列,這也如前所述的那樣,因為I-Cache可能包含一些舊指令,每次調用的時候緩存都不同步所導致的。

而模擬器環境卻不會發生這樣的情況, 而且函數調用序列會跟之前沒有移除cacheflush時完全相同, 也就是每次函數調用前緩存都是一致的. 這是因為QEMU會跟蹤代碼頁上的修改,并確保生成的代碼始終與內存中的目標指令匹配, 因此QEMU會放棄之前版本的代碼翻譯并重新生成新代碼。

結語

看到這里會不會已經覺得檢測方法夠多了,可是我還只是看了13年14年的資料。有關近幾年的資料還未涉及。

***我就把這些檢測方法整合在一張思維導圖(見附件)里供大家一覽,歡迎大家和我交流帶帶我

參考鏈接

strazzere/anti-emulator:***發表于2013年HitCon, 提出了檢測虛擬機的一些方法和思路, 應該是Android模擬器檢測的開山之作了, 本文也主要基于該倉庫進行講解.

Rage Against the Virtual Machine: Hindering Dynamic Analysis of Android Malware:通過任務調度檢測和使用SMC識別都是參考于這篇論文. 這篇論文和下面這篇論文十分有參考價值, 值得一讀.

Evading Android Runtime Analysis via Sandbox Detection:論文中提出了大量的檢測Android運行環境的方法和思路, 內容豐富且十分全面, 也值得一讀.

CalebFenton/AndroidEmulatorDetect:這個倉庫其實是整合了一些文章和倉庫中的檢測方法和代碼, 而且并不全面, 不過倒是給出了很多參考鏈接, 我順藤摸瓜.

How can I detect when an Android application is running in the emulator? 網友給出了很多解決方法. 但實際上并不全面, 也只是模擬器檢測中的冰山一角罷了. 畢竟可以檢測的地方多了去了。

利用任務調度特性檢測Android模擬器

 

責任編輯:武曉燕 來源: 看雪社區
相關推薦

2012-05-18 10:22:23

2010-07-26 09:02:38

2013-07-17 09:32:58

2018-10-11 11:07:28

Windows虛擬機方法

2023-02-20 14:24:56

AndroidDalvikART

2010-01-21 11:17:36

xen虛擬機

2023-04-26 07:51:36

虛擬機操作系統進程

2011-04-08 09:25:50

虛擬機

2016-09-27 20:12:33

Android虛擬機Android動態調試

2009-10-13 15:00:36

物理機虛擬機網絡安全

2022-01-26 16:30:47

代碼虛擬機Linux

2022-08-09 11:25:52

數據備份服務器虛擬化磁盤

2010-03-03 09:57:37

Linux虛擬機

2009-09-07 21:51:59

2020-01-17 10:52:37

無服務器容器技術

2021-03-16 10:36:38

網絡釣魚安全檢測網絡安全

2009-06-29 19:36:07

虛擬機備份虛擬環境

2020-12-08 05:58:57

CPU虛擬化虛擬機

2024-03-13 08:03:02

2009-09-04 08:33:25

VirtualBox虛
點贊
收藏

51CTO技術棧公眾號

婷婷综合六月| 狠狠狠狠狠狠狠| 欧美黄色一级| 日韩欧美在线免费观看| 亚洲精品在线免费看| 精品久久人妻av中文字幕| 国产精品毛片| 日韩最新在线视频| 在线免费观看a级片| 精品女同一区二区三区在线观看| 一级精品视频在线观看宜春院| 欧美不卡三区| 精品久久久中文字幕人妻| 日韩主播视频在线| 久久久久久亚洲精品| 受虐m奴xxx在线观看| 亚洲综合网站| 欧美日韩精品久久久| 欧美精品第1页| 91色精品视频在线| 国产精品熟女视频| 欧美三级在线| 日韩在线观看免费全集电视剧网站| 黄色激情在线观看| 国产亚洲高清在线观看| 欧美亚洲综合另类| 免费av观看网址| av在线网址观看| 白白色 亚洲乱淫| 亚洲一区亚洲二区| 中文字幕在线一| 久久狠狠一本精品综合网| 久久69精品久久久久久久电影好| 色婷婷国产精品免| 美女久久99| 亚洲国产精品人人爽夜夜爽| 国产成人美女视频| 欧美成a人片免费观看久久五月天| 亚洲图片欧美综合| 成人毛片100部免费看| 男人的天堂在线视频| 不卡av电影在线播放| 91香蕉国产在线观看| 一区二区三区午夜| 奇米影视一区二区三区| 亚洲综合日韩| 精品sm捆绑视频| 性生活在线视频| 国产麻豆精品| 欧美一区二区网站| 亚洲欧美一区二区三区不卡| 9999在线精品视频| 欧美一区二视频| 国产成人av免费观看| 免费一区二区三区在线视频| 欧美一级国产精品| 人妻互换一二三区激情视频| 视频一区国产| 亚洲国产精彩中文乱码av在线播放 | 亚洲精品承认| 亚洲视频一二三| 久久精品在线免费视频| av在线网址观看| 亚洲成人1区2区| 成年人免费在线播放| 欧美xxx视频| 欧美男生操女生| 亚洲欧美日韩网站| 国产精品任我爽爆在线播放| 亚洲精品理论电影| 欧美黄色一级生活片| 久久精品国产99久久| 久久国产精品亚洲| 日韩欧美亚洲视频| 日本在线免费看| 日本女优在线视频一区二区| 国产精品日韩在线| 国产特级黄色片| 国产suv精品一区二区三区| 国内精品视频免费| 成人精品一区| 一区二区免费看| 成人免费观看视频在线观看| 看片一区二区| 精品国产一区二区三区四区四| 一出一进一爽一粗一大视频| 日韩大片在线| 久久久久久久久久国产精品| www.欧美色| 国产精品99精品久久免费| 国产一区免费视频| 瑟瑟视频在线| 精品久久久一区| 国产三级国产精品国产专区50| 麻豆久久一区| 亚洲少妇激情视频| 久久久久免费看| 日韩国产精品久久久久久亚洲| 亚洲综合在线中文字幕| 日韩a在线观看| 亚洲免费在线看| 一本色道无码道dvd在线观看| 91麻豆精品国产综合久久久| 亚洲精品720p| 91精品国产闺蜜国产在线闺蜜| 一本综合久久| 亚洲一区二区三区777| 欧美男男同志| 亚洲一区二区三区不卡国产欧美| 国内自拍视频网| 果冻天美麻豆一区二区国产| 久久久久久久久久久久久久久久久久 | 91精品国产三级| 免费av一区| 久久免费精品视频| 国产乱淫av片免费| 国产亚洲精品久| 老太脱裤让老头玩ⅹxxxx| 在线日韩三级| 最近2019中文字幕大全第二页| 国产精品99精品| 国产老肥熟一区二区三区| 五月天久久狠狠| 亚洲少妇视频| 亚洲缚视频在线观看| 日韩一区二区三区四区在线| 青青草97国产精品免费观看 | 亚洲精品专区| 欧美日韩精品系列| 色婷婷在线影院| 99在线观看免费视频精品观看| 5566av亚洲| 日本美女在线中文版| 色狠狠桃花综合| 色噜噜在线观看| 亚洲伦理精品| 国产伦精品一区| 巨大荫蒂视频欧美另类大| 欧美色精品在线视频| 在线免费观看视频| 青青草原综合久久大伊人精品优势| 久久精品ww人人做人人爽| 丁香影院在线| 亚洲第一视频网站| 亚洲免费激情视频| 91社区在线播放| 那种视频在线观看| 欧美男同视频网| 国产精品h在线观看| 成人欧美一区| 欧美伦理视频网站| 国产探花在线免费观看| 国产成人午夜片在线观看高清观看| 老汉色影院首页| jizz久久精品永久免费| 久久久久久久成人| 姝姝窝人体www聚色窝| 欧美日韩国产精品一区二区三区四区 | 亚洲欧美三级伦理| 最近中文字幕免费在线观看| 中文字幕不卡在线播放| 九九九九九伊人| 午夜国产欧美理论在线播放| 国产欧美精品一区二区三区| 制服丝袜专区在线| 中文字幕亚洲一区二区三区五十路| 在线免费看毛片| 亚洲激情校园春色| 一区二区视频观看| 日产欧产美韩系列久久99| 一区二区三区我不卡| 综合欧美亚洲| 26uuu日韩精品一区二区| 福利片在线观看| 在线播放91灌醉迷j高跟美女| 青娱乐免费在线视频| 91在线国产福利| 中文字幕精品一区二区三区在线| 亚洲小说欧美另类社区| 欧美日韩成人一区二区三区| 97精品资源在线观看| 久久久久久久久久久久久久久久久久av| 天天摸夜夜添狠狠添婷婷| 欧美无砖专区一中文字| 欧美交换国产一区内射| 久久五月婷婷丁香社区| 亚洲精品性视频| 一区二区激情| 一区二区三区视频在线播放| 91精品国产自产在线丝袜啪| 国产www精品| 人人澡人人添人人爽一区二区| 国产视频一区在线| 99久久久久成人国产免费| 欧美日韩在线免费| 男人与禽猛交狂配| 久久久综合激的五月天| 日批视频在线看| 视频一区二区国产| 91亚洲精品国产| 日韩一区二区在线| 精品一区久久| 欧美第一在线视频| 国产精品亚洲精品| 天堂电影一区| 五月婷婷六月综合| 国产98在线|日韩| 欧美大陆国产| 国产97在线播放| rebdb初裸写真在线观看| 日韩中文理论片| 国产黄在线播放| 亚洲精品久久久久中文字幕二区| 一级久久久久久久| 欧美性jizz18性欧美| 国产在线成人精品午夜| 综合激情成人伊人| jizz18女人高潮| 久久久久久久久伊人| 日韩黄色一区二区| 国产精品系列在线观看| 久久婷婷综合色| 日本亚洲一区二区| 黑人糟蹋人妻hd中文字幕| 韩国av一区| a级片一区二区| 亚洲国产成人精品女人| 亚洲欧洲一区二区福利| 国产精品一区2区3区| 欧美精品一区二区视频| 欧美人妖视频| 精品视频一区在线| 久久综合五月婷婷| 国内外成人免费视频| eeuss国产一区二区三区四区| 亚洲综合小说区| 免费一区二区三区在线视频| 亚洲精品女av网站| 精品亚洲a∨一区二区三区18| 国产在线高清精品| 不卡的国产精品| 91免费看片网站| 电影一区中文字幕| 91视频在线免费观看| 视频国产精品| 国产成人看片| 国内精品国产成人国产三级粉色| 国产日韩欧美| 亚洲欧洲精品一区| 91久久电影| 99re6这里有精品热视频| 欧美日韩综合| 免费看日本毛片| 久久久久国产精品一区三寸| 免费激情视频在线观看| 免费在线欧美视频| 国产美女18xxxx免费视频| 激情综合五月天| 超碰在线超碰在线| 高清视频一区二区| aaaa黄色片| 国产夜色精品一区二区av| 中文字幕 自拍| 国产欧美精品一区aⅴ影院 | 伊人网在线综合| 国产精品一区二区男女羞羞无遮挡| 91pony九色| 国产69精品久久99不卡| jizz日本免费| 国产欧美一区二区三区网站| 免费精品在线视频| 夜夜爽夜夜爽精品视频| 久久狠狠高潮亚洲精品| 91福利视频在线| 99产精品成人啪免费网站| 亚洲国产高清自拍| 91在线网址| 欧美激情综合色| 成人在线爆射| 91日韩在线播放| 综合综合综合综合综合网| 黄色一级片网址| 亚洲一区二区三区高清| 国产三级国产精品国产专区50| 粉嫩13p一区二区三区| 中文字幕网站在线观看| 亚洲欧美偷拍三级| 天天综合网久久综合网| 欧美日韩夫妻久久| 香蕉久久一区二区三区| 日韩综合视频在线观看| 一个人www视频在线免费观看| 国产精品一区久久久| 国产精品流白浆在线观看| 亚洲欧美在线网| 性一交一乱一区二区洋洋av| 中文av字幕在线观看| 91视频com| 国产一级二级三级| 在线观看91视频| 老司机午夜福利视频| 中文字幕亚洲专区| 久久电影tv| 国产成人一区二区三区免费看| 欧美一区二区麻豆红桃视频| www.射射射| 国产美女精品人人做人人爽 | 亚洲精品成a人| 波多野结衣一区二区三区在线 | 精品av中文字幕在线毛片 | www.成人网.com| 亚洲天堂黄色片| 在线免费不卡视频| 偷拍自拍在线视频| 欧美精品18videos性欧美| 亚洲人成777| 亚洲成人a**址| 亚洲在线成人| 午夜男人的天堂| 亚洲综合成人网| hs视频在线观看| 日韩在线一区二区三区免费视频| 免费福利视频一区二区三区| 国产欧美一区二区三区另类精品 | 亚洲精品福利视频网站| 中文在线观看av| 亚洲色图第三页| 成人福利视频| 蜜桃999成人看片在线观看| 亚洲香蕉网站| 欧美久久久久久久久久久| 亚洲精品久久7777| 精品黑人一区二区三区国语馆| 精品国产美女在线| 亚洲色图图片| 五月天综合婷婷| 激情成人综合网| 中国一级片在线观看| 欧美日韩1234| 美女黄视频在线观看| 国产女人精品视频| 欧美激情另类| 中文字幕一区久久| 一区二区三区欧美久久| www.激情五月| 久久久免费精品视频| 理论片一区二区在线| 亚洲不卡中文字幕无码| 99re热这里只有精品免费视频| 国产做受高潮漫动| 精品亚洲va在线va天堂资源站| 一本大道色婷婷在线| 日本一区二区高清视频| 男女激情视频一区| 在线观看亚洲网站| 日韩精品一区国产麻豆| 国内小视频在线看| 久久久久久久久久久一区 | 自拍视频在线播放| 国产自产女人91一区在线观看| 我不卡影院28| 香蕉视频免费网站| 欧美日韩在线免费| av网站在线免费观看| 91久久精品国产91久久性色| 欧美啪啪一区| 五月婷婷综合在线观看| 欧美视频一区二| 超碰人人在线| 久久久久久a亚洲欧洲aⅴ| 美女性感视频久久| 强行糟蹋人妻hd中文| 亚洲精品国产品国语在线| 青青热久免费精品视频在线18| 一区二区三区在线观看www| 懂色av一区二区三区免费看| 国产精品视频免费播放| 中文字幕欧美在线| 2021年精品国产福利在线| avav在线看| 中文字幕亚洲视频| 欧美熟妇另类久久久久久不卡 | xxxx日韩| 成人性视频欧美一区二区三区| 亚洲欧洲综合另类| 四虎影视在线播放| 91人成网站www| 免费亚洲视频| 国产稀缺精品盗摄盗拍| 亚洲国产另类 国产精品国产免费| 成人在线爆射| 日韩视频免费播放| 综合久久国产九一剧情麻豆| 手机av免费在线观看| 成人午夜黄色影院| 亚洲一区二区三区四区五区午夜| 97在线观看视频免费| 亚洲精品久久久久久下一站| 婷婷久久免费视频| 久久久久久久久久久久久国产精品 |