Fingerprint Playground 虚拟机检测原理分析

目标站点:https://demo.fingerprint.com/playground
采集时间:2026-06-18
本报告基于本地 Firefox 内核 domtrace / jscall / http 落盘、Ruyipage 自动化网络记录和页面快照分析。结论用于技术研究与公众号解析,不等价于 Fingerprint 官方服务端模型。

一句话结论

Fingerprint Playground 的“Virtual Machine”不是前端 JS 里直接写死的一条规则,而是:

浏览器 SDK 采集环境指纹
-> 加密/压缩后提交到 Fingerprint 边缘接口
-> 服务端返回 visitor_id / event_id
-> Playground 再用 event_id 查询服务端事件详情
-> 服务端事件详情里给出 virtual_machine 与 virtual_machine_ml_score

本次样本最终结果:

virtual_machine: false
virtual_machine_ml_score: 0.155
suspect_score: 15
bot: not_detected
tampering: false
developer_tools: true

虽然 WebGL renderer 暴露了 Microsoft Basic Render Driver 这种软件渲染/回退渲染特征,但服务端没有直接判定为虚拟机。原因是它更像一个多信号评分模型:WebGL 是强信号之一,但不是唯一证据。

请求链复盘

核心链路如下:

1. GET /playground
   加载 Next.js 页面和 playground chunk

2. GET /DBqbMN7zXxwl4Ei8/web/v4/ahNo3Idb3RiQg69bQglE?ci=jsl/4.0.0
   加载 Fingerprint Pro JS agent

3. GET /DBqbMN7zXxwl4Ei8/tdSBLg/81tfzl/e?region=us&q=ahNo3Idb3RiQg69bQglE
   获取一段短文本初始化材料

4. POST /DBqbMN7zXxwl4Ei8?region=us&ci=js/4.1.0&q=ahNo3Idb3RiQg69bQglE
   SDK 提交加密后的环境采集 body,响应 event_id / visitor_id / suspect_score

5. POST /api/event/v4/1781762212213.gMJxBp
   Playground 用 event_id 查询完整服务端事件,拿到 Smart Signals 与 raw_device_attributes

本地证据:

证据 文件
SDK agent 源码 tmp/static/37_demo.fingerprint.com_DBqbMN7zXxwl4Ei8_web_v4_ahNo3Idb3RiQg69bQglE_ci_jsl_4.0.0.js
SDK 首次识别响应 tmp/trace/http_packet/000025_POST_200_demo_fingerprint_com_DBqbMN7zXxwl4Ei8_pid12988_380000057.http_packet.json
Playground 事件详情响应 tmp/trace/http_packet/000028_POST_200_demo_fingerprint_com_api_event_v4_1781762212213_gMJxBp_pid12988_38000005a.http_packet.json
页面入口 chunk tmp/static/19_demo.fingerprint.com__next_static_chunks_2473-1eedb759263b52d2.js.js
DOM/JSCALL 运行轨迹 tmp/trace/domtrace/trace_process_12492.jsonltmp/trace/jscall/trace_jscall_process_12492.jsonl

前端只负责展示,判定来自服务端事件

页面 chunk 中可以看到 Playground 的逻辑:

getData({ linkedId, timeout, immediate: true })
-> 得到 agentResponse.event_id
-> fetch("/api/event/v4/" + event_id, { method: "POST" })
-> 渲染 server response 里的 virtual_machine

也就是说,virtual_machine 不是页面本地计算的字段。前端只是把服务端事件 JSON 中的字段展示为:

Virtual Machine: Not detected

服务端事件响应中的关键片段:

{
  "event_id": "1781762212213.gMJxBp",
  "sdk": {
    "platform": "js",
    "version": "4.1.0",
    "integrations": [
      { "name": "fingerprintjs-pro-cloudfront", "version": "2.2.0" },
      { "name": "fingerprintjs-pro-react", "version": "3.0.0" }
    ]
  },
  "virtual_machine": false,
  "virtual_machine_ml_score": 0.155,
  "raw_device_attributes": {}
}

上面的 raw_device_attributes 在真实响应里是完整对象,README 中省略展开。

实际检测信号与证据链

这一节只列本次页面真实采到、服务端真实返回、trace 真实出现的信号。证据分四层:

页面展示值 -> HTTP 事件 JSON 字段 -> DOM trace 调用 -> agent 源码函数

页面侧可见证据在 tmp/capture/page_visible_text.txt

Virtual Machine    Not detected
JavaScript Agent Response:
  event_id: "1781762212213.gMJxBp"
  visitor_id: "orsF9S092M2X9NOJNLmr"
  suspect_score: 15
Server API Response:
  virtual_machine: false
  virtual_machine_ml_score: 0.155

服务端事件响应在 tmp/trace/http_packet/000028_POST_200_demo_fingerprint_com_api_event_v4_1781762212213_gMJxBp_pid12988_38000005a.http_packet.json,核心字段路径都在 responseBody.text 里:

信号 服务端字段路径 本次实际值
VM 最终结论 virtual_machine / virtual_machine_ml_score false / 0.155
WebGL renderer raw_device_attributes.webgl_basics.renderer ANGLE (Microsoft, Microsoft Basic Render Driver Direct3D11 vs_5_0 ps_5_0), or similar
WebGL vendor/version raw_device_attributes.webgl_basics.vendor/version Mozilla / WebGL 1.0 (OpenGL ES 2.0 Chromium)
WebGL 扩展摘要 raw_device_attributes.webgl_extensions context_attributesparametersshader_precisionsextensionsextension_parameters 都是 hash
Canvas raw_device_attributes.canvas winding=truegeometry=64eb3eab062851c8cbed87bca98b6f6ctext=c17750b6edad27927cb0401bca6ec2c6
字体 raw_device_attributes.fonts/font_hash CalibriFranklin GothicHELVMS UI GothicMarlettSegoe UI LightSimHeiSmall Fonts,hash=1affeb088cac7b5efc90e012a4cac857
Audio raw_device_attributes.audio 35.749972093850374
Math raw_device_attributes.math 5f030fa7d2e5f9f757bfaf81642eb1a6
Screen raw_device_attributes.screen_resolution/color_depth [920, 1961]24
OS/平台 user_agentbrowser_detailsraw_device_attributes.platform/oscpu Firefox 151 / Windows 10 / Win32 / Windows NT 10.0; Win64; x64
资源能力 hardware_concurrency/plugins CPU 核心数 8,5 个 PDF 插件
存储能力 session_storage/local_storage/indexed_db/cookies_enabled 全部为 true
时区/VPN timezone/timezone_offset/vpn_methods 本机时区 Asia/Shanghai,VPN 命中 timezone_mismatchos_mismatch

对应的 agent DOM trace 证据都来自 tmp/trace/domtrace/trace_process_12492.jsonl,并且 stack 命中 https://demo.fingerprint.com/DBqbMN7zXxwl4Ei8/web/v4/ahNo3Idb3RiQg69bQglE?ci=jsl/4.0.0

信号 次数 trace 位置 调用与返回 agent 函数
WebGL 基础参数 92 trace_process_12492.jsonl:136349 getParameter(7938) -> WebGL 1.0 (OpenGL ES 2.0 Chromium) lX@5:42016
WebGL 扩展列表 1 trace_process_12492.jsonl:136357 getSupportedExtensions() -> 含 WEBGL_debug_renderer_info 等 27 项 EX@5:42654
Shader 精度 12 trace_process_12492.jsonl:136505 getShaderPrecisionFormat(35632, 36336) eG@5:7312
Canvas 文本 4 trace_process_12492.jsonl:133334 fillText("Cwm fjordbank gly ...", 2, 15) bG@5:14401
Canvas 输出 4 trace_process_12492.jsonl:133338 toDataURL() -> PNG data URL,length=7806,trace hash=d0383832c39a7dd8 lQ@5:95440
Canvas 像素 2 trace_process_12492.jsonl:133806 getImageData(1, 1, 958, 718) agent 内部 D@5:182853
插件 7 trace_process_12492.jsonl:135696 navigator.plugins -> PluginArray length=5 aB@5:38510
MIME 6 trace_process_12492.jsonl:135972 navigator.mimeTypes -> MimeTypeArray length=2 IF@5:84950
CPU 核心 2 trace_process_12492.jsonl:135657 navigator.hardwareConcurrency -> 8 tB@5:37599
平台 2 trace_process_12492.jsonl:135690 navigator.platform -> Win32 TB@5:38229
OSCPU 2 trace_process_12492.jsonl:135629 navigator.oscpu -> Windows NT 10.0; Win64; x64 nB@5:37003
语言 5 trace_process_12492.jsonl:135635 navigator.languages -> ["en-US", "en"] rB@5:37171
触摸能力 3 trace_process_12492.jsonl:135742 navigator.maxTouchPoints -> 0 cB@5:38825
屏幕宽高 4/4 trace_process_12492.jsonl:132967132970 screen.width=1961screen.height=920 ud@5:133730
颜色深度 1 trace_process_12492.jsonl:135642 screen.colorDepth -> 24 DB@5:37479
Storage 21/1/2 trace_process_12492.jsonl:135672135667133280 localStoragesessionStorageindexedDB 均可读 qB/oB/YH
随机源 113 trace_process_12492.jsonl:132345 crypto.getRandomValues(Uint32Array) oU@5:168263
时区偏移 1 trace_process_12492.jsonl:133857 Date.getTimezoneOffset() -> -480 y$1@5:5536
Audio 1/1/1 trace_process_12492.jsonl:133096133102138877 createOscillator()createDynamicsCompressor()getChannelData(0) HZ@5:104381
Worker 通信 4 trace_process_12492.jsonl:138820 Worker.postMessage([0]) wG@5:13193
Math 精度 1 trace_process_12492.jsonl:135830 Math.pow(Math.PI, -100) -> 1.9275814160560206e-50 dX@5:41183
媒体能力 9/7 trace_process_12492.jsonl:133555133172 navigator.mediaCapabilitiesrequestMediaKeySystemAccess("com.microsoft.playready", ...) XK/EP

静态源码对应关系在 tmp/static/37_demo.fingerprint.com_DBqbMN7zXxwl4Ei8_web_v4_ahNo3Idb3RiQg69bQglE_ci_jsl_4.0.0.js

函数 源码位置 作用
bG column 13918 创建 canvas,绘制文字和几何图形,调用 isPointInPathfillTexttoDataURL,形成 canvas.winding/geometry/text
lX column 41950 getParameter(VERSION/VENDOR/RENDERER/SHADING_LANGUAGE_VERSION),形成 webgl_basics
EX column 42660 getSupportedExtensionsgetContextAttributesgetExtension、批量 getParameter,形成 webgl_extensions
eG column 7373 getShaderPrecisionFormat,形成 shader precision 指纹
HZ column 104318 创建 OfflineAudioContext,连接 oscillator/compressor,渲染后读 getChannelData,形成 audio 数值
dX column 40497 acos/acosh/asin/asinh/atanh/exp/expm1/log1p/pow 等做浮点精度采样,形成 math hash
nB/rB/tB/TB/aB/cB columns 37078/37116/37661/38286/38577/38863 读取 oscpu/languages/hardwareConcurrency/platform/plugins/touch
AB/y$1 columns 37728/5551 读取 Intl.DateTimeFormat().resolvedOptions().timeZoneDate.getTimezoneOffset()
oB/qB columns 38063/38133 检测 sessionStorage/localStorage
s(e) column 192211 配置 apiKey、modules、worker,URL.createObjectURL(new Blob(...))new Worker(...)

首个识别请求在 tmp/trace/http_packet/000025_POST_200_demo_fingerprint_com_DBqbMN7zXxwl4Ei8_pid12988_380000057.http_packet.json

POST /DBqbMN7zXxwl4Ei8?region=us&ci=js/4.1.0&q=ahNo3Idb3RiQg69bQglE
initiator: agent js line 5 column 90905
request body: 二进制/加密编码后的 text/plain
response: {"version":"4","event_id":"1781762212213.gMJxBp","visitor_id":"orsF9S092M2X9NOJNLmr","suspect_score":15,...}

Playground 的二次查询在页面 chunk tmp/static/19_demo.fingerprint.com__next_static_chunks_2473-1eedb759263b52d2.js.js

fetch("/api/event/v4/".concat(event_id), { method: "POST" })

同一个 chunk 只负责渲染:

propertyName: "virtual_machine"
L.virtual_machine === true ? "Yes ..." : "Not detected"

这条链路证明:前端 agent 确实采集了 WebGL、Canvas、Audio、Navigator、Screen、Storage、Math、Worker 等环境信号;但是 virtual_machine=falsevirtual_machine_ml_score=0.155 是服务端事件返回,不是页面本地 if/else 算出来的。

SDK 采集了什么

从 agent 静态代码和 DOM trace 可以确认,它采集的不只是 WebGL。主要包括:

类别 证据点
WebGL getParametergetShaderPrecisionFormatgetContextAttributes
Canvas createElement("canvas")getContext("2d")fillTexttoDataURLgetImageData
Navigator userAgentplatformhardwareConcurrencypluginsmimeTypeslanguagespermissions
Screen/Window screen.width/height/availWidth/availHeight/colorDepthinner/outer
Storage localStoragesessionStorageStorage.getItem/setItem
Audio OfflineAudioContextcreateOscillatorcreateDynamicsCompressor
Worker 创建 Blob worker,采集 worker 侧 navigator / wasm 能力
时间与区域 Intl.DateTimeFormatDate.getTimezoneOffset

DOM trace 中 agent 相关调用计数节选:

Document.createElement                  238
HTMLElement.get offsetWidth             145
HTMLElement.get offsetHeight            137
Crypto.getRandomValues                  113
WebGLRenderingContext.getParameter       92
Window.get crypto                        36
Window.get localStorage                  21
WebGLRenderingContext.getShaderPrecisionFormat 12
Navigator.get plugins                     7
Navigator.get permissions                 6
HTMLCanvasElement.getContext              5
Navigator.get mimeTypes                   6
CanvasRenderingContext2D.fillText         4
HTMLCanvasElement.toDataURL               4
Screen.get width/height                   4
Navigator.get hardwareConcurrency         2
Intl.DateTimeFormat                       2

这些调用说明 Fingerprint 的虚拟机判断更像“环境一致性评分”,不是单点检测。

本次样本的原始设备属性

服务端事件里的关键 raw_device_attributes

{
  "webgl_basics": {
    "version": "WebGL 1.0 (OpenGL ES 2.0 Chromium)",
    "vendor": "Mozilla",
    "renderer": "ANGLE (Microsoft, Microsoft Basic Render Driver Direct3D11 vs_5_0 ps_5_0), or similar",
    "shading_language_version": "WebGL GLSL ES 1.0 (OpenGL ES GLSL ES 1.0 Chromium)"
  },
  "screen_resolution": [920, 1961],
  "oscpu": "Windows NT 10.0; Win64; x64",
  "hardware_concurrency": 8,
  "platform": "Win32",
  "plugins": [
    { "name": "PDF Viewer" },
    { "name": "Chrome PDF Viewer" },
    { "name": "Chromium PDF Viewer" },
    { "name": "Microsoft Edge PDF Viewer" },
    { "name": "WebKit built-in PDF" }
  ],
  "timezone": "Asia/Shanghai",
  "timezone_offset": "+08:00",
  "audio": 35.749972093850374,
  "math": "5f030fa7d2e5f9f757bfaf81642eb1a6",
  "font_hash": "1affeb088cac7b5efc90e012a4cac857"
}

这里最值得注意的是 WebGL:

ANGLE (Microsoft, Microsoft Basic Render Driver Direct3D11 vs_5_0 ps_5_0), or similar

Microsoft Basic Render Driver 通常意味着没有走真实 GPU 厂商驱动,而是走了 Windows 的基础渲染/软件回退链路。这对虚拟机检测很敏感,因为很多虚拟化、远程桌面、无 GPU 环境都会表现出类似特征。

但它不是“必杀”。本样本还有几组正常信号:

platform: Win32
oscpu: Windows NT 10.0; Win64; x64
hardware_concurrency: 8
plugins: 5 个 PDF 类插件
storage: localStorage/sessionStorage/indexedDB 可用
bot: not_detected
tampering: false

所以服务端给出的是低 ML 分数 0.155,最终 virtual_machine=false

虚拟机检测原理拆解

可把 VM 检测拆成 4 层:

1. 显式虚拟硬件标记

这是最直接的一层,主要看 WebGL renderer/vendor、系统能力和设备名中是否出现:

VirtualBox
VMware
Parallels
QEMU
SVGA
VirGL
llvmpipe
softpipe
SwiftShader
GDI Generic
Software Rasterizer

本次实测里,VMware, Inc. / SVGA3D / VMware SVGA 3D 是可以触发官方 virtual_machine=true 的强信号;VirtualBox Graphics Adapter 会触发篡改/异常侧信号,但没有单独触发 VM 最终结论。

2. 软件渲染与 GPU 回退

Microsoft Basic Render DriverSwiftShaderllvmpipe 这类不是一定等于 VM,但说明渲染链路不正常。常见来源包括:

虚拟机未安装显卡增强驱动
云桌面或远程桌面
无硬件加速的浏览器环境
反检测浏览器刻意伪造失败
系统 GPU 驱动异常或被禁用

所以它通常是“加分项”,不是“一票否决”。

3. 跨信号一致性

服务端会把多组信号放在一起看:

UA/oscpu/platform 是否一致
WebGL backend 是否符合操作系统
屏幕尺寸与 DPR 是否像真实用户设备
CPU 核心数是否过低
插件、MIME、字体、语言是否像对应浏览器
storage/indexedDB/worker/audio/canvas 是否完整
canvas、font、audio、math hash 是否稳定

例如:

UA 显示 Windows,但 WebGL 是 Apple Metal
UA 显示 macOS,但 WebGL 是 Direct3D
平台是 Win32,但没有插件、没有 storage、只有 1 核 CPU

这些组合会比单一字段更有解释力。

4. 服务端 ML/规则融合

Playground 返回了 virtual_machine_ml_score,说明至少存在模型评分结果。前端只拿最终字段展示,具体模型权重和训练特征不在前端暴露。

因此可以确定:

前端 SDK = 采集器 + payload builder + 加密提交
服务端 = 规则/模型判定
Playground = event_id 二次查询 + 展示

不能把前端 JS 中某个 WebGL 函数直接等同为完整 VM 检测算法。

参数敏感性实验

用户关心的是“到底哪个参数决定虚拟机”。直接改 /api/event/v4/{event_id} 没意义,因为这个接口只是按 event_id 查询服务端已经计算好的事件。真正影响结果的是 Fingerprint agent 的 identify POST:

POST /DBqbMN7zXxwl4Ei8?region=us&ci=js/4.1.0&q=ahNo3Idb3RiQg69bQglE
Content-Type: text/plain
body: 二进制/加密编码后的采集 payload

所以实验方法是:导航前用 page.add_preload_script() 改浏览器环境源头,让官方 SDK 正常采集、正常打包、正常提交,再读取对应 /api/event/v4/{event_id} 的服务端结果。脚本在:

tmp/vm_signal_matrix.py

复现命令:

python tmp/vm_signal_matrix.py --cases baseline webgl_nvidia webgl_virtualbox webgl_vmware webgl_swiftshader low_cpu_only storage_disabled combined_vm webgl_vmware_vendor_only webgl_svga_renderer_only webgl_vmware_angle_renderer --wait 45

python tmp/vm_signal_matrix.py --summarize-existing --cases baseline webgl_nvidia webgl_virtualbox webgl_vmware webgl_swiftshader low_cpu_only storage_disabled combined_vm webgl_vmware_vendor_only webgl_svga_renderer_only webgl_vmware_angle_renderer

完整结果在:

tmp/vm_matrix/results.json
tmp/vm_matrix/results.md

本次 11 组结果如下:

case 改动 服务端采到的关键 WebGL virtual_machine VM ML tampering suspect
baseline 不注入 Mozilla / Microsoft Basic Render Driver false 0.103 false 15
webgl_nvidia 物理 NVIDIA renderer Google Inc. (NVIDIA) / NVIDIA GeForce RTX 3060 false 0.104 true 23
webgl_virtualbox VirtualBox renderer Oracle Corporation / VirtualBox Graphics Adapter false 0.132 true 15
webgl_vmware VMware + SVGA3D VMware, Inc. / SVGA3D; build: RELEASE; LLVM; true 0.109 true 29
webgl_swiftshader SwiftShader Google Inc. / Google SwiftShader false 0.118 true 15
low_cpu_only CPU=2 原始 Basic Render Driver false 0.148 false 7
storage_disabled indexedDB 不可用 原始 Basic Render Driver false 0.070 false 7
combined_vm VirtualBox + CPU=2 + 空插件 + 小屏 + indexedDB 不可用 Oracle Corporation / VirtualBox Graphics Adapter false 0.195 true 15
webgl_vmware_vendor_only 只改 vendor=VMware, Inc. VMware, Inc. / 原始 Basic Render Driver true 0.104 true 29
webgl_svga_renderer_only 只改 renderer=SVGA3D Mozilla / SVGA3D; build: RELEASE; LLVM; true 0.164 false 21
webgl_vmware_angle_renderer ANGLE 形式 VMware SVGA 3D Mozilla / ANGLE (VMware, VMware SVGA 3D Direct3D11...) true 0.077 false 21

关键证据文件:

baseline:
tmp/vm_matrix/baseline/http_packet/000029_POST_200_demo_fingerprint_com_api_event_v4_1781765779900_oPqQNf_pid4172_40000005c.http_packet.json

VirtualBox:
tmp/vm_matrix/webgl_virtualbox/http_packet/000029_POST_200_demo_fingerprint_com_api_event_v4_1781765826280_hwq3pk_pid4936_40000005d.http_packet.json

VMware + SVGA3D:
tmp/vm_matrix/webgl_vmware/http_packet/000029_POST_200_demo_fingerprint_com_api_event_v4_1781765998121_ILLq9R_pid4952_40000005d.http_packet.json

只改 VMware vendor:
tmp/vm_matrix/webgl_vmware_vendor_only/http_packet/000029_POST_200_demo_fingerprint_com_api_event_v4_1781766299834_Ur96rm_pid13596_40000005d.http_packet.json

只改 SVGA3D renderer:
tmp/vm_matrix/webgl_svga_renderer_only/http_packet/000029_POST_200_demo_fingerprint_com_api_event_v4_1781766345049_n6NC0P_pid5328_40000005d.http_packet.json

ANGLE 形式 VMware renderer:
tmp/vm_matrix/webgl_vmware_angle_renderer/http_packet/000029_POST_200_demo_fingerprint_com_api_event_v4_1781766391556_CEMPGs_pid15880_40000005d.http_packet.json

可直接确认的结论:

1. 当前服务端 VM 最终布尔值最敏感的是 WebGL vendor/renderer 中的 VMware/SVGA 特征。
2. vendor=VMware, Inc. 单独足以触发 virtual_machine=true。
3. renderer=SVGA3D 单独足以触发 virtual_machine=true,而且这一组 tampering=false,说明它不是靠“补丁被发现”才判 VM。
4. renderer=ANGLE (VMware, VMware SVGA 3D Direct3D11...) 也触发 virtual_machine=true。
5. VirtualBox Graphics Adapter、SwiftShader、低 CPU、indexedDB 不可用、空插件组合,在本次实验里都没有触发 virtual_machine=true。
6. WebGL 字段被 JS preload 改写时,经常会触发 tampering=true;但 tampering 和 virtual_machine 是两套不同信号,不能混为一谈。

一个反直觉点:virtual_machine_ml_score 不是最终布尔值的简单阈值。比如 webgl_vmware_angle_renderer 的 ML 分数只有 0.077,但 virtual_machine=truecombined_vm 的 ML 分数 0.195 更高,却仍是 false。这说明服务端很可能是“规则命中 + ML 分数”融合:VMware/SVGA 这类字符串更像明确规则命中,Basic Render Driver、低 CPU、存储异常更像模型/异常分。

本地纯算实现

我在 src/vm_risk.py 写了一个可解释的本地纯算版本,用来复现“信号如何合成风险”的思路。

它不复刻 Fingerprint 私有模型,只做可解释规则:

明确 VM renderer: 高权重
软件/回退 renderer: 中低权重
ANGLE backend: 低权重上下文信号
低 CPU / 空插件 / 小屏 / webdriver / OS 渲染链不一致: 辅助权重
score >= 0.6 或命中明确 VM renderer 才判 vm_detected=true

运行真实服务端事件包:

$env:PYTHONIOENCODING='utf-8'
python src/vm_risk.py tmp/trace/http_packet/000028_POST_200_demo_fingerprint_com_api_event_v4_1781762212213_gMJxBp_pid12988_38000005a.http_packet.json

输出:

{
  "vm_detected": false,
  "score": 0.34,
  "risk_level": "low",
  "flag_ids": [
    "webgl_software_renderer",
    "webgl_angle_backend"
  ],
  "facts": {
    "webgl_vendor": "Mozilla",
    "webgl_renderer": "ANGLE (Microsoft, Microsoft Basic Render Driver Direct3D11 vs_5_0 ps_5_0), or similar",
    "hardware_concurrency": 8.0,
    "platform": "Win32",
    "oscpu": "Windows NT 10.0; Win64; x64",
    "screen_resolution": [920, 1961],
    "plugins_count": 5
  }
}

这个结果和服务端趋势一致:有风险信号,但不够判虚拟机。

测试:

python -m unittest tests/test_vm_risk.py

测试覆盖了:

Microsoft Basic Render Driver: 有风险信号,但不单独判 VM
VirtualBox/SVGA3D/VMware renderer: 本地规则按明确 VM renderer 处理
普通 NVIDIA/Intel/AMD 实体 GPU: 低风险
http_packet responseBody.text 包装输入
[920,1961] 这种分辨率顺序不误判小屏
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐