安卓设备指纹

  1. IPC代理
  2. Java层设备指纹
    1. 获取
    2. 修改测试
      1. hook
      2. 内存反射
  3. 蓝牙网卡MAC
    1. 获取
    2. 修改测试
  4. serial(序列号)
    1. 获取
    2. 修改

通过采集手机的某些字段,从而实现得到设备的唯一的标识

设备指纹主要分为三部分,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
2
3
4
5
6
7
8
public String getAddress() {
try {
return mManagerService.getAddress(mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, "", e);
}
return null;
}

修改测试

获取的方法主要通过IPC的代理类方式获取,所以可以先去hook代理的IPC类

serial(序列号)

获取

1
2
3
if(Build.VERSION.SDK_INT >= Build.VERSION_CONDES.O){
return Build.getSerial();
}

修改

也可以直接对IPC类进行处理,Hook getSerialForPackage方法即可


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 3049155267@qq.com

💰

×

Help us with donation