NFC模拟卡功能是工作后的第一个项目,当时完全没接触过android,别说是代码,就连用的手机也不是andorid,所以当时遇到的一些问题现在看起来很蠢,都是一些基础问题。现在回头看实现当时需求的功能,可能1天的时间都用不到。
需求:让手机能当做门禁卡刷开小区、办公楼闸机。
目录
1 NFC基础知识
2 读取NFC卡内信息
3 修改手机NFC的uid
3.1 确认原始状态
3.2 尝试修改这个值
3.3 配置文件修改
4 总结
问题1:无论给什么权限的app,都不能修改/vendor/etc/libnfc-nxp_RF.conf
问题2:avc权限问题
整体流程
NFC技术支持设备之间进行非接触式点对点的数据传输,可以在10cm距离内交换数据,属于一种非接触式识别和互联通信技术,通常在移动设备、消费类电子产品、智能硬件工具间进行近距离无线通信。
其工作分为三个模式:
- 点对点模式(P2P mode)
在此模式下,两台支持 NFC 的设备在短距离内直接通信。它用于安全支付、文件共享和设备配对等应用。 - 卡模式(Card emulation)
在此模式下,NFC 设备模拟一张非接触式智能卡。它允许设备与传统非接触式卡读卡器进行通信。例如,NFC 智能手机可以模拟一张交通卡,用于乘坐公共交通工具。以及本文提到的模拟门禁卡。 - 读卡器模式(Reader/writer mode)
在此模式下,NFC 设备充当读卡器或写入器,与非接触式智能卡或标签进行通信。例如,NFC 智能手机可以读取非接触式银行卡或门禁卡上的数据。
这个项目用到的模式就是卡模式和读卡器模式,先通过读卡器模式读取门禁卡上的数据,再写入手机中,然后进入卡模式,手机就可以当做门禁卡使用了。
标签:Tag,其中包含了少量的信息。具有不同的标准,执行不同的协议,不同类型的卡中可能包含不同类型的tag。
android提供了原生接口实现此功能,使用读卡器模式,通过NFC.Adapter实现对tag等信息的读取。
读取中分为三个优先级:
- NDEF.DISCOVERED
此意图在以下情况下广播:检测到包含 NDEF(NFC 数据交换格式)消息的 NFC 标签或设备。检测到支持 NDEF 的 NFC 设备,但没有包含 NDEF 消息。 - TECH_DISCOVERED
检测到支持特定 NFC 技术的 NFC 标签或设备,无论是否包含 NDEF 消息。 - TAG_DISCOVERED
检测到任何类型的 NFC 标签,无论是否包含 NDEF 消息或支持特定 NFC 技术。
意图的优先级最高,其次是 意图,最后是 意图。这意味着如果同时检测到 NFC 标签和 NDEF 消息,则应用程序将首先收到 意图,然后是 意图,最后是 意图。
在Manifest中注册意图:
卡中包含了很多数据,对门禁卡功能有用的是什么呢?
>>>tag中的uid,在非加密门禁卡中,仅比对此项是否与数据库中匹配。
可以理解为卡的“身份证”。
读取uid信息,代码中的cardId变量:
代码中读取的还有一些ndef信息,但后面也都没有用上了。下面是NDEF信息的解析函数:
3.1 确认原始状态
换了几台设备,读出的uid各不相同,但有一个规律:08xxxxxx。
这是源于NFCC协议的缺省,未设置情况下是以08开头的8位16进制uid。
3.2 尝试修改这个值
在代码中对找到对这个值进行设置的地方,位于:
问题:相当于将uid写死了。在后续的app中需要实现对这个uid的修改,如果在此修改则需要通过代码注入等方式,代价高。
3.3 配置文件修改
寻找配置文件,在配置文件中修改对应的值。配置文件位于:
对应的uid字段:NXP_CORE_CONF配置如下:
其中33 , 04后跟的就是想要设置的uid。
到此,跟NFC相关的技术内容其实就已经结束了,想要实现手机NFC模拟门禁卡,其实就是修改uid的配置。这种方式只针对最简单的非加密门禁卡。
但是当时做的时候,困难才刚刚开始。
问题1:无论给什么权限的app,都不能修改/vendor/etc/libnfc-nxp_RF.conf
看吧,这个问题真的很蠢,稍微了解一点android就会知道,vendor下的文件怎么可能给你乱搞。论Read-only-file system的含金量。当时又搞avc,又搞挂载,反正一顿操作hhh。
还出了一个乌龙:突然有一段时间能用了。猜猜是什么原因?
答案是想往手机里push文件,就需要root remount,这下好了,不是只读的了,当然就可以修改了,当时还以为解决了,白高兴半天。
但这也是为什么市面上第三方的NFC模拟卡软件都需要手机的root权限的原因,可能内部大多都是修改uid的这种逻辑。
如果不是源码开发,将手机root后,修改这个文件也可以实现NFC模拟卡功能。
因为是源码开发,后面修改:
将系统读config的地方换到了可修改的位置,实现对uid的修改。
问题2:avc权限问题
这也是android源码开发比较常见的问题了,解决方案也很简单。
- Step 1:抓取avc权限问题log
- Step 2:使用工具audit2allow,执行audit2allow –i avc
- Step 3:可以输出对应需要的权限如下(例)
- Step 4:找到对应.te文件
- Step 5:例中位于
- Step 6:在其中加入上面的输出