使用RC522(SI522)写UID卡0扇区0块

在淘宝买的UID白卡,可以使用特殊指令写0扇区0块,达到修改卡号的目的。

一开始淘宝白卡各类繁多,没搞明白,查了查以下几个关键词:

IC卡:普通的S50卡,0扇区0块不可更改。

UID: 0扇区0块可以更改(使用特殊指令)。

CUID:0扇区0块可以更改(使用标准扇区读写指令)。

FUID:0扇区0块可以更改(与UID类似,但只能写一次)。

S50资料参考: https://www.cnblogs.com/SCPlatform/p/5116180.html


手上刚好有一块SI522的板子,SI522据说完全兼容MFRC522,拿来测试。

通过查阅资料,得知写UID的流程是这样的:

#1.寻卡
send:26 
recv:04 00 
#2.防冲突
send:93 20 
recv:B0 6A BC 3B 5D 
#3.选卡
send:93 70 B0 6A BC 3B 5D D9 36 
recv:08 B6 DD 
#4.休眠
send:50 00 57 CD 
#5.写0块后门指令1(7bit模式)
send:40
recv:0A 
#6.写0块后门指令2
send:43 
recv:0A 
#7.写块数据
send:A0 00 5F B1 
recv:0A 
#8.写入16字节的块数据
send:75 C5 48 37 CF 08 04 00 62 63 64 65 66 67 68 69 5C BB 
recv:0A 

#块0数据注解
75 C5 48 37: 4字节卡号
CF         : XOR卡号校验
08         : 卡容量
04 00      : 卡类型
62 63 64 65: 其它
66 67 68 69: 其它

那么,搞清楚通信数据流程后,如何实现这个流程呢?

第1步寻卡,SI522库函数已提供:PICC_IsNewCardPresent();

第2步3步,Si522库函数已提供:PICC_Select() ;

第4步休眠,Si522库函数已提供:PICC_HaltA();

第5,6步,没有现成的函数,但可以用PCD_TransceiveData()函数实现;

第7步,写数据有库函数:MIFARE_Write(0, block, 16);

下面是第5,6步的参考代码:

uint8_t validBits;
uint8_t send_data[8];
uint8_t recv_data[8];
uint8_t recv_size;

//第5步,发送0x40指令
validBits = 7;
send_data[0] = 0x40;
status = PCD_TransceiveData(send_data, 1, recv_data, &recv_size, &validBits, 0, false);
if(status != STATUS_OK)
{
	return 0;
}

//第6步发送0x43指令
send_data[0] = 0x43;
status = PCD_TransceiveData(send_data, 1, recv_data, &recv_size, NULL, 0, false);
if(status != STATUS_OK)
{
	return 0;
}

最后,成功地使用SI522修改了UID卡的卡号。