跳至主要內容

再论类原生系统上的Mifare Classic UID模拟

NaiveTomcat大约 2 分钟开发NFCAndroid

前言

2024年底,我写了一篇关于在类原生系统上实现Mifare Classic卡UID模拟的文章。但是现在尝试重新实现时发现,之前的方法实际上是存在问题的。当时也出现了问题,但是使用软件“NFC卡模拟”生成Magisk模块并刷入之后,问题得到了解决。实际上是我对于libnfc-nxp.conflibnfc-nci.conf的理解有误,导致手机NFC协议栈按照前述办法修改之后无法正确启动。本文记录了我对于之前方法的修正以及正确的实现方法。

NCI指令载荷长度修改

之前的做法是直接将设置UID的指令追加到相应的配置项中。但是NCI指令头部包含预期载荷长度和预期指令数量,因此直接填充指令会导致协议栈无法正确解析指令,进而无法启动。

NCI指令的第三个字节是从此之后开始数的载荷长度,第四个字节是从此之后开始数的指令数量。因此在追加指令时,需要同时修改这两个字节以反映新增指令的长度和数量。

对于四字节UID的设置指令33,04,1A,2B,3C,4D,载荷长度为6(即指令本身的长度),指令数量为1(即新增的指令数量)。因此对于NXP_NFC_PROFILE_EXTN,通常原始指令为20,02,05,01,A0,44,01,00,我们修改为20,02,0B,02,A0,44,01,00,33,04,1A,2B,3C,4D

对于NXP_CORE_CONF,因为通常原始指令已经有33,00的设置,我们只是修改这一条指令的载荷为4字节。因此将33,00修改为33,04,1A,2B,3C,4D,并且指令头部的载荷长度增加4即可。

默认路由配置

另外,还需要修改默认协议路由。原始配置通常为eSE或UICC,修改为路由到Host即可。具体见下:

DEFAULT_ISODEP_ROUTE=0x00
DEFAULT_MIFARE_CLT_ROUTE=0x00
DEFAULT_OFFHOST_ROUTE=0x00

其余配置

NXP_CHECK_DEFAULT_PROTO_SE_IDlibnxp-nci.conf中的NXP_PRFD_TECH_SE也要修改为0x00

其余Quirks

如果配置文件没有变化的情况下重启了NFC服务,在我的设备上,会导致NFC回退至动态UID模式。不知具体原因,当前workaround是切换卡片时先写一个无效的UID(如00:00:00:00)再写入目标UID。