CHG: Merged the "hf mfu rdbl" and "hf mfu crdbl" commands into "hf mfu rdbl". One read command.

CHG:  Merged the "hf mfu wrbl" and "hf mfu cwrbl" commands into "hf mfu wrbl". One write command.

Both new commands implement a help, authentication (0x1A/0x1B) for ULC and the rest,
This commit is contained in:
iceman1001 2015-05-20 23:44:11 +02:00
parent 329f5cf2a5
commit fff69a1e34
5 changed files with 321 additions and 263 deletions

View file

@ -847,7 +847,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
MifareUWriteBlock(c->arg[0], c->d.asBytes);
break;
case CMD_MIFAREU_WRITEBL:
MifareUWriteBlock_Special(c->arg[0], c->d.asBytes);
MifareUWriteBlock_Special(c->arg[0], c->arg[1], c->d.asBytes);
break;
case CMD_MIFARE_NESTED:
MifareNested(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);

View file

@ -180,7 +180,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
void MifareWriteBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
void MifareUWriteBlock(uint8_t arg0,uint8_t *datain);
void MifareUWriteBlock_Special(uint8_t arg0,uint8_t *datain);
void MifareUWriteBlock_Special(uint8_t arg0, uint8_t arg1, uint8_t *datain);
void MifareNested(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
void MifareChkKeys(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);
void Mifare1ksim(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain);

View file

@ -449,12 +449,20 @@ void MifareUWriteBlock(uint8_t arg0, uint8_t *datain)
LEDsoff();
}
void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
// Arg0 : Block to write to.
// Arg1 : 0 = use no authentication.
// 1 = use 0x1A authentication.
// 2 = use 0x1B authentication.
// datain : 4 first bytes is data to be written.
// : 4/16 next bytes is authentication key.
void MifareUWriteBlock_Special(uint8_t arg0, uint8_t arg1, uint8_t *datain)
{
uint8_t blockNo = arg0;
bool useKey = (arg1 == 1); //UL_C
bool usePwd = (arg1 == 2); //UL_EV1/NTAG
byte_t blockdata[4] = {0x00};
memcpy(blockdata, datain,4);
memcpy(blockdata, datain, 4);
LEDsoff();
LED_A_ON();
@ -467,6 +475,28 @@ void MifareUWriteBlock_Special(uint8_t arg0, uint8_t *datain)
return;
};
// UL-C authentication
if ( useKey ) {
uint8_t key[16] = {0x00};
memcpy(key, datain+4, sizeof(key) );
if ( !mifare_ultra_auth(key) ) {
OnError(1);
return;
}
}
// UL-EV1 / NTAG authentication
if (usePwd) {
uint8_t pwd[4] = {0x00};
memcpy(pwd, datain+4, 4);
uint8_t pack[4] = {0,0,0,0};
if (!mifare_ul_ev1_auth(pwd, pack)) {
OnError(1);
return;
}
}
if(mifare_ultra_special_writeblock(blockNo, blockdata)) {
if (MF_DBGLEVEL >= 1) Dbprintf("Write block error");
OnError(0);

View file

@ -208,6 +208,27 @@ static int ulev1_requestAuthentication( uint8_t *pwd, uint8_t *pack, uint16_t pa
return len;
}
static int ul_auth_select( iso14a_card_select_t *card, TagTypeUL_t tagtype, bool hasAuthKey, uint8_t *authenticationkey, uint8_t *pack, uint8_t packSize){
if ( hasAuthKey && (tagtype & UL_C)) {
//will select card automatically and close connection on error
if (!ulc_authentication(authenticationkey, false)) {
PrintAndLog("Error: Authentication Failed UL-C");
return 0;
}
} else {
if ( !ul_select(card) ) return 0;
if (hasAuthKey) {
if (ulev1_requestAuthentication(authenticationkey, pack, packSize) < 1) {
ul_switch_off_field();
PrintAndLog("Error: Authentication Failed UL-EV1/NTAG");
return 0;
}
}
}
return 1;
}
static int ulev1_getVersion( uint8_t *response, uint16_t responseLength ){
uint8_t cmd[] = {MIFARE_ULEV1_VERSION};
@ -614,7 +635,6 @@ int CmdHF14AMfUInfo(const char *Cmd){
int status;
bool errors = false;
bool hasAuthKey = false;
bool hasPwdKey = false;
bool locked = false;
uint8_t cmdp = 0;
uint8_t datalen = 0;
@ -636,7 +656,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
if ( !datalen ) {
memcpy(authenticationkey, data, 4);
cmdp += 2;
hasPwdKey = true;
hasAuthKey = true;
break;
}
// UL-C size key
@ -667,24 +687,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
PrintAndLog("-------------------------------------------------------------");
ul_print_type(tagtype, 6);
if (!ul_select(&card)) return 0;
if ( hasAuthKey && (tagtype & UL_C)) {
//will select card automatically and close connection on error
if (!ulc_authentication(authenticationkey, false)) {
PrintAndLog("Error: Authentication Failed UL-C");
return 0;
}
}
if ( hasPwdKey ) {
len = ulev1_requestAuthentication(authenticationkey, pack, sizeof(pack));
if (len < 1) {
ul_switch_off_field();
PrintAndLog("Error: Authentication Failed UL-EV1/NTAG");
return 0;
}
}
if (!ul_auth_select( &card, tagtype, hasAuthKey, authenticationkey, pack, sizeof(pack))) return -1;
// read pages 0,1,2,3 (should read 4pages)
status = ul_read(0, data, sizeof(data));
@ -692,13 +695,10 @@ int CmdHF14AMfUInfo(const char *Cmd){
ul_switch_off_field();
PrintAndLog("Error: tag didn't answer to READ");
return status;
}
if (status == 16) {
} else if (status == 16) {
ul_print_default(data);
ndef_print_CC(data+12);
}
else {
} else {
locked = true;
}
@ -745,7 +745,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
}
}
// reselect for future tests (ntag test)
if ( !ul_select(&card) ) return 0;
if (!ul_auth_select( &card, tagtype, hasAuthKey, authenticationkey, pack, sizeof(pack))) return -1;
}
}
@ -755,7 +755,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
if ((tagtype & (UL_EV1_48 | UL_EV1_128))) {
if (ulev1_print_counters() != 3) {
// failed - re-select
if ( !ul_select(&card) ) return 0;
if (!ul_auth_select( &card, tagtype, hasAuthKey, authenticationkey, pack, sizeof(pack))) return -1;
}
}
@ -770,7 +770,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
if (status == 32) ulev1_print_signature( ulev1_signature, sizeof(ulev1_signature));
else {
// re-select
if ( !ul_select(&card) ) return 0;
if (!ul_auth_select( &card, tagtype, hasAuthKey, authenticationkey, pack, sizeof(pack))) return -1;
}
}
@ -781,9 +781,12 @@ int CmdHF14AMfUInfo(const char *Cmd){
PrintAndLog("Error: tag didn't answer to GETVERSION");
ul_switch_off_field();
return status;
} else if (status == 10) {
ulev1_print_version(version);
} else {
locked = true;
if (!ul_auth_select( &card, tagtype, hasAuthKey, authenticationkey, pack, sizeof(pack))) return -1;
}
if (status == 10) ulev1_print_version(version);
else locked = true;
uint8_t startconfigblock = 0;
uint8_t ulev1_conf[16] = {0x00};
@ -819,7 +822,7 @@ int CmdHF14AMfUInfo(const char *Cmd){
PrintAndLog("Found a default password: %s || Pack: %02X %02X",sprint_hex(key, 4), pack[0], pack[1]);
break;
} else {
if ( !ul_select(&card) ) return 0;
if (!ul_auth_select( &card, tagtype, hasAuthKey, authenticationkey, pack, sizeof(pack))) return -1;
}
}
if (len < 1) PrintAndLog("password not known");
@ -833,105 +836,241 @@ int CmdHF14AMfUInfo(const char *Cmd){
}
//
// Mifare Ultralight Write Single Block
// Write Single Block
//
int CmdHF14AMfUWrBl(const char *Cmd){
uint8_t blockNo = -1;
bool chinese_card = FALSE;
uint8_t bldata[16] = {0x00};
int blockNo = -1;
bool errors = false;
bool hasAuthKey = false;
bool hasPwdKey = false;
bool swapEndian = false;
uint8_t cmdp = 0;
uint8_t keylen = 0;
uint8_t blockdata[20] = {0x00};
uint8_t data[16] = {0x00};
uint8_t authenticationkey[16] = {0x00};
uint8_t *keyPtr = authenticationkey;
// starting with getting tagtype
TagTypeUL_t tagtype = GetHF14AMfU_Type();
if (tagtype == UL_ERROR) return -1;
while(param_getchar(Cmd, cmdp) != 0x00)
{
switch(param_getchar(Cmd, cmdp))
{
case 'h':
case 'H':
return usage_hf_mfu_wrbl();
case 'k':
case 'K':
// EV1/NTAG size key
keylen = param_gethex(Cmd, cmdp+1, data, 8);
if ( !keylen ) {
memcpy(authenticationkey, data, 4);
cmdp += 2;
hasPwdKey = true;
break;
}
// UL-C size key
keylen = param_gethex(Cmd, cmdp+1, data, 32);
if (!keylen){
memcpy(authenticationkey, data, 16);
cmdp += 2;
hasAuthKey = true;
break;
}
PrintAndLog("\nERROR: Key is incorrect length\n");
errors = true;
break;
case 'b':
case 'B':
blockNo = param_get8(Cmd, cmdp+1);
uint8_t maxblockno = 0;
for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++){
if (tagtype & UL_TYPES_ARRAY[idx])
maxblockno = UL_MEMORY_ARRAY[idx]+1;
}
if (blockNo < 0) {
PrintAndLog("Wrong block number");
errors = true;
}
if (blockNo > maxblockno){
PrintAndLog("block number to large. Max block is %u/0x%02X \n", maxblockno,maxblockno);
errors = true;
}
cmdp += 2;
break;
case 'l':
case 'L':
swapEndian = true;
cmdp++;
break;
case 'd':
case 'D':
if ( param_gethex(Cmd, cmdp+1, blockdata, 8) ) {
PrintAndLog("Block data must include 8 HEX symbols");
errors = true;
break;
}
cmdp += 2;
break;
default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
//Validations
if(errors) return usage_hf_mfu_wrbl();
}
if ( blockNo == -1 ) return usage_hf_mfu_rdbl();
// Swap endianness
if (swapEndian && hasAuthKey) keyPtr = SwapEndian64(authenticationkey, 16, 8);
if (swapEndian && hasPwdKey) keyPtr = SwapEndian64(authenticationkey, 4, 4);
if ( blockNo <= 3)
PrintAndLog("Special Block: %0d (0x%02X) [ %s]", blockNo, blockNo, sprint_hex(blockdata, 4));
else
PrintAndLog("Block: %0d (0x%02X) [ %s]", blockNo, blockNo, sprint_hex(blockdata, 4));
//Send write Block
UsbCommand c = {CMD_MIFAREU_WRITEBL, {blockNo}};
memcpy(c.d.asBytes,blockdata,4);
if ( hasAuthKey ){
c.arg[1] = 1;
memcpy(c.d.asBytes+4,authenticationkey,16);
}
else if ( hasPwdKey ) {
c.arg[1] = 2;
memcpy(c.d.asBytes+4,authenticationkey,4);
}
SendCommand(&c);
UsbCommand resp;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: hf mfu wrbl <block number> <block data (8 hex symbols)> [w]");
PrintAndLog(" [block number]");
PrintAndLog(" [block data] - (8 hex symbols)");
PrintAndLog(" [w] - Chinese magic ultralight tag");
PrintAndLog("");
PrintAndLog(" sample: hf mfu wrbl 0 01020304");
PrintAndLog("");
return 0;
}
blockNo = param_get8(Cmd, 0);
if (blockNo > MAX_UL_BLOCKS){
PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight Cards!");
return 1;
}
if (param_gethex(Cmd, 1, bldata, 8)) {
PrintAndLog("Block data must include 8 HEX symbols");
return 1;
}
if (strchr(Cmd,'w') != 0 || strchr(Cmd,'W') != 0 ) {
chinese_card = TRUE;
}
if ( blockNo <= 3) {
if (!chinese_card){
PrintAndLog("Access Denied");
} else {
PrintAndLog("--specialblock no:%02x", blockNo);
PrintAndLog("--data: %s", sprint_hex(bldata, 4));
UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
memcpy(d.d.asBytes,bldata, 4);
SendCommand(&d);
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLog("isOk:%02x", isOK);
} else {
PrintAndLog("Command execute timeout");
}
}
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLog("isOk:%02x", isOK);
} else {
PrintAndLog("--block no:%02x", blockNo);
PrintAndLog("--data: %s", sprint_hex(bldata, 4));
UsbCommand e = {CMD_MIFAREU_WRITEBL, {blockNo}};
memcpy(e.d.asBytes,bldata, 4);
SendCommand(&e);
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLog("isOk:%02x", isOK);
} else {
PrintAndLog("Command execute timeout");
}
PrintAndLog("Command execute timeout");
}
return 0;
}
//
// Mifare Ultralight Read Single Block
// Read Single Block
//
int CmdHF14AMfURdBl(const char *Cmd){
UsbCommand resp;
uint8_t blockNo = -1;
char cmdp = param_getchar(Cmd, 0);
int blockNo = -1;
bool errors = false;
bool hasAuthKey = false;
bool hasPwdKey = false;
bool swapEndian = false;
uint8_t cmdp = 0;
uint8_t keylen = 0;
uint8_t data[16] = {0x00};
uint8_t authenticationkey[16] = {0x00};
uint8_t *keyPtr = authenticationkey;
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: hf mfu rdbl <block number>");
PrintAndLog(" sample: hfu mfu rdbl 0");
return 0;
}
// starting with getting tagtype
TagTypeUL_t tagtype = GetHF14AMfU_Type();
if (tagtype == UL_ERROR) return -1;
while(param_getchar(Cmd, cmdp) != 0x00)
{
switch(param_getchar(Cmd, cmdp))
{
case 'h':
case 'H':
return usage_hf_mfu_rdbl();
case 'k':
case 'K':
// EV1/NTAG size key
keylen = param_gethex(Cmd, cmdp+1, data, 8);
if ( !keylen ) {
memcpy(authenticationkey, data, 4);
cmdp += 2;
hasPwdKey = true;
break;
}
// UL-C size key
keylen = param_gethex(Cmd, cmdp+1, data, 32);
if (!keylen){
memcpy(authenticationkey, data, 16);
cmdp += 2;
hasAuthKey = true;
break;
}
PrintAndLog("\nERROR: Key is incorrect length\n");
errors = true;
break;
case 'b':
case 'B':
blockNo = param_get8(Cmd, cmdp+1);
uint8_t maxblockno = 0;
for (uint8_t idx = 0; idx < MAX_UL_TYPES; idx++){
if (tagtype & UL_TYPES_ARRAY[idx])
maxblockno = UL_MEMORY_ARRAY[idx]+1;
}
blockNo = param_get8(Cmd, 0);
if (blockNo > MAX_UL_BLOCKS){
PrintAndLog("Error: Maximum number of blocks is 15 for Ultralight");
return 1;
if (blockNo < 0) {
PrintAndLog("Wrong block number");
errors = true;
}
if (blockNo > maxblockno){
PrintAndLog("block number to large. Max block is %u/0x%02X \n", maxblockno,maxblockno);
errors = true;
}
cmdp += 2;
break;
case 'l':
case 'L':
swapEndian = true;
cmdp++;
break;
default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
//Validations
if(errors) return usage_hf_mfu_rdbl();
}
if ( blockNo == -1 ) return usage_hf_mfu_rdbl();
// Swap endianness
if (swapEndian && hasAuthKey) keyPtr = SwapEndian64(authenticationkey, 16, 8);
if (swapEndian && hasPwdKey) keyPtr = SwapEndian64(authenticationkey, 4, 4);
//Read Block
UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
if ( hasAuthKey ){
c.arg[1] = 1;
memcpy(c.d.asBytes,authenticationkey,16);
}
else if ( hasPwdKey ) {
c.arg[1] = 2;
memcpy(c.d.asBytes,authenticationkey,4);
}
SendCommand(&c);
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
if (isOK) {
uint8_t *data = resp.d.asBytes;
PrintAndLog("Block: %0d (0x%02X) [ %s]", (int)blockNo, blockNo, sprint_hex(data, 4));
PrintAndLog("Block: %0d (0x%02X) [ %s]", blockNo, blockNo, sprint_hex(data, 4));
}
else {
PrintAndLog("Failed reading block: (%02x)", isOK);
@ -939,20 +1078,19 @@ int CmdHF14AMfURdBl(const char *Cmd){
} else {
PrintAndLog("Command execute time-out");
}
return 0;
}
int usage_hf_mfu_info(void)
{
int usage_hf_mfu_info(void) {
PrintAndLog("It gathers information about the tag and tries to detect what kind it is.");
PrintAndLog("Sometimes the tags are locked down, and you may need a key to be able to read the information");
PrintAndLog("The following tags can be identified:\n");
PrintAndLog("Ultralight, Ultralight-C, Ultralight EV1");
PrintAndLog("NTAG 213, NTAG 215, NTAG 216");
PrintAndLog("my-d, my-d NFC, my-d move, my-d move NFC\n");
PrintAndLog("Usage: hf mfu info k <key>");
PrintAndLog("Usage: hf mfu info h k <key>");
PrintAndLog(" Options : ");
PrintAndLog(" h : this help");
PrintAndLog(" k <key> : key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
PrintAndLog("");
PrintAndLog(" sample : hf mfu info");
@ -960,13 +1098,13 @@ int usage_hf_mfu_info(void)
return 0;
}
int usage_hf_mfu_dump(void)
{
int usage_hf_mfu_dump(void) {
PrintAndLog("Reads all pages from Ultralight, Ultralight-C, Ultralight EV1");
PrintAndLog("and saves binary dump into the file `filename.bin` or `cardUID.bin`");
PrintAndLog("It autodetects card type.\n");
PrintAndLog("Usage: hf mfu dump l k <key> n <filename w/o .bin> p <> q <>");
PrintAndLog(" Options : ");
PrintAndLog(" h : this help");
PrintAndLog(" k <key> : key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
PrintAndLog(" l : swap entered key's endianness for auth");
PrintAndLog(" n <FN > : filename w/o .bin to save the dump as");
@ -980,6 +1118,35 @@ int usage_hf_mfu_dump(void)
return 0;
}
int usage_hf_mfu_rdbl(void) {
PrintAndLog("Read a block and print. It autodetects card type.\n");
PrintAndLog("Usage: hf mfu rdbl h l b <block number> k <key> \n");
PrintAndLog(" Options:");
PrintAndLog(" h : this help");
PrintAndLog(" b <no> : block to read");
PrintAndLog(" k <key> : key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
PrintAndLog(" l : swap entered key's endianness");
PrintAndLog("");
PrintAndLog(" sample : hf mfu rdbl b 0");
PrintAndLog(" : hf mfu rdbl b 0 k 00112233445566778899AABBCCDDEEFF");
PrintAndLog(" : hf mfu rdbl b 0 k 11223344\n");
return 0;
}
int usage_hf_mfu_wrbl(void) {
PrintAndLog("Usage: hf mfu wrbl <block number> <block data (8 hex symbols)> [w]");
PrintAndLog(" Options:");
PrintAndLog(" h : this help");
PrintAndLog(" b <no> : block to write");
PrintAndLog(" d <data> : [block data] - (8 hex symbols)");
PrintAndLog(" k <key> : key for authentication [UL-C 16bytes, EV1/NTAG 4bytes]");
PrintAndLog(" l : swap entered key's endianness");
PrintAndLog("");
PrintAndLog(" sample : hf mfu wrbl b 0 d 01020304");
PrintAndLog(" : hf mfu wrbl b 0 d 01020304 k 11223344\n");
return 0;
}
//
// Mifare Ultralight / Ultralight-C / Ultralight-EV1
// Read and Dump Card Contents, using auto detection of tag size.
@ -1357,142 +1524,6 @@ int CmdTestDES(const char * cmd)
}
**/
//
// Ultralight C Read Single Block
//
int CmdHF14AMfUCRdBl(const char *Cmd)
{
UsbCommand resp;
bool hasPwd = FALSE;
uint8_t blockNo = -1;
uint8_t key[16];
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: hf mfu crdbl <block number> <key>");
PrintAndLog("");
PrintAndLog("sample: hf mfu crdbl 0");
PrintAndLog(" hf mfu crdbl 0 00112233445566778899AABBCCDDEEFF");
return 0;
}
blockNo = param_get8(Cmd, 0);
if (blockNo < 0) {
PrintAndLog("Wrong block number");
return 1;
}
if (blockNo > MAX_ULC_BLOCKS ){
PrintAndLog("Error: Maximum number of blocks is 47 for Ultralight-C");
return 1;
}
// key
if ( strlen(Cmd) > 3){
if (param_gethex(Cmd, 1, key, 32)) {
PrintAndLog("Key must include %d HEX symbols", 32);
return 1;
} else {
hasPwd = TRUE;
}
}
//Read Block
UsbCommand c = {CMD_MIFAREU_READBL, {blockNo}};
if ( hasPwd ) {
c.arg[1] = 1;
memcpy(c.d.asBytes,key,16);
}
SendCommand(&c);
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
if (isOK) {
uint8_t *data = resp.d.asBytes;
PrintAndLog("Block: %0d (0x%02X) [ %s]", (int)blockNo, blockNo, sprint_hex(data, 4));
}
else {
PrintAndLog("Failed reading block: (%02x)", isOK);
}
} else {
PrintAndLog("Command execute time-out");
}
return 0;
}
//
// Mifare Ultralight C Write Single Block
//
int CmdHF14AMfUCWrBl(const char *Cmd){
uint8_t blockNo = -1;
bool chinese_card = FALSE;
uint8_t bldata[16] = {0x00};
UsbCommand resp;
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 3 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: hf mfu cwrbl <block number> <block data (8 hex symbols)> [w]");
PrintAndLog(" [block number]");
PrintAndLog(" [block data] - (8 hex symbols)");
PrintAndLog(" [w] - Chinese magic ultralight tag");
PrintAndLog("");
PrintAndLog(" sample: hf mfu cwrbl 0 01020304");
PrintAndLog("");
return 0;
}
blockNo = param_get8(Cmd, 0);
if (blockNo > MAX_ULC_BLOCKS ){
PrintAndLog("Error: Maximum number of blocks is 47 for Ultralight-C Cards!");
return 1;
}
if (param_gethex(Cmd, 1, bldata, 8)) {
PrintAndLog("Block data must include 8 HEX symbols");
return 1;
}
if (strchr(Cmd,'w') != 0 || strchr(Cmd,'W') != 0 ) {
chinese_card = TRUE;
}
if ( blockNo <= 3 ) {
if (!chinese_card){
PrintAndLog("Access Denied");
return 1;
} else {
PrintAndLog("--Special block no: 0x%02x", blockNo);
PrintAndLog("--Data: %s", sprint_hex(bldata, 4));
UsbCommand d = {CMD_MIFAREU_WRITEBL, {blockNo}};
memcpy(d.d.asBytes,bldata, 4);
SendCommand(&d);
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLog("isOk:%02x", isOK);
} else {
PrintAndLog("Command execute timeout");
return 1;
}
}
} else {
PrintAndLog("--Block no : 0x%02x", blockNo);
PrintAndLog("--Data: %s", sprint_hex(bldata, 4));
UsbCommand e = {CMD_MIFAREU_WRITEBL, {blockNo}};
memcpy(e.d.asBytes,bldata, 4);
SendCommand(&e);
if (WaitForResponseTimeout(CMD_ACK,&resp,1500)) {
uint8_t isOK = resp.arg[0] & 0xff;
PrintAndLog("isOk : %02x", isOK);
} else {
PrintAndLog("Command execute timeout");
return 1;
}
}
return 0;
}
//
// Mifare Ultralight C - Set password
//
@ -1724,10 +1755,8 @@ static command_t CommandTable[] =
{"dbg", CmdHF14AMfDbg, 0, "Set default debug mode"},
{"info", CmdHF14AMfUInfo, 0, "Tag information"},
{"dump", CmdHF14AMfUDump, 0, "Dump Ultralight / Ultralight-C tag to binary file"},
{"rdbl", CmdHF14AMfURdBl, 0, "Read block - Ultralight"},
{"wrbl", CmdHF14AMfUWrBl, 0, "Write block - Ultralight"},
{"crdbl", CmdHF14AMfUCRdBl, 0, "Read block - Ultralight C"},
{"cwrbl", CmdHF14AMfUCWrBl, 0, "Write block - Ultralight C"},
{"rdbl", CmdHF14AMfURdBl, 0, "Read block"},
{"wrbl", CmdHF14AMfUWrBl, 0, "Write block"},
{"cauth", CmdHF14AMfucAuth, 0, "Authentication - Ultralight C"},
{"setpwd", CmdHF14AMfucSetPwd, 1, "Set 3des password - Ultralight-C"},
{"setuid", CmdHF14AMfucSetUid, 1, "Set UID - MAGIC tags only"},

View file

@ -4,25 +4,24 @@
#ifndef CMDHFMFU_H__
#define CMDHFMFU_H__
//standard ultralight
int CmdHF14AMfUWrBl(const char *Cmd);
int CmdHF14AMfURdBl(const char *Cmd);
//Crypto Cards
int CmdHF14AMfUCRdBl(const char *Cmd);
int CmdHF14AMfUCRdCard(const char *Cmd);
int CmdHF14AMfucAuth(const char *Cmd);
//general stuff
int CmdHF14AMfUDump(const char *Cmd);
int CmdHF14AMfUInfo(const char *Cmd);
uint32_t GetHF14AMfU_Type(void);
uint32_t GetHF14AMfU_Type(void);
int ul_print_type(uint32_t tagtype, uint8_t spacer);
void ul_switch_off_field(void);
int usage_hf_mfu_dump(void);
int usage_hf_mfu_info(void);
int usage_hf_mfu_rdbl(void);
int usage_hf_mfu_wrbl(void);
int CmdHFMFUltra(const char *Cmd);