通过采集手机的某些字段,从而实现得到设备的唯一的标识
设备指纹主要分为三部分,Java层设备指纹,Native设备指纹,popen执行一些命令获取设备信息,包括一些核心的设备指纹
IPC代理
Android是基础的cs架构(客户端和服务端),Android有context用来调用各种安卓本身提供的基础api(如PackageManager,ActivityManager等),这些Manager都有一个代理人,当调用这个Manager里的一些api时,对于简单的api可以直接在本进程实现,如果是复杂的字段(如查询系统信息,调用系统关键函数),他就需要调用”IPC代理人“,他是向服务端通讯的关键,通讯的内容就是对应的IPC协议(通过底层的共享内存Binder传递)
Java层设备指纹
获取
最常用的就是获取android id(在设备首次启动时会随机生成一个64位数字,并以16进制字符串的形式保存,但是恢复出厂设置或者刷机等,即wipe之后会重置)
1 | Settings.Secure.getString(context.getContentResolver(),Settings.Secure.ANDROID_ID) |
在Global中还有一些比较隐蔽的设备指纹(Settings.Global存放了一些全局变量,Settings.Secure放了一些与安全相关)
1 | Settings.Global.getString(context.getContentResolver(),"mi_helth_id")//还有"gcbooster_uuid","key_mqs_uuid","ad_aaid" |
修改测试
hook
Global和Secure都是实现的NameValueTable接口,底层调用的是getStringForUser(resolver,name,resolver.getUserId()),可以hook这个方法
内存反射
查看getStringForUser方法可以发现整体的cache放在sNameValueCache变量和MOVED_TO_GLOBAL变量内部存储
可以反射MOVED_TO_GLOBAL(HashSet类型)或sNameValueCache(高版本为对象,低版本为ArrayMap)去获取值,只要绕过反射限制后就能通过反射变量的方法去获取。sNameValueCache的修改则可以调用putStringForUser这个api
蓝牙网卡MAC
获取
通过BluetoothAdapter的getAddress方法
1 | public String getAddress() { |
修改测试
获取的方法主要通过IPC的代理类方式获取,所以可以先去hook代理的IPC类
serial(序列号)
获取
1 | if(Build.VERSION.SDK_INT >= Build.VERSION_CONDES.O){ |
修改
也可以直接对IPC类进行处理,Hook getSerialForPackage方法即可
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 3049155267@qq.com