一、32个账号,一部"手机"
深圳一家做TikTok内容分发的团队,六个人,两个剪辑、三个运营、一个技术。他们的做法在2024到2025年很常见:一台256G内存的工作站,跑安卓模拟器,模拟器里开多个安卓实例,每个实例登一个TikTok账号,一共32个。代理用的是按量计费的住宅IP,每个实例绑一条。内容侧做得不差,选题跟得上,剪辑水准在同类账号里属于中上。
第9天开始出事。先是7个账号的新发视频播放量从平均4200掉到200以内,评论区还在,点赞掉到个位数。运营以为是内容问题,换了两版选题,没用。第13天,21个账号进入同一个状态,视频发布后停留在"正在处理"超过40分钟,发布成功但搜索不到。第15天,其中6个账号直接收到封禁提示,登录页面弹出的原文是:Your account was permanently banned due to multipleviolation so four Community Guidelines。另外还有4个账号在换设备登录时被拦,提示Too many attempts.Pleasetryagainlater,换IP也没用。
技术同事接手排查,用adb连进每个模拟器实例做了一轮设备参数导出,结果很干净利落。
32个实例的AndroidID有19个完全相同,因为模拟器的镜像是同一份克隆出来的,SSAID的生成种子没变。IMEI里有28个是同一串以35开头的默认值,剩下4个是运营手动改的,但改法是同一个补丁工具生成的连号。Build.FINGERPRINT全部指向同一个字符串,品牌写的是samsung,但ro.product.cpu.abilist里第一位是x86_64。GSFID因为共用了同一份Google服务框架数据目录,有11个重复。最要命的是传感器:加速度计三轴读数在所有实例里都是恒定的0.0/9.81/0.0,一动不动,连一丝噪声都没有。
一台真机放在桌上不动,加速度计也会有±0.02到±0.05量级的抖动,这是MEMS器件的固有噪声。32台设备同时静止在小数点后一位都不差的数值上,这在任何一个风控模型里都是极强的聚类特征。
平台从来不需要证明你在做什么,它只需要证明这32个"设备"是同一个东西。
二、Web端指纹和移动端指纹,不是同一套东西
这件事必须先掰开。很多从PC端多账号管理迁移过来的团队,会下意识把Web端那套认知套到安卓上,然后踩坑。
浏览器里的指纹,本质是间接推断。Canvas渲染出来的PNG做哈希、WebGL读UNMASKED_RENDERER_WEBGL、AudioContext跑一段OfflineAudioContext算浮点尾数、字体枚举、屏幕分辨率、时区偏移。这些数据的共同点是:浏览器沙箱不允许你直接读硬件序列号,只能通过渲染差异去反推硬件型号。所以Web端的指纹是概率性的、可漂移的、需要多维交叉才能定位到人。
安卓App不一样。App跑在系统里,只要权限给到,很多标识是直接读出来的,不需要推断。TelephonyManager.getImei()拿到的就是IMEI本身,Settings.Secure.ANDROID_ID拿到的就是SSAID本身。这是确定性标识,一个字段就能定位。
从Android10开始,Google把READ_PHONE_STATE拿IMEI这条路封了,普通App调getImei()会抛SecurityException,需要READ_PRIVILEGED_PHONE_STATE这个签名级权限。这确实堵掉了一部分,但风控方立刻换了替代方案:WidevineDRMID(MediaDrm的deviceUniqueId属性)、GSFID(从com.google.android.gsf的contentprovider读)、AdvertisingID、以及最重要的——多个弱标识的组合哈希。
所以移动端的对抗层级更深。Web端你改浏览器就行,移动端你得改到系统层,甚至硬件层。
维度 |
Web浏览器端 |
安卓App端 |
标识获取方式 |
渲染差异反推 |
系统API直接读取 |
典型强标识 |
无,全为弱标识 |
IMEI、SSAID、DRMID |
采集权限门槛 |
无需授权 |
部分需运行时权限 |
可读系统信息 |
UA、时区、语言 |
Build全量、prop、proc |
硬件传感器 |
基本不可读 |
加速度陀螺磁力可读 |
native层检测 |
不适用 |
可直读maps与syscall |
指纹稳定性 |
可漂移,需交叉 |
单字段即可定位 |
改造成本 |
浏览器内核层 |
系统层或硬件层 |
表1:两端采集面的层级差异,决定了对抗方案不能通用
三、Android设备指纹的五层采集面,逐层说清楚
3.1硬件标识层:确定性强度居前的一批
这一层是风控的首要优先级,因为它不依赖行为、不依赖内容、单字段就能建立强关联。
IMEI/MEID:15位(MEID为14位十六进制)。IMEI的前8位是TAC(型号分配码),直接对应机型。这里有个容易忽略的坑:如果你把机型伪装成Pixel7,但IMEI的TAC段落属于某个国产品牌,一致性校验立刻挂掉。改IMEI不是随便生成15位数字,第15位是Luhn算法校验位,TAC段要和声称的机型对得上。
AndroidID(SSAID):从Android8.0开始,SSAID的生成规则改成了「应用签名密钥+用户+设备」三元组的哈希。同一台设备上不同签名的App拿到的SSAID不同,但同一个App在同一台设备上永远相同。恢复出厂设置会重置。它是App侧最常用的设备标识。
GSFID:Google服务框架ID,16位十六进制,从content://com.google.android.gsf.gservices查询android_id得到。它和Google账号体系强绑定,Google系产品(包括Play商店、YouTube)以及大量依赖GMS的第三方App都会读。克隆镜像时如果连/data/data/com.google.android.gsf一起复制,GSFID就会撞车,这是模拟器方案里最高频的翻车点之一。
WidevineDRMID:通过MediaDrm(WIDEVINE_UUID).getPropertyByteArray("deviceUniqueId")获取。这个值在Android8以后按App区分,但在很多定制ROM和模拟器上处理不干净,会出现跨App一致甚至跨设备一致的情况。视频类平台(TikTok、YouTube、Netflix)对它敏感度很高,因为DRM本来就是它们的基础设施。
Build.SERIAL:Android8.0之后返回"unknown",但ro.serialno/ro.boot.serialno这两个系统属性在有shell权限时仍可读,一些SDK会通过native层的__system_property_get去拿。
MAC地址:Android6.0之后WifiInfo.getMacAddress()统一返回02:00:00:00:00:00,但/sys/class/net/wlan0/address这个节点在部分ROM上仍然可读。另外Android10引入了每个SSID随机化MAC,如果一批"设备"连的是同一个SSID却用同一个MAC,那就是明显异常。
3.2系统属性层:一致性比数值本身更重要
这一层特别考验功力。不是"改成什么"的问题,而是"改完之后彼此对不对得上"的问题。
Build.FINGERPRINT的标准格式是:brand/product/device:release/id:type/tags。举个真实格式的例子,google/panther/panther:14/UP1A.231105.001/10817346:user/release-keys。风控侧会做的事情很朴素——把这个字符串拆开,逐段和ro.product.brand、ro.product.name、ro.product.device、ro.build.version.release、ro.build.id、ro.build.type、ro.build.tags逐一比对。任何一段对不上,直接标记。
然后是横向对照。声称是Pixel7(代号panther),那么ro.board.platform应该是gs201,ro.hardware应该是panther,屏幕分辨率应该是1080x2400,DPI420,ro.product.cpu.abilist应该只有arm64-v8a,armeabi-v7a,armeabi。如果你的abilist里出现x86_64,机型伪装再完美也没用。
SELinux状态:getenforce返回Enforcing是正常量产机的状态,返回Permissive基本等于宣告这台设备被改过。/sys/fs/selinux/enforce读出来应该是1。
/proc与/sys下的可读节点是native层检测的主战场:
· /proc/cpuinfo里的Hardware字段和CPUpart编号,能直接看出是不是真实ARMSoC
· /proc/self/maps能看到进程加载的所有so,注入型框架会在这里留痕
· /proc/net/tcp能看到本地监听端口,某些调试框架会开固定端口
· /sys/class/thermal/thermal_zone*/temp温度曲线,虚拟环境往往恒定或缺失
· /proc/uptime与SystemClock.elapsedRealtime()的差值,异常时说明时间被改过
3.3传感器层:伪造难度居前的一层
开头那个案例栽在这儿。传感器不是"有没有"的问题,是"像不像"的问题。
加速度计:静置时三轴合成模值应该接近9.78到9.83(随纬度变化),单轴噪声标准差在0.01到0.06之间,且噪声是白噪声特征。手持时会有0.5Hz到3Hz的低频抖动,那是人手的生理性震颤。
陀螺仪:静置零偏不为零,通常在±0.01rad/s量级,且零偏会随温度缓慢漂移。一台真机开机半小时后的零偏和刚开机时是不一样的。
磁力计:受机身内部电流影响,读数会随屏幕亮度、充电状态变化。同一批"设备"如果磁力计读数完全一致,等于告诉平台它们跑在同一个虚拟层上。
触摸事件:MotionEvent里的getPressure()和getSize()才是重点。真人手指按下去,压力值是从0快速上升到峰值再缓慢回落的曲线,接触面积随压力同步变化。脚本注入的点击事件,pressure往往是恒定的1.0,size恒定的0.0或某个固定值。滑动轨迹上,真人的采样点间距是变加速的,机器生成的往往是等距或标准贝塞尔曲线。
3.4网络与运营商层:一致性校验的重灾区
这一层的问题不在于单个字段,在于交叉矛盾。
SIM侧:MCC/MNC(如印尼Telkomsel是51010,泰国AIS是52003,美国T-Mobile是310260)、SIM序列号ICCID、运营商名称、SIM国家码。基站侧:CID、LAC、信号强度。WiFi侧:BSSID、SSID、连接的AP厂商OUI段。
然后是IP。一台声称在雅加达、SIM是Telkomsel、时区Asia/Jakarta的设备,出口IP如果解析到美国某数据中心,这不是"可疑",这是"确定"。反过来,SIM显示无卡但WiFi在雅加达、IP也在雅加达,反而正常得多——很多东南亚用户就是WiFi设备。
另一个高频翻车点:一批设备用同一个代理服务商的相邻IP段。IP不同了,但ASN相同、地理位置精确到同一个坐标、TTL和TCP指纹(MSS、窗口大小、时间戳选项顺序)完全一致。这种情况在网络层就完成了聚类,设备参数改得再干净也没用。
3.5应用与使用痕迹层:软信号,但权重在涨
已安装应用列表:Android11引入包可见性限制,需要QUERY_ALL_PACKAGES权限或在manifest里声明queries白名单。但很多头部App都申请了这个权限。一批设备如果装的App完全一样、包名列表哈希一致、连安装顺序都相同,这个信号很强。
输入法列表、系统字体列表、系统语言与地区、电池健康度(BatteryManager的BATTERY_PROPERTY_CAPACITY和充电循环数)、开机时长、屏幕亮度历史、通知渠道配置。
这一层单看每个都很弱,组合起来做哈希就变强了。风控侧的常见做法是把这一层的十几个字段拼成一个soft_fingerprint,参与最终的相似度打分,权重不高但足以在硬标识都改干净之后完成补刀。
层级 |
典型字段 |
标识强度 |
变更难度 |
硬件标识层 |
IMEI、SSAID、DRMID |
极强 |
系统层深度改 |
系统属性层 |
Build.FINGERPRINT |
强 |
需全量一致 |
传感器层 |
加速度陀螺噪声 |
中强 |
需物理器件 |
网络运营商层 |
MCC/MNC、BSSID |
强 |
需真实链路 |
应用痕迹层 |
应用列表、字体 |
弱,组合后中 |
运营侧可控 |
表2:越靠上越难改,越靠下越依赖日常运营习惯
四、代码:平台侧的一致性校验是怎么写的
下面这段是adb侧的快速体检,用来在部署环境之前自己先跑一遍。逻辑很简单,把风控会读的字段一次性导出来,人工看矛盾点。
第二段是Kotlin,模拟平台SDK侧的校验逻辑。真实的商业SDK会做得更狠,包括native层的so自校验、反调试、字符串加密,这里只保留判定骨架。
第5条那个PROP_LAYER_INCONSISTENT是重点。Java层的Build.MODEL是静态字段,在Zygote进程启动时就填好了;native层的__system_property_get每次调用都会去读共享内存里的property区。Xposed类框架hook的是Java层,如果没有同步处理native层,这两个值就会打架。这也是为什么框架层改机方案在有native检测的App面前很难过关。
第三段是风控侧的设备聚类,Python伪代码,讲清楚思路就够了。
注意LINK_SOFT那条线。真实系统里,落在软阈值区间的设备不会立刻处置,而是被打上标记进观察队列,等待行为侧信号叠加。开头案例里"第9天开始限流、第13天扩大、第15天封禁"的节奏,很符合这种先观察后处置的策略。它给了运营方一个错觉:前八天都好好的,说明方案没问题。实际上第一天就已经被聚成一簇了。
五、三条技术路线:模拟器、Root改机、ARM真机
把这三条路摊开讲,各自的优点和硬伤都说。
安卓模拟器(含各类PC端安卓容器)。底层是x86/x86_64的CPU,跑ARM的so需要libhoudini或libndk_translation做二进制转译。优点很实在:成本低,一台工作站能开十几个实例,本地调试方便,图形性能靠宿主GPU,跑游戏很流畅。硬伤在于它的"出身"藏不住——ro.kernel.qemu、/dev/qemu_pipe、Hardware字段里的ranchu/goldfish、abilist里的x86_64、以及那套完全静止的虚拟传感器。这些特征可以逐个打补丁,但检测方只需要命中其中一条。而且转译层本身有性能指纹:同样一段ARMnative代码,在转译环境下的执行耗时分布和真机不一样,做过精细化检测的SDK会测这个。
Root改机(Magisk+LSPosed/Xposed系)。跑在真实ARM手机上,硬件底子是真的,这是它的核心优势。改机模块hookframework层的Build字段、TelephonyManager、SensorManager,把参数换掉。对于只做Java层采集的App,这套方案效果不错,而且灵活,模块可以自己写。硬伤有三个:一是hook痕迹在native层藏不住,/proc/self/maps里的so路径、inode异常、以及前面说的Java层与native层prop不一致;二是Magisk的DenyList和检测方一直在军备竞赛,Momo、NativeDetector这类工具能查出来的项每半年都在增加;三是PlayIntegrityAPI出来之后,Root设备基本拿不到MEETS_DEVICE_INTEGRITY,更别说MEETS_STRONG_INTEGRITY,这对依赖GMS的场景是硬门槛。另外还有个现实问题:一台真机只能跑一套环境,规模上去之后设备采购、供电、网络、机架管理全是成本。
ARM真机云手机。远端机房里放的是ARM架构的物理卡板,一块卡板上跑若干个独立的完整Android系统实例,通过串流把画面推给用户,用ADB和API做控制。它的技术合理性在于:CPU是真的ARM,abilist天然是arm64-v8a,没有转译层;传感器可以由卡板上的真实器件或硬件级模拟提供;参数变更做在系统层甚至更底层,而不是靠hookframework。国内外做这个方向的产品有若干家,MostLogin的云手机是其中之一,它的实现路径是远端高性能ARM物理卡板独立运行完整Android系统,对IMEI、MAC地址、SIM运营商信息做深度虚拟和变更,并同时开放ADB与ROOT权限供自定义脚本使用;同类方案还有MoreLogin云手机、DuoPlus、FoxPhone、CloudPhones等,各家在卡板密度、参数可配置粒度、代理绑定方式上各有取舍。
ARM云手机的问题也要说清楚,我见过太多把它当银弹的。一是出口网络是共享机房链路,如果不绑定独立代理,一批实例的出口ASN和TCP指纹会高度一致,网络层直接聚类,设备层做得再好也白搭。二是多数云手机镜像为了给用户开放ADB和ROOT,本身就不是GMS认证的量产镜像,PlayIntegrity的强完整性判定大概率过不了,对高度依赖硬件attestation的场景不适用。三是串流有延迟,一般在30到120毫秒之间,对操作节奏敏感的场景会引入行为异常。四是成本比模拟器高一个量级。
还有一点,任何方案都不解决行为层的问题。工具提供的是环境层的隔离能力,不提供行为层的豁免。这话听着像免责声明,但它是这一行很关键的经验。
对比维度 |
安卓模拟器 |
Root改机真机 |
ARM物理卡板云手机 |
CPU架构 |
x86转译ARM |
原生ARM |
原生ARM |
abilist特征 |
含x86,易识别 |
干净 |
干净 |
参数变更层级 |
虚拟机配置层 |
framework层hook |
系统层与硬件层 |
native检测抗性 |
弱 |
中,maps有痕迹 |
较强 |
传感器真实度 |
多为静态死值 |
真实器件读数 |
器件或硬件级模拟 |
单环境成本 |
低 |
中高,含硬件 |
中 |
规模化难度 |
低 |
高,需机架管理 |
低,云端弹性 |
PlayIntegrity |
基本不通过 |
通常不通过 |
视镜像而定 |
自动化接入 |
ADB可用 |
ADB可用 |
ADB与RESTAPI |
网络出口风险 |
需逐实例绑代理 |
可用SIM流量 |
需逐实例绑代理 |
典型短板 |
出身特征难清干净 |
hook痕迹与GMS |
串流延迟与共享链路 |
表3:没有一条路线在所有维度占优,选型取决于目标平台的检测深度
六、云手机的分层架构,一层层看清楚
把云手机拆开看,它是五层结构,每一层出问题的表现完全不同。理解这个分层,排障的时候能少走很多弯路。
最底下是物理ARM卡板。一块卡板通常是一颗中高端移动SoC加上内存和存储,机架式插在服务器里。这一层决定了CPU架构、真实的/proc/cpuinfo内容、GPU型号、以及是否有真实的传感器器件。卡板的密度(一块卡板跑几个实例)直接影响性能和参数独立性。
往上是独立Android实例。每个实例是一套完整的Android系统,有自己的/data分区、自己的用户空间、自己的进程树。关键在于"独立"这两个字的实现深度——是共享内核的容器化隔离,还是每个实例独占一套系统。前者密度高但内核级信息(如/proc/version、boot_id、uptime)容易穿透;后者独立性好但成本高。
第三层是设备参数虚拟化层。IMEI、MAC、SIM运营商信息、Build属性族、传感器数据在这里被改写。做得好的实现会保证一致性联动:改了机型,abilist、分辨率、DPI、GPUrenderer字符串、传感器型号列表全部跟着变,而不是只改一个Build.MODEL完事。判断一家产品这一层做得深不深,有个简单办法:看它是否会根据所选机型自动匹配对应的芯片参数,把IMEI、MAC、传感器读数一并做硬件级还原。MostLogin的云手机在产品文档里描述的就是这个思路,加上语言、时区、SIM、运营商的联动配置;具体到不同机型库的覆盖度,各家差异比较大,选型时值得拿几个冷门机型试一下。
第四层是网络出口绑定。每个实例绑一条独立代理,走HTTP/HTTPS/Socks5。这一层如果偷懒,前三层全部作废。
最上面是控制面:ADB通道、RESTAPI、脚本执行。这一层决定了自动化能做到什么程度,也决定了团队协作时的权限边界。开放ADB和ROOT意味着你能自己写脚本、自己装检测工具、自己核对参数,这对做技术验证的团队很重要;代价是前面说过的PlayIntegrity问题。这是一组需要自己权衡的取舍,不存在两头都占的方案。
层级 |
承载内容 |
关键技术点 |
典型故障表现 |
物理ARM卡板 |
SoC、GPU、器件 |
卡板密度与散热 |
性能抖动,温度异常 |
独立Android实例 |
完整系统与分区 |
隔离深度 |
boot_id或uptime雷同 |
参数虚拟化层 |
IMEI/MAC/SIM/Build |
一致性联动 |
机型与ABI矛盾 |
网络出口绑定 |
代理与DNS |
逐实例绑定 |
ASN聚类,DNS泄露 |
控制面 |
ADB与RESTAPI |
权限与审计 |
脚本行为过于规整 |
表4:从下往上排障,先确认底层再看上层
七、平台与地区的风险信号差异
把所有平台当成一样对待,是另一个常见错误。同一个信号,在不同平台不同地区的权重差别很大。
TikTok在东南亚市场(印尼、越南、泰国、菲律宾)的用户设备构成非常碎片化,大量千元级安卓机,系统版本从Android9到Android14都有,同一个WiFi下多个账号在网吧和家庭场景里也很常见。所以纯粹的"同IP多账号"在这个市场的判定权重相对温和。但对设备标识的重复度非常敏感——因为它是内容分发平台,重复设备意味着可能的流量操纵。
TikTok在北美市场逻辑不同。设备构成集中(iPhone占比高,安卓这边Samsung和Pixel为主),住宅IP的地理精度高,运营商体系规范。这边对IP质量的要求明显更高,数据中心IP和低质量住宅代理很容易被识别。同时北美对内容合规的审查更重,很多"限流"其实是内容策略而非设备关联。
Instagram的特点是账号资料完整度和社交图谱权重高。一个新注册账号,如果没有头像、没有简介、粉丝关注比异常、并且和一批同样特征的账号互相关注,社交图谱层面的关联信号比设备层还强。Meta在图谱分析上的积累很深。
Facebook是目前少数几个能找到相对可比的公开独立测试数据的场景。有一组被行业反复引用的测试结果:Multilogin在Facebook场景的封号率6.7%,BitBrowser(比特浏览器)约20%,GoLogin约40%。
上述数据引自公开的第三方独立测试报告,仅覆盖Facebook单一平台。该测试的样本量、代理质量、行为脚本设计、观察周期均未公开对齐,不同测试方的方法学差异可能显著影响结果,不能外推到TikTok、Instagram或任何移动端场景。其余厂商在该场景暂无公开独立测试数据。
把它写在这里,不是为了排座次,而是为了说明一件事:即便是有公开数据的场景,数据的可比性也是有限的。移动端云手机领域至今没有类似口径的公开独立测试,任何声称自己在移动端有精确封号率数字的说法,都值得追问一句测试方法是什么。
平台与地区 |
首要关联信号 |
次级信号 |
容忍度倾向 |
TikTok东南亚 |
设备标识重复 |
内容重复度 |
对同IP相对温和 |
TikTok北美 |
IP质量与归属 |
内容合规 |
对机房IP敏感 |
Instagram全球 |
社交图谱关联 |
资料完整度 |
新号动作敏感 |
Facebook全球 |
设备与Cookie关联 |
注册手机号段 |
验证链路严格 |
Google生态 |
GSFID与账号历史 |
硬件attestation |
依赖设备完整性 |
表5:信号权重按平台调整,不存在一套通用配置
八、一份可以直接照着跑的自检清单
部署完环境不做验证就上账号,等于闭着眼睛开车。下面这套清单是可执行的,工具都是公开可得的。
第一轮,系统层自检。用DevCheck或DeviceInfoHW这类App看基础信息,重点核对四件事:CPU架构显示是否为arm64-v8a且不含x86;机型、品牌、Build号三者是否与真实机型库对得上;SELinux状态是否为Enforcing;系统版本与安全补丁日期是否合理(Android14配一个2019年的安全补丁日期就很奇怪)。
第二轮,改机痕迹检测。Momo(检测能力覆盖较广的开源检测工具)和NativeDetector是常用的两个。看的是:有没有检测到hook框架、native层与Java层的prop是否一致、是否存在异常的so映射、是否有调试端口监听。这一轮如果全绿,说明环境的"出身"处理得比较干净。
第三轮,完整性证明。用PlayIntegrityAPIChecker跑一次,看返回的是MEETS_BASIC_INTEGRITY、MEETS_DEVICE_INTEGRITY还是MEETS_STRONG_INTEGRITY。这里要现实一点:开放了ROOT权限的云手机环境,通常拿不到DEVICE级以上。如果你的目标平台强依赖这个(比如某些金融类、Google深度绑定的场景),那这条路线本身就不适配,换方案比调参数有意义。
第四轮,传感器验证。用任意传感器读数App,静置观察加速度计30秒。合格标准:三轴合成模值在9.7到9.9之间,单轴数值在小数点后两位上持续变化,不是死值。摇一摇设备(云手机可通过控制面模拟),看陀螺仪是否有对应响应。
第五轮,网络层验证。在设备浏览器里访问IP检测站点,核对:出口IP的地理位置与设备时区、系统语言、SIM运营商是否自洽;DNS解析走的是不是同一出口(避免DNS泄露);WebRTC是否暴露内网地址;ASN是否为住宅类型而非数据中心。这一轮同时要横向对比一批设备——如果十台设备的出口ASN相同,那就是问题。
第六轮,横向去重。这一步很容易被跳过,也很关键。把一批设备的关键字段全导出来,做一次自查式的聚类,就用前面那段Python的思路。自己先跑一遍平台会跑的逻辑,看看自己的设备池能不能被自己聚成一簇。设备多的时候手工导出不现实,看产品有没有开放RESTfulAPI——MostLogin、AdsPower、比特浏览器这几家都提供了不同形式的接口,能把环境参数批量拉出来喂给脚本;接口的字段完整度各家不同,有的只暴露配置项不暴露实际生效值,这种就得配合ADB再核一遍。
自检轮次 |
检测手段 |
通过判据 |
系统层信息 |
DevCheck等信息App |
ABI纯净,机型自洽 |
改机痕迹 |
Momo、NativeDetector |
无hook痕迹与端口 |
完整性证明 |
PlayIntegrityChecker |
按目标平台需求取舍 |
传感器 |
传感器读数App |
静置有噪声非死值 |
网络出口 |
IP与DNS检测站点 |
地理时区SIM三者一致 |
横向去重 |
自建聚类脚本 |
两两相似度低于阈值 |
表6:六轮全过不代表安全,但任何一轮不过基本可以确定有问题
环境隔离解决的是"你看起来不像同一个人",解决不了"你做的事情不像人"。前者是工程问题,后者是运营问题,把两者混为一谈是这一行代价很高的学费。
回到开头那32个账号。他们后来换了ARM真机云手机方案,重建了18个环境,逐个做完六轮自检才上号,三个月内没有再出现批量异常。但有意思的是,其中还是有2个账号被限流了,排查下来是内容侧的问题——搬运素材做二次剪辑,被内容指纹识别了。这恰好印证了那句话:环境层做干净,只是把牌桌上的一半问题解决了。