安卓手机游戏的识别码设计思路

通常安卓手机用作识别码的有IMEI、MAC、Android ID。但是这几个值在虚拟器上面都是可以改的,有些虚拟器的IMEI值就是空或者都是一样的,特别是到了后面的安卓版本,玩家是可以不允许APP获邓这些值的权限的,这个有点尴尬。

假如我们不用上述的值,还有什么办法能获得一个手机的唯一码,可以在app删除,重装,清空缓存等操作后,仍然能获取到这个相同的码吗?

我们先看看市场上有没有这种功能的app?有,包括友盟统计,百度统计等统计的SDK,它们是怎么实现手机识别的呢?它既然能统计app安装的次数,那肯定能识别出这个手机是不是已经安装过了吧?是怎么识别的呢?

最简单的就是反编译一下大厂的统计sdk看看。原来大厂的手机识别码设计思路真是超级简单:

1、第一次启动时,按固定的几个保存的地方查找手机识别码

2、如果找到,就用它。并且将那些用户误删除掉的文件再重新生成会来。

3、如果没有找到,就随机(真的就是随机)生成一个,并且在所有固定的目标生成文件保存这个识别码。

真的蛮简单粗爆的,这种方法其实还是有漏洞,就是将所有的文件都删除后,再次启动的程序会生成一个全新的识别码,这样就相当于是一个新的手机了。但现实中这种机率太低了,为什么,看看大厂们都保存到了哪儿吧:

先看百度统计的cuid,原来百度统计是将自己的cuid保存在一个叫libcuid.so的文件里面,有点夸张,居然用了so文件后缀,so是动态库文件,这样垃圾清空软件就不敢轻易删除这个so文件,(哈哈,只能说百度全家桶真的不是一般的贱,程序猿的日常--祝百度早日倒闭):

百度的cuid一共保存了以下这几个地方,在使用时按以下优先级查找

  1. 先在程序内部files中找 libcuid.so
  2. 查找接收 "com.baidu.intent.action.GALAXY" 的接收者的包名,在它包名目录下面找libcuid.so (看起来像是找百度全家桶的包在sd卡生成的缓存)
  3. 用 getSystemSettingValue("com.baidu.deviceid.v2")的设置值加密
  4. 找文件"backups/.SystemConfig/.cuid2"
  5. 直接用getSystemSettingValue(“com.baidu.deviceid”)的值
  6. 找文件"baidu/.cuid"
  7. 找文件"backups/.SystemConfig/.cuid"

上述缓存文件都找不到,就生成一个随机数做md5加密

安卓手机游戏的识别码设计思路

 

android sdk<23就用一个随机生成的数,大于23则用android_id

安卓手机游戏的识别码设计思路

 

看看百度将cuid保存的几个地方,一般用户根本就不太可能删除得干净。特别是有全家桶的情况下,更加不可能了。

 

然后再看看友盟统计的umid的加载:

1、 在app内部加载一个.imprint的文件

2、从这个.imprint文件中读取一个umid的值

3、如果这个值不存在,会从下面三个文件中加载

安卓手机游戏的识别码设计思路

4、如果这个三个文件不存在,会将imprint的值按顺序写入上面三个文件。如果上述三个文件中的值存在,但是和imprint的值不一样,会使用上述三个文件中的值,但是没有看到imprint的值怎么处理的代码。

5、另外还有一个extid.dat的地方保存了umid

安卓手机游戏的识别码设计思路

 

友盟的初始化umid的地方一直没有找到代码。但保存的地方就上述几个文件。

友盟的umid不是用deviceID 或者android_id,因为它的代码里面这几个id是不一样的用途,所以猜测每一次生成umid时应该和百度的cuid一样仍然是一个随机数。但友盟的代码混驳做得比较好,函数名太乱,反编译没有找到初始化umid这一步。

 

友盟统计UMID潜在的一个坑

https://blog.csdn.net/codezjx/article/details/51823694

这个文章提到2016年时的umid在不同机器上是有可能相同的

 

UMID 方案解析

https://www.cnblogs.com/Umeng/p/3885497.html

这个文章提到了新的umid在同一个设备中也是可能会变化的,但是um sdk尽量用缓存保证它的生命周期足够长,不容易变化

 

跟据上述的分析,友盟的umid很有可能和百度cuid一样,是用随机值生成的。

 

好了,上述分析完大厂的做法,我们自己游戏的uid设计思路:

1、从app内部目录找xxxxxxuid.dat文件,从中读取uid

2、固定几个缓存目录,如果不存在xxxxxxuid.dat,就用内部的数据生成,如果存在,就和内部数据对比,如果不一致,就使用缓存的更新内部的

3、如果上述的缓存都不存在,就随机生成一个uid,并且保存在内部xxxxxxuid.dat和外部xxxxxxuid.dat

4、外部的缓存目录参考友盟,定为如下三个:

 

/sdcard/Android/data/.xxxxxx/xxxxxxuid.dat

/sdcard/Android/obj/.xxxxxx/xxxxxxuid.dat

/data/local/tmp/.xxxxxx/xxxxxxuid.dat(这个目录可能有写权限问题,还是换一个吧)

好了,到此,我们设计了一个uid,保存在上述三个地方,应该足够保证app被删除后再重装还是能找回来了。