揭秘-Android刷量有多容易

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: 做互联网开发的同学可能对流量这个词很熟悉,在互联网行业中对一个产品的质量有一些关键指标,比如日活DAU,比如次日留存,点击率。

做互联网开发的同学可能对流量这个词很熟悉,

在互联网行业中对一个产品的质量有一些关键指标,比如日活DAU,比如次日留存,点击率。

往往评估一个产品的变现能力会通过日活来计算。

因此也就诞生了一些灰色产业,专门在日活上做文章。

而作为金主(广告主)来说,如何判断一个产品的真实日活就显得非常重要了。

行业潜规则里,你自己家给的日活数据都要打个折。。除非能提供一些第三方的统计数据。

今天要说的是一个设计不完善的DAU系统有多容易伪造数据。

刷量手段

现在市面上做Android灰色产业的技术手段离不开这几种

· 协议破解

· 伪造用户操作

· 伪造用户数据

我们以其中"伪造用户数据"这一点为例子来展示一下如何通过技术手段实现用一个手机让一个app日活过百的。

一个正常的日活

首先我挑选了一个国外的小众SDK,类似于友盟这种有日活统计功能的。

下面是在我开始刷量之前的数据,

记住哦,从这里开始我都只用了两台手机。

可以看到DAU在3/6之前不超过5(当然这里面超过2的那些是google play上的其他真实用户)。

开始破解

首先需要确定的是它用哪个指标来进行用户唯一性的判断,

这里我通过抓包分析它的接口数据如下,

{
 "advertiser_id": "966694c4-05fa-4020-a39c-ad3bced26b62",
 "carrier": "",
 "custom_id": "",
 "screen_height": 1920,
 "screen_width": 1080,
 "limit_tracking": false,
 "ln": "zh",
 "locale": "CN",
 "device_brand": "Xiaomi",
 "device_model": "MI MAX",
 "device_type": "tablet",
 //省略无关数据
 "device_time": 1526006628156,
 "controller_version": "1.0.9.16",
 "user_metadata": {},
 "device_audio": false,
 "test_mode": false,
 "guid": "395fce37-55c3-410e-bdb8-7d20fad3c14e",
 "guid_key": "395fce37-55c3-410e-bdb8-7d20fad3c14eDUBu6wJ27y6xs7VWmNDw67DD"
}

乍看下来没发现什么特别的字段,起码没有我想象中应该出现的 device_id这种字段。

但是我发现了一个熟悉的数据模式

"advertiser_id": "966694c4-05fa-4020-a39c-ad3bced26b62",

做过SDK相关的同学会知道,这个字段跟UUID一模一样,

那么这个UUID是从哪里来的呢?

进一步猜测

到这里开始陷入僵局,接下来有两种可能性,

· sdk在app第一次启动的时候生成了UUID

· sdk在上报数据的时候从GP取的UUID

做过海外的同学可能了解,GP本身也有一个AdvertisingIdClient.Info,可以获取设备唯一性识别码,而这个编码跟上面接口中的数据长的也是一样的。

如果是第二种可能的话,要破解就比较麻烦了。

那么我们从简单的第一个可能下手。

如果把gms service删了会怎样?这样就能排除 gp的干扰了。

在这个思路下,我把手机的 GMS框架删掉后重新请求了数据,

这时候的接口数据变成下这样了,

{
 "advertiser_id": "",
 "device_id": "97b4cf89a32c3ddb08c1ee0be43d827b129a134b",
}

上面的接口数据只列出了前后的差异,并不是只有这两条哦。

可以看到原本的跟UUID一模一样的字段变空了,取而代之的是多了个 device_id字段,

也就是说,

这个SDK 在国内环境下(没有谷歌的环境)用了另一套机制用来确定设备唯一性,

然而这里再次陷入僵局。

这一长串字符是什么玩意?

山穷水尽疑无路

这个时候开始基本就是靠猜了,

一般用来确定设备唯一性的数据有这个几个

· UUID

· android_id(通过 Setttings获取)

· IMEI/MEID等移动设备唯一编号

对于上面这几种可能来说,比较可能的是第二第三个数据,

第一个为什么被我排除了呢,

因为考虑到 device_id 应该是经过了加密,而UUID加密不出来这样的字段,所以我们可以先从第二个可能性开始。

接下来就是确定它的加密方式了!

一般常见的加密方式,不外乎 md5/sha1这些,可以先暴力猜测一下,顶多20分钟就可以知道结果。

5分钟后。。。

运气不错,当尝试到 android_id + sha1 组合的时候就得到了接口中的 device_id数据。

数据有了,接下来的思路就是用 Xposed框架来 hook获取 android_id的接口了,

相对于上面的破解过程,Xposed的代码非常简单,

private void hookAndroidID(XC_LoadPackage.LoadPackageParam lpparam, final DeviceInfo info) {
 XposedBridge.log("[methodhook] hookAndroidID()");
 XposedHelpers.findAndHookMethod(Settings.Secure.class.getName(), lpparam.classLoader, "getString", ContentResolver.class, String.class, new XC_MethodHook() {
 @Override
 protected void afterHookedMethod(MethodHookParam param) throws Throwable {
 XposedBridge.log("[afterHookedMethod] hookAndroidID: " + (String)info.getAndroidId());
 param.setResult((String)"whatever you want");
 super.afterHookedMethod(param);
 }
 });
}

在hook了这个方法之后,每次sdk要去拿 android_id,都会被替换成我们设置进去的假数据。

伪造后的日活

下面来看看在经过破解之后的数据吧,

看看这暴涨100倍的日活。

如何防御刷量

其实关于破解和加密一直都是魔高一丈道高一尺的博弈,

并没有能够完全无解的加密逻辑,有的只是无限提高破解代价的逻辑。

对于上面给出的例子来说,其实只要在接口和唯一性数据的选择上给出更好的方案就可以避免被刷量了。

比如接口数据加密,不要用 device_id这种显眼的字段,

比如用下发秘钥的方式去和 android_id一起加密,这样即使拿到其中一个,也猜测不出来加密算法。

总而言之,Android 的刷量思路基本就跟上面所说的这样,

但我不鼓励大家去恶意刷量,希望在平时开发中在敏感数据的设计上多绕几个弯,这样能避免被其他人利用。

喜欢的亲们请点个关注吧!欢迎转发。

更多Android进阶技术,面试资料系统整理分享,职业生涯规划,产品,思维,行业观察,谈天说地。可以加Android架构师群;701740775。

相关文章
|
30天前
|
缓存 搜索推荐 Android开发
安卓开发中的自定义控件实践
【10月更文挑战第4天】在安卓开发的海洋中,自定义控件是那片璀璨的星辰。它不仅让应用界面设计变得丰富多彩,还提升了用户体验。本文将带你探索自定义控件的核心概念、实现过程以及优化技巧,让你的应用在众多竞争者中脱颖而出。
|
30天前
|
Java Android开发 Swift
安卓与iOS开发对比:平台选择对项目成功的影响
【10月更文挑战第4天】在移动应用开发的世界中,选择合适的平台是至关重要的。本文将深入探讨安卓和iOS两大主流平台的开发环境、用户基础、市场份额和开发成本等方面的差异,并分析这些差异如何影响项目的最终成果。通过比较这两个平台的优势与挑战,开发者可以更好地决定哪个平台更适合他们的项目需求。
98 1
|
7天前
|
编解码 Java Android开发
通义灵码:在安卓开发中提升工作效率的真实应用案例
本文介绍了通义灵码在安卓开发中的应用。作为一名97年的聋人开发者,我在2024年Google Gemma竞赛中获得了冠军,拿下了很多项目竞赛奖励,通义灵码成为我的得力助手。文章详细展示了如何安装通义灵码插件,并通过多个实例说明其在适配国际语言、多种分辨率、业务逻辑开发和编程语言转换等方面的应用,显著提高了开发效率和准确性。
|
5天前
|
Android开发 开发者 UED
安卓开发中自定义View的实现与性能优化
【10月更文挑战第28天】在安卓开发领域,自定义View是提升应用界面独特性和用户体验的重要手段。本文将深入探讨如何高效地创建和管理自定义View,以及如何通过代码和性能调优来确保流畅的交互体验。我们将一起学习自定义View的生命周期、绘图基础和事件处理,进而探索内存和布局优化技巧,最终实现既美观又高效的安卓界面。
18 5
|
4天前
|
JSON Java Android开发
探索安卓开发之旅:打造你的第一个天气应用
【10月更文挑战第30天】在这个数字时代,掌握移动应用开发技能无疑是进入IT行业的敲门砖。本文将引导你开启安卓开发的奇妙之旅,通过构建一个简易的天气应用来实践你的编程技能。无论你是初学者还是有一定经验的开发者,这篇文章都将成为你宝贵的学习资源。我们将一步步地深入到安卓开发的世界中,从搭建开发环境到实现核心功能,每个环节都充满了发现和创造的乐趣。让我们开始吧,一起在代码的海洋中航行!
|
5天前
|
缓存 数据库 Android开发
安卓开发中的性能优化技巧
【10月更文挑战第29天】在移动应用的海洋中,性能是船只能否破浪前行的关键。本文将深入探讨安卓开发中的性能优化策略,从代码层面到系统层面,揭示如何让应用运行得更快、更流畅。我们将以实际案例和最佳实践为灯塔,引领开发者避开性能瓶颈的暗礁。
16 3
|
8天前
|
存储 IDE 开发工具
探索Android开发之旅:从新手到专家
【10月更文挑战第26天】在这篇文章中,我们将一起踏上一段激动人心的旅程,探索如何在Android平台上从零开始,最终成为一名熟练的开发者。通过简单易懂的语言和实际代码示例,本文将引导你了解Android开发的基础知识、关键概念以及如何实现一个基本的应用程序。无论你是编程新手还是希望扩展你的技术栈,这篇文章都将为你提供价值和启发。让我们开始吧!
|
1月前
|
Web App开发 安全 程序员
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
多年的互联网寒冬在今年尤为凛冽,坚守安卓开发愈发不易。面对是否转行或学习新技术的迷茫,安卓程序员可从三个方向进阶:1)钻研谷歌新技术,如Kotlin、Flutter、Jetpack等;2)拓展新功能应用,掌握Socket、OpenGL、WebRTC等专业领域技能;3)结合其他行业,如汽车、游戏、安全等,拓宽职业道路。这三个方向各有学习难度和保饭碗指数,助你在安卓开发领域持续成长。
58 1
FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
|
13天前
|
Java API Android开发
安卓应用程序开发的新手指南:从零开始构建你的第一个应用
【10月更文挑战第20天】在这个数字技术不断进步的时代,掌握移动应用开发技能无疑打开了一扇通往创新世界的大门。对于初学者来说,了解并学习如何从无到有构建一个安卓应用是至关重要的第一步。本文将为你提供一份详尽的入门指南,帮助你理解安卓开发的基础知识,并通过实际示例引导你完成第一个简单的应用项目。无论你是编程新手还是希望扩展你的技能集,这份指南都将是你宝贵的资源。
42 5
|
12天前
|
设计模式 IDE Java
探索安卓开发:从新手到专家的旅程
【10月更文挑战第22天】 在数字时代的浪潮中,移动应用开发如同一座金矿,吸引着无数探险者。本文将作为你的指南针,指引你进入安卓开发的广阔天地。我们将一起揭开安卓平台的神秘面纱,从搭建开发环境到掌握核心概念,再到深入理解安卓架构。无论你是初涉编程的新手,还是渴望进阶的开发者,这段旅程都将为你带来宝贵的知识和经验的财富。让我们开始吧!