hook android api伪造设备信息做刷量
hook android api伪造设备信息做刷量
概述
Android平台上app的统计数据都是基于Android的设备信息的,比如首次使用(激活),活跃(日活跃DAU,月活跃MAU)等都需要根据设备唯一信息来统计。不仅统计,业务需求也都是根据设备唯一信息来展开的,比如签到,同一台设备不能签第二次,比如运营推广发积分发红包,每台手机只能领取一次,再比如app分发渠道统计应用的激活,同一台手机第一次使用某app才算激活等等这些场景都需要靠设备信息来唯一确定一台手机。
怎么唯一确定一台Android手机,Android程序员都知道,
- IMEI
- IMSI
- SIM_SER sim卡序列号
- MAC地址,
- Android_ID android系统第一次启动生成的一个唯一ID
- Brand 手机品牌
- Model 手机型号
这些信息基本能唯一定位一台手机,为了便于使用,我们的设备ID一般取其中的部分字段做hash,比如hash(MAC地址+IMEI)。
有些刷量的工具依赖于虚拟机,开发虚拟机或者修改android模拟器来模拟不同的硬件设备。从分层角度上看,android系统从下到上可以抽象为这几层 :设备硬件层,应用框架层API,和应用APP,其中设备+API 两层就可以看做是实现了虚拟机。
应用层App直接与API打交道,相同的api调用,不同的返回就相当于不同的虚拟机了。
- APP
API
硬件设备
hook简介
Cydia Substrate hook框架可以hook Java和 C native层的代码,运行时改变代码的实现,是一个很强大的hook工具,也能做为很强大的调试工具。
官网地址:http://www.cydiasubstrate.com/
SDK下载地址:http://asdk.cydiasubstrate.com/zips/cydia_substrate-r2.zip
demo地址:https://github.com/zencodex/cydia-android-hook.git
hook框架:https://cache.saurik.com/apks/com.saurik.substrate_0.9.4010.apk
Cydia Substrate的使用:
- 前提,手机需要root权限
- 手机上安装hook框架apk
- 参考demo编写hook的源程序
- 使用hook框架程序link,重启手机验证
注意hook是针对这个系统的,而不是某个特定的app。某个api被hook后,比如获取手机号的api被hook,这台手机上所有的app获取的手机号都是被修改后的手机号,因此,如果手机上的设备相关api都被hook了,相当于是虚拟了一个新的手机了。
cydia substrate的使用可以参考这两篇文章
http://www.csdn.net/article/2015-08-07/2825405
http://drops.wooyun.org/tips/8084
设备信息API的hook
获取imei
Java 代码
public String getIMEI() {String imei = "";TelephonyManager telepManager;telepManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);imei = telepManager.getDeviceId();return imei;
}
获取IMEI调用api是 android.telephony.TelephonyManager.getDeviceId(),
如何hook呢
MS.hookClassLoad("android.telephony.TelephonyManager",new MS.ClassLoadHook() {@Overridepublic void classLoaded(Class<?> clz) {// hook getDeviceIdMethod methodGetImei;try {methodGetImei = clz.getMethod("getDeviceId",new Class<?>[0]);} catch (NoSuchMethodException e) {methodGetImei = null;}if (methodGetImei != null) {final MS.MethodPointer old = new MS.MethodPointer();MS.hookMethod(clz, methodGetImei,new MS.MethodHook() {@Overridepublic Object invoked(Object obj,Object... args)throws Throwable {int index = readIndex();return deviceIds[index];}}, old);}});
}
这样,被hook的这台android设备上调用TelephonyManager.getDeviceId()返回的就不再是设备的真实IMEI,而是deviceIds[index],deviceIds是一个设备IMEI号的数组,我们构造一个样本足够大deviceIds,就容易做到了IMEI号的伪造和刷量。
获取imsi / sim卡序列号
android.telephony.TelephonyManager.getSubscriberId();
android.telephony.TelephonyManager.getSimSerialNumber();
imsi和sim卡序列号的hook方法与 imei的hook类似,不再重复。
mac地址
public String getMacAddress() {WifiManager wifi = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);WifiInfo info = wifi.getConnectionInfo();return info.getMacAddress();
}
android.net.wifi.WifiInfo.getMacAddress();
getMacAddress()的hook与IMEI的写法基本一样,替换一下类名和方法名就可,
不再重复。
Android_Id
// Secure.ANDROID_ID : public static final String ANDROID_ID = "android_id";return android.provider.Settings.System.getString(mContext.getContentResolver(),Secure.ANDROID_ID);
android_id 的hook方式
MS.hookClassLoad("android.provider.Settings$Secure",new ClassLoadHook() {@Overridepublic void classLoaded(Class<?> clz) {// hook getAndroidIdMethod methodGetAndroidId;try {methodGetAndroidId = clz.getMethod("getString",ContentResolver.class, String.class);} catch (NoSuchMethodException e) {methodGetAndroidId = null;}if (methodGetAndroidId != null) {final MS.MethodPointer old = new MS.MethodPointer();MS.hookMethod(clz, methodGetAndroidId,new MS.MethodHook() {@Overridepublic Object invoked(Object obj,Object... args)throws Throwable {if ("android_id".equals(String.valueOf(args[1]))) {int index = readIndex();return andIds[index];}return old.invoke(obj, args);}}, old);}}});
Object invoked(Object obj,Object… args) 中 obj是指实例化的类对象,在当前这个场景下就是Secure的对象,args是obj.getString(ContentResolver,String)的参数列表,依次是ContentResolver对象和String类型的key,下标从0开始。args[0]是ContentResolver类型,args[1]是String类型,当args[1] == “android_id”时,也就是调用getString(ContentResolver,“android_id”)时,返回值被篡改,key为别的字符串时,按照原本的逻辑返回应有的属性
return old.invoke(obj, args);
brand 和 model
android.os.Build.BRAND; // brand
android.os.Build.MODEL; // model;
brand和model是在Build类里定义的两个静态变量,没发现cydia substrate针对类变量的修改机制,这个hook怎么做呢?请往下看:
/** The brand (e.g., carrier) the software is customized for, if any. */
public static final String BRAND = getString("ro.product.brand");/** The end-user-visible name for the end product. */
public static final String MODEL = getString("ro.product.model");
注意到Brand和MODEL两个变量初始化时调用了getString方法,hook住这个方法,根据传人的参数做好判断应该就可以了。继续往下看:
private static String getString(String property) {return SystemProperties.get(property, UNKNOWN);
}
这个方法是是private的,通过反射去getMethod时候麻烦一下,我们继续往下走一步,来到了android.os.SystemProperties.get(String,String),于是乎,我们hook这个api。
MS.hookClassLoad("android.os.SystemProperties", new ClassLoadHook() {@Overridepublic void classLoaded(Class<?> clz) {// hook getString(String pro)Method methodGetString;try {methodGetString = clz.getMethod("get",String.class,String.class);} catch (NoSuchMethodException e) {methodGetString = null;}if (methodGetString != null) {final MS.MethodPointer old = new MS.MethodPointer();MS.hookMethod(clz, methodGetString,new MS.MethodHook() {@Overridepublic Object invoked(Object obj,Object... args)throws Throwable {if ("ro.product.brand".equals(String.valueOf(args[0]))) {int index = readIndex();return brands[index];}if ("ro.product.model".equals(String.valueOf(args[0]))) {int index = readIndex();return models[index];}return old.invoke(obj, args);}}, old);}}});
源码和demo
验证的测试代码
TelephonyManager telepManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);String imei = telepManager.getDeviceId();String andId = Secure.getString(getContentResolver(),"android_id");String mac = initMAC();String imsi = telepManager.getSubscriberId();String ss = telepManager.getSimSerialNumber();String brand = android.os.Build.BRAND;String model = android.os.Build.MODEL;String text = String.format("%s,%s,%s,%s,%s,%s,%s,---%s", imei,andId, mac, imsi, ss,brand,model,String.valueOf(readIndex()));resText.setText(text);
hook前的设备真实数据
resText显示 :null,6fdace0b66e3cac,null,,,FZS,FZS_Y80_NB,—30
hook后的伪造数据
resText显示 :865761021428959,ab591f34ef3b9aa6,5c:f7:c3:33:b3:0c,460012538363135,606390041315,GiONEE,W900,—30
只要设备信息的数据空间足够大,就可以创造很多的DAU,很多的激活。。。
当然,很多平台都有自己的防作弊系统,比如会分析IP是否离散等等,单纯修改设备信息可能不一定会有效果,需要自行评估。
hook程序的源代码和测试demo
https://github.com/devxiaobai/android_device_info_hook.git
参考
http://www.csdn.net/article/2015-08-07/2825405
http://drops.wooyun.org/tips/8084
hook android api伪造设备信息做刷量相关推荐
- Android获取硬件设备信息
此文介绍一些获取Android手机硬件信息的方法 主要是从Build和TelephonyManager中获取 以及使用反射获取SystemProperties 并使用他的get方法获取一些系统隐藏掉 ...
- android获取设备的型号,Android获取手机设备信息
Android的设备信息获取很简单,导入android.os.Build,在Build类 中有你需要的所有信息. 如果如要经常查阅,可以收藏此文章,需要时点开看一看 下面我打印了一些信息,查查单词的中 ...
- Android 获取手机设备信息:名称、型号、系统版本号、厂商、设备制造商、SDK版本、系统语言等等
常用的设备信息获取方法: /*** 设备名称** @return 设备名称*/public static String getDeviceName() {return android.os.Build ...
- Android 获取手机设备信息(厂商,型号等)
public class DeviceUtils {/*** 获取当前手机系统语言.** @return 返回当前系统语言.例如:当前设置的是"中文-中国",则返回"zh ...
- Android获取手机设备信息并区分真机与模拟器
有些时候我们不想App在模拟器上被别人使用,所以我们禁止在模拟器上使用App 判断是否为真机: 根据以下四图,我们可以对真机与模拟器来做一个简单区分: 如果Serial码为unkonwn或者andro ...
- Android专业获取设备信息如:AndroidID、唯一设备ID、制造商、型号、版本号、版本码等
在开发app中很多时候需要获取设备的基本信息等运用到项目中,就需要一些方法获取,网上资源中方法五花八门,有的还获取不到,令人头大,话不多说,鄙人整理了一套方法,话不多说真机测试如下>上图: 接下 ...
- Android代码片段:设备信息
设备ID /*** Use for getting your device id if available.** @param context* @return your device id*/pub ...
- Android获取USB设备信息
一.通过路径查询 cat /proc/bus/input/devices 二.使用UsbManager获取插入手机的USB设备名字 private void getDevice() {UsbManag ...
- Flutter获取Android/iOS设备信息
我们在进行各个系统的原生开发时,都有对应的方法获取设备信息,那么在使用Flutter时如何获取设备相关的相关信息呢? 我们本文就来介绍一个Flutter插件: Flutter Device Info ...
最新文章
- 泊松回归、gamma回归、Tweedie回归等广义线性回归模型GLM的评估指标:校准曲线、 洛伦兹曲线、卡方检验、AIC、BIC、偏差(Deviance)指标
- 首个获得FDA批准的脑机接口设备:“突破性”脑机接口设备用于造福人类
- 【计算机网络】网络层 : OSPF 协议 ( 协议简介 | 链路状态路由算法 | OSPF 区域 | OSPF 特点 )
- spark streaming 的 Job创建、调度、提交
- Linux下的I/O多路复用select,poll,epoll浅析
- 【老军医方】在脱发过程中遇到的各种疑难杂症
- Kienct与Arduino学习笔记(2) 深度图像与现实世界的深度图的坐标
- 学习笔记一 线性代数
- unity 3D入门
- selenium + python环境搭建步骤
- win10 干净卸载anaconda
- #小米游戏盒子 #小米笔记本驱动 @FDDLC
- Python 爬虫篇-利用urllib库下载网页中的图片实例演示
- 代币系统对会计准则和企业财务革新的启示
- 无线充电原理是什么?
- python字典中删除键值对的del语句与pop方法
- SAP BW实施实时报表的方法(流式处理链)
- OSChina Maven使用说明
- 行业大咖到访众美集团 共话众美定制广场十大价值点
- 面试前夕知识点梳理之JavaScript(补充)