Skip to content

DEX 反虚拟机规则 ​

anti_vmanti_debug28 + 3 private

apkid/rules/dex/anti-vm.yara — 28 条公开规则 + 3 条 private 积木。检测 反虚拟机/反模拟器技术——应用查询各种环境特征判断自己是否运行在沙箱/模拟器/QEMU 里。其中 checks_debugger_present 的 tag 是 anti_debug(反调试)。

🎯 检测原理 ​

反虚拟机技术分几大类:

  1. Build 属性检测:查 Build.FINGERPRINT/MODEL/BRAND 等是否匹配 "generic"/"sdk"/"google_sdk"/"goldfish" 等模拟器特征值。
  2. TelephonyManager 检测:查 SIM 运营商、设备 ID、手机号是否为模拟器默认值(如 000000000000000、155552155)。
  3. 文件系统检测:查 /sys/qemu_trace、/dev/qemu_pipe、/init.goldfish.rc 等 QEMU 痕迹文件。
  4. 系统属性检测:查 ro.hardware、ro.kernel.qemu、ro.secure 等 getprop 值。
  5. 调试检测:Debug.isDebuggerConnected()。

APKiD 用 3 个 private 积木识别"调用了哪个查询类"(Build/Debug/TelephonyManager),再细分具体检测项。

📋 private 积木规则(3 条) ​

私有规则说明
uses_build_classReferences android.os.Build 类 — Landroid/os/Build; 类名引用
uses_debug_classReferences android.os.Debug 类 — Landroid/os/Debug; 类名引用
uses_telephony_classReferences android.telephony.TelephonyManager 类 — 类名引用

Build 系列检测都要求 uses_build_class,Telephony 系列要求 uses_telephony_class——先确认"引用了这个类",再看具体检测字符串,降低误报。

📋 公开规则(28 条) ​

📱 Build 属性检测(12 条,anti_vm) ​

规则tag说明
checks_build_fingerprintanti_vmBuild.FINGERPRINT check — 匹配 "generic"/"unknown"/"generic/sdk/generic" 等
checks_build_modelanti_vmBuild.MODEL check — "google_sdk"/"sdk"/"Emulator"/"Android SDK built for x86"
checks_build_manufactureranti_vmBuild.MANUFACTURER check — "Genymotion"/"unknown"
checks_build_brandanti_vmBuild.BRAND check — "generic"
checks_build_deviceanti_vmBuild.DEVICE check — "generic"
checks_build_productanti_vmBuild.PRODUCT check — "google_sdk"/"sdk"
checks_build_hardwareanti_vmBuild.HARDWARE check — "goldfish"/"ranchu"/"vbox86"
checks_build_boardanti_vmBuild.BOARD check — "unknown"
checks_build_idanti_vmBuild.ID check — "FRF91"
possible_build_serial_checkanti_vmpossible Build.SERIAL check — 只查 SERIAL 字符串(无字面量)
checks_build_tagsanti_vmBuild.TAGS check — "test-keys"
checks_build_useranti_vmBuild.USER check — "android-build"

📞 TelephonyManager 检测(7 条,anti_vm) ​

规则tag说明
checks_sim_operatoranti_vmSIM operator check — getSimOperator + "Android"
checks_network_operatoranti_vmnetwork operator name check — getNetworkOperatorName + "Android"
checks_device_idanti_vmdevice ID check — getDeviceId + 000000000000000
checks_line1_numberanti_vmline 1 number check — getLine1Number + 155552155
checks_voicemail_numberanti_vmvoice mail number check — getVoiceMailNumber + 15552175049
checks_subscriber_idanti_vmsubscriber ID check — getSubscriberId + 0000000000
checks_network_interface_namesanti_vmnetwork interface name check — NetworkInterface.getName + eth0

🖥️ 文件/属性/QEMU 检测(8 条,anti_vm) ​

规则tag说明
checks_cpuinfoanti_vm/proc/cpuinfo check — 文件路径 + "Goldfish"
checks_build_typeanti_vmro.build.type check — 属性 + "user"
checks_hardwareanti_vmro.hardware check — "goldfish"/"ranchu"
checks_product_deviceanti_vmro.product.device check — "generic"
checks_kernel_qemuanti_vmro.kernel.qemu check — 只查属性字符串
possible_ro_secure_checkanti_vmpossible ro.secure check — 只查属性字符串
checks_qemu_fileanti_vmemulator file check — /init.goldfish.rc//sys/qemu_trace//dev/qemu_pipe 等 9 个路径
possible_vm_checkanti_vmpossible VM check — isEmulator 方法名

🐛 反调试(1 条,anti_debug) ​

规则tag说明
checks_debugger_presentanti_debugDebug.isDebuggerConnected() check — Debug + isDebuggerConnected 字符串

注意 checks_debugger_present 的 tag 是 anti_debug,因为反调试属于独立类别。详见 anti-debug 类别。

🔍 规则源码示例 ​

checks_build_fingerprint — Build 属性 + 模拟器特征值 ​

yara
rule checks_build_fingerprint : anti_vm {
  strings:
    $prop = {00 0B 46 49 4E 47 45 52 50 52 49 4E 54 00}  // FINGERPRINT
    $str_1 = {00 07 67 65 6E 65 72 69 63 00 0A}            // generic
    $str_2 = {00 07 75 6E 6B 6E 6F 77 6E 00}              // unknown
    $str_3 = "generic/sdk/generic"
    $str_4 = "generic/generic/generic"
    $str_5 = "generic/google_sdk/generic"
    $str_6 = "generic_x86/sdk_x86/generic_x86"
    $str_7 = "Android/full_x86/generic_x86"
    $str_8 = "generic/vbox86p/vbox86p"
  condition:
    uses_build_class and $prop and 1 of ($str_*)
}

逻辑:引用了 Build 类 + 出现 FINGERPRINT 字符串 + 出现至少 1 个模拟器特征值(如 "generic/sdk/generic")→ 判定做了 FINGERPRINT 反虚拟机检测。$str_* 是常见模拟器的 fingerprint 值。

checks_qemu_file — QEMU 痕迹文件 ​

yara
rule checks_qemu_file : anti_vm {
  strings:
    $a = "/init.goldfish.rc"
    $b = "/sys/qemu_trace"
    $c = "/system/bin/qemud"
    $d = "/system/bin/qemu-props"
    $e = "/system/lib/libc_malloc_debug_qemu.so"
    $f = "/dev/qemu_pipe"
    $g = "/dev/socket/qemud"
    $h = "/dev/socket/genyd"             // Geny 检测
    $i = "/dev/socket/baseband_genyd"
  condition:
    is_dex and 1 of them
}

模拟器(尤其 QEMU/Genymotion)会在文件系统留下这些特殊文件。命中 1 个即判定。

checks_debugger_present — 反调试 ​

yara
rule checks_debugger_present : anti_debug {
  strings:
    $debug = "Debug"
    $debugger_connected = "isDebuggerConnected"
  condition:
    uses_debug_class and $debug and $debugger_connected
}

引用 Debug 类 + isDebuggerConnected 方法名 → 判定做了反调试检测。

📊 finding 示例 ​

json
{
  "tag": "anti_vm::checks_build_fingerprint",
  "category": "anti_vm",
  "source": "app.apk!classes.dex",
  "identifier": "checks_build_fingerprint",
  "confidence": "high"
}

🧠 反虚拟机不等于恶意 ​

很多正规金融/DRM/游戏应用也做反虚拟机检测(防在模拟器上跑挂机/作弊)。APKiD 只标"有这个检测",是否恶意要看上下文。possible_* 前缀的规则(possible_build_serial_check、possible_ro_secure_check、possible_vm_check)是弱信号——只查了属性/方法名字符串,没确认对比值,可能是误报。

📍 相关 ​

基于 GPL & Commercial 双重许可发布