精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

国产一区高清| 污视频在线免费| 综合久久婷婷| 亚洲国产天堂久久综合网| 男人日女人bb视频| 求av网址在线观看| 99视频精品在线| 国产精品久久久久福利| 极品盗摄国产盗摄合集| 亚洲都市激情| 欧美一区二区精品久久911| 国产精品无码一区二区在线| 日本成人网址| 久久综合九色综合久久久精品综合| 国产精品爽爽爽| 日韩精品一区二区不卡| 91欧美在线| 亚洲欧美国产va在线影院| 亚洲图片 自拍偷拍| 日韩pacopacomama| 午夜视频在线观看一区二区 | 136国产福利精品导航| 精品视频高清无人区区二区三区| 91tv国产成人福利| 日韩和欧美的一区| 91超碰caoporn97人人| caoporn91| 日韩欧美视频| 亚洲欧美日本精品| 在线看黄色的网站| 99久久久国产| 欧美日韩精品三区| 国产成人久久777777| 9765激情中文在线| 一级精品视频在线观看宜春院 | 亚洲美女黄网| 欧美精品中文字幕一区| 五月婷婷婷婷婷| 九九亚洲视频| 亚洲女人天堂网| 中文字幕一区二区三区人妻电影| 超碰在线成人| 亚洲成人网久久久| 稀缺呦国内精品呦| 亚洲精品一二三**| 欧美一级精品在线| 女人扒开双腿让男人捅 | 欧美日韩欧美一区二区| 老司机午夜av| 成人精品国产| 欧美日韩国产天堂| 国产成人美女视频| 成人精品在线| 日韩一区二区精品在线观看| 黄色a级三级三级三级| 日韩深夜福利网站| 欧美精品tushy高清| 亚洲一二三不卡| www一区二区三区| 91精品国产综合久久精品性色| 国产精品自在自线| 国产一区精品二区| 精品国产一区二区三区四区四 | 琪琪久久久久日韩精品 | 尤物网在线观看| 中文字幕乱码久久午夜不卡| 亚洲高清乱码| 国产丝袜在线| 亚洲综合在线免费观看| 97在线国产视频| 亚洲美女炮图| 欧美三级日本三级少妇99| 91女神在线观看| 日韩精品久久久久久久软件91| 精品欧美久久久| 丰满少妇一区二区三区| 嫩草一区二区三区| 精品国产一区二区三区四区在线观看 | 91久久久久久久久久久久| 日本不卡一区二区| 91九色精品视频| 欧美视频一二区| 国产天堂亚洲国产碰碰| 日本黄色播放器| 国产福利在线免费观看| 欧美性xxxxx| 欧美激情第3页| 欧美偷窥清纯综合图区| 国产亚洲精品久久久优势| 麻豆天美蜜桃91| 新狼窝色av性久久久久久| 国产综合久久久久| 色香蕉在线视频| 国产精品视频第一区| 日韩美女爱爱视频| 欧美大片1688网站| 精品国产三级电影在线观看| 一色道久久88加勒比一| 中文字幕一区二区三区在线视频| 97超级碰碰人国产在线观看| 亚洲一区精品在线观看| 丁香激情综合国产| 亚洲精品9999| 英国三级经典在线观看| 51午夜精品国产| 日本少妇xxxx| 天天影视综合| 国产va免费精品高清在线观看| aaaa一级片| 国产丝袜美腿一区二区三区| 国产激情片在线观看| 国产成+人+综合+亚洲欧美| 精品成人一区二区三区四区| 中文字幕91视频| 亚洲在线黄色| 国产伦精品一区二区三区免费视频 | 成人动漫av在线| 91免费网站视频| 五月激情久久| 亚洲精品日韩欧美| 国产污片在线观看| 国产呦精品一区二区三区网站| 日本成人黄色| 国产黄大片在线观看| 日韩午夜在线影院| 精品人妻伦九区久久aaa片| 视频在线观看一区二区三区| 国精产品99永久一区一区| 中文字幕在线观看播放| 欧美日韩aaa| 娇妻被老王脔到高潮失禁视频| 亚洲黄色影院| 国产精品二区三区四区| 性xxxxfjsxxxxx欧美| 欧美高清视频www夜色资源网| 无码一区二区三区在线| 亚洲综合国产| 久久久久九九九| 成人影院在线视频| 亚洲福利视频免费观看| 免费在线视频一区二区| 国产激情一区二区三区| 国产精品88久久久久久妇女| 国产精品美女久久久久人| 色婷婷综合久久久久| 一本一道人人妻人人妻αv| 欧美国产精品中文字幕| 久久久久久三级| 凹凸成人精品亚洲精品密奴| 国产精彩精品视频| av在线电影网| 欧美日韩高清在线播放| 男人晚上看的视频| 国产主播一区二区| 激情六月天婷婷| 第四色中文综合网| 69久久夜色精品国产7777| 人妻少妇一区二区三区| 韩曰欧美视频免费观看| 无码国产69精品久久久久同性| 另类天堂av| 日韩理论片在线观看| 久久69成人| 欧美理论电影在线播放| 欧美 日韩 国产 精品| 欧美天天综合色影久久精品| 精品国产成人亚洲午夜福利| 奇米色一区二区三区四区| 日韩欧美国产二区| 亚洲欧美在线人成swag| 久99久在线视频| 日韩一级片免费看| 在线观看三级视频欧美| 老熟妻内射精品一区| 成人精品一区二区三区四区| 成人黄色av片| 操欧美老女人| 亚洲综合第一页| 欧亚在线中文字幕免费| 一区二区三欧美| www.麻豆av| 一本大道综合伊人精品热热| 日本黄区免费视频观看| 国产成人精品亚洲日本在线桃色 | 亚洲成人精品在线| 国产又大又粗又爽| 亚洲黄网站在线观看| 日韩网站在线播放| 国内不卡的二区三区中文字幕 | 日韩中文字幕91| 玖玖精品在线视频| 免费成人结看片| 成人黄色在线免费| 天堂网在线最新版www中文网| 中国人与牲禽动交精品| 蜜桃视频久久一区免费观看入口| 日韩欧美中文在线| 免费在线观看一级片| 久久久精品天堂| 国产亚洲精品成人a| 欧美aaaaaa午夜精品| 波多野结衣av一区二区全免费观看| 国产欧美日韩精品一区二区三区 | 深夜影院在线观看| 欧美精选午夜久久久乱码6080| 日韩免费不卡视频| 成人欧美一区二区三区小说| 国产精品伦子伦| 国产一区二区在线看| chinese少妇国语对白| 韩国久久久久| 宅男一区二区三区| 深夜福利久久| 国产精品视频免费一区| 亚洲伊人精品酒店| 国产精品96久久久久久| 嗯啊主人调教在线播放视频| 久久久精品日本| 二区三区在线| 亚洲剧情一区二区| 日本黄色免费视频| 欧美r级在线观看| 国产又粗又黄又爽| 欧美日韩五月天| 精品久久久久久久久久久久久久久久| 夜夜嗨av一区二区三区网页| 国产三级精品三级观看| 国产调教视频一区| 91精彩刺激对白露脸偷拍| 成人精品国产一区二区4080| 国产又粗又猛又爽又黄| 韩国毛片一区二区三区| av免费一区二区| 美女性感视频久久| 艹b视频在线观看| 日本在线观看不卡视频| 可以免费观看av毛片| 西西裸体人体做爰大胆久久久| 无码 制服 丝袜 国产 另类| 国产综合网站| www.亚洲视频.com| 亚洲天堂激情| www国产无套内射com| 黄色成人av网站| 大荫蒂性生交片| 国自产拍偷拍福利精品免费一| 欧美黄色免费网址| 欧美日韩精品| 久久国产午夜精品理论片最新版本| 国产综合自拍| 欧美综合在线播放| 一区二区三区福利| 久久久久久久中文| 亚洲欧美激情诱惑| 黄色av免费在线播放| 日本aⅴ免费视频一区二区三区| 中文字幕天天干| 狠狠色丁香久久婷婷综合_中| 婷婷中文字幕在线观看| 国产成人精品一区二区三区网站观看| 韩国黄色一级片| 成人av片在线观看| 丰满圆润老女人hd| 亚洲国产岛国毛片在线| 三级黄色录像视频| 亚洲精品日韩一| www.国产成人| 91高清在线观看| 亚洲无码精品在线播放| 欧美一级理论片| 亚洲欧洲国产综合| 中文字幕日韩高清| 欧美黄色视屏| 国产mv久久久| 粉嫩av国产一区二区三区| 国产精品乱码视频| 国产一区二区三区电影在线观看| 中文字幕在线亚洲三区| 韩国精品一区二区三区| 国产精品无码一本二本三本色| 久久福利资源站| 天天躁日日躁狠狠躁免费麻豆| 91麻豆免费视频| 永久免费看mv网站入口| 亚洲超丰满肉感bbw| 成年人晚上看的视频| 日韩免费看网站| 麻豆导航在线观看| 欧美大码xxxx| 亚洲成人人体| 国产精品yjizz| 日韩精品诱惑一区?区三区| 日韩亚洲欧美一区二区| 日韩精品五月天| 国产亚洲精品成人a| 国产日产精品1区| 国产精品自拍视频一区| 欧美日韩一级黄| 香港一级纯黄大片| 久久影视电视剧免费网站| av高清不卡| 不卡一卡2卡3卡4卡精品在| 国产精品自拍区| 91免费黄视频| 国产最新精品免费| 欧美做受高潮6| 精品成人国产在线观看男人呻吟| 国产普通话bbwbbwbbw| 亚洲人成电影在线播放| 美女91在线| 91理论片午午论夜理片久久| 国产精品一线天粉嫩av| 欧美 国产 综合| 国产成人亚洲精品青草天美 | 亚洲亚洲人成综合网络| 无码人妻久久一区二区三区| 精品国产乱码91久久久久久网站| 日本福利在线| 国产精品久久久久久av福利软件| 国产欧美自拍一区| 麻豆传媒网站在线观看| 麻豆精品一区二区三区| 欧洲女同同性吃奶| 午夜不卡av免费| 国产综合在线播放| 久久99国产精品自在自在app| 欧美美女被草| 亚洲高清在线播放| 日韩精品一二三| 99久久精品免费视频| 色综合久久天天综合网| 无码国产精品96久久久久| 久久久久久久999精品视频| 91亚洲精品在看在线观看高清| 亚洲国产精品综合| 日本va欧美va欧美va精品| 在线免费观看视频| 欧美亚洲日本一区| yjizz视频网站在线播放| 国产精品va在线播放| 一区二区美女| 免费国产成人av| 国产午夜精品理论片a级大结局| 日韩黄色在线播放| 亚洲欧美日韩中文视频| 深夜成人影院| 日韩精品欧美一区二区三区| 日本美女一区二区三区| 欧美色图17p| 91精品在线一区二区| а√天堂资源地址在线下载| 91色在线观看| 欧美日韩精选| 成人手机在线免费视频| 日韩欧美中文免费| 在线观看免费高清完整| 91理论片午午论夜理片久久| 国产一区日韩欧美| 午夜视频在线观看国产| 欧美小视频在线| 午夜在线视频| 91热精品视频| 亚洲三级国产| 一区二区三区伦理片| 4438x亚洲最大成人网| 少妇视频在线| 久久久免费看| 免费在线观看视频一区| 99久久婷婷国产综合| 亚洲国产精品成人精品| 欧美男女交配| 影音欧美亚洲| av在线播放成人| 日韩xxx视频| 九九九久久久久久| 偷拍自拍亚洲色图| 欧美婷婷精品激情| 亚洲综合一二三区| 国产精品免费播放| 666精品在线| 麻豆久久精品| 天天干中文字幕| 亚洲欧美日韩网| 韩国三级成人在线| 免费在线激情视频| 日韩理论片在线| 日本不卡视频一区二区| 成人在线中文字幕| 亚洲欧美日韩一区在线观看| 日韩av毛片在线观看| 亚洲国产91精品在线观看| 九色成人搞黄网站| 国产色一区二区三区| 国产精品三级av在线播放| 丰满少妇在线观看bd| 国产精品香蕉国产| a91a精品视频在线观看| 日韩精品一区二区三区在线视频| 亚洲国产精品久久久久| 亚洲色图图片|