/* send a command before reading */ int CmdLFCommandRead(const char *Cmd) { static char dummy[3] = {0x20,0x00,0x00}; UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K}; bool errors = FALSE; //uint8_t divisor = 95; //125khz uint8_t cmdp = 0; int strLength = 0; while(param_getchar(Cmd, cmdp) != 0x00) { switch(param_getchar(Cmd, cmdp)) { case 'h': return usage_lf_cmdread(); case 'H': //divisor = 88; dummy[1]='h'; cmdp++; break; case 'L': cmdp++; break; case 'c': strLength = param_getstr(Cmd, cmdp+1, (char *)&c.d.asBytes); cmdp+=2; break; case 'd': c.arg[0] = param_get32ex(Cmd, cmdp+1, 0, 10); cmdp+=2; break; case 'z': c.arg[1] = param_get32ex(Cmd, cmdp+1, 0, 10); cmdp+=2; break; case 'o': c.arg[2] = param_get32ex(Cmd, cmdp+1, 0, 10); cmdp+=2; break; default: PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp)); errors = 1; break; } if(errors) break; } // No args if(cmdp == 0) errors = 1; //Validations if(errors) return usage_lf_cmdread(); // in case they specified 'H' strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy); clearCommandBuffer(); SendCommand(&c); return 0; }
int CmdHF15Restore(const char*Cmd) { FILE *file; uint8_t uid[8]={0x00}; char filename[FILE_PATH_SIZE] = {0x00}; char buff[255] = {0x00}; size_t blocksize=4; uint8_t cmdp = 0; char newCmdPrefix[255] = {0x00}, tmpCmd[255] = {0x00}; char param[FILE_PATH_SIZE]=""; char hex[255]=""; uint8_t retries = 3, tried = 0; int retval=0; size_t bytes_read; uint8_t i=0; while(param_getchar(Cmd, cmdp) != 0x00) { switch(tolower(param_getchar(Cmd, cmdp))) { case '-': param_getstr(Cmd, cmdp, param, sizeof(param)); switch(param[1]) { case '2': case 'o': strncpy(newCmdPrefix, " ",sizeof(newCmdPrefix)-1); strncat(newCmdPrefix, param, sizeof(newCmdPrefix)-1); break; default: PrintAndLogEx(WARNING, "Unknown parameter '%s'", param); return usage_15_restore(); } break; case 'f': param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE); cmdp++; break; case 'r': retries=param_get8ex(Cmd, cmdp+1, 3, 10); cmdp++; break; case 'b': blocksize=param_get8ex(Cmd, cmdp+1, 4, 10); cmdp++; break; case 'u': param_getstr(Cmd, cmdp+1, buff, FILE_PATH_SIZE); cmdp++; snprintf(filename,sizeof(filename),"hf-15-dump-%s-bin",buff); break; case 'h': return usage_15_restore(); default: PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); return usage_15_restore(); break; } cmdp++; } PrintAndLogEx(INFO,"Blocksize: %u",blocksize); if(filename[0]=='\0') { PrintAndLogEx(WARNING,"Please provide a filename"); return 1; } if ((file = fopen(filename,"rb")) == NULL) { PrintAndLogEx(WARNING, "Could not find file %s", filename); return 2; } if (!getUID(uid)) { PrintAndLogEx(WARNING, "No tag found"); return 3; } while (1) { tried=0; hex[0]=0x00; tmpCmd[0]=0x00; bytes_read = fread( buff, 1, blocksize, file ); if ( bytes_read == 0) { PrintAndLogEx(SUCCESS, "File reading done (%s).", filename); fclose(file); return 0; } else if ( bytes_read != blocksize) { PrintAndLogEx(WARNING, "File reading error (%s), %u bytes read instead of %u bytes.", filename, bytes_read, blocksize); fclose(file); return 2; } for(int j=0;j<blocksize;j++) snprintf(hex+j*2,3,"%02X", (unsigned char)buff[j]); for(int j=0;j<sizeof(uid)/sizeof(uid[0]);j++) snprintf(buff+j*2,3,"%02X", uid[j]); //TODO: Addressed mode currently not work //snprintf(tmpCmd, sizeof(tmpCmd), "%s %s %d %s", newCmdPrefix, buff, i, hex); snprintf(tmpCmd, sizeof(tmpCmd), "%s u %d %s", newCmdPrefix, i, hex); PrintAndLogEx(DEBUG, "Command to be sent: %s", tmpCmd); for(tried=0;tried<retries;tried++) if(!(retval=CmdHF15Write(tmpCmd))) break; if(tried >= retries) return retval; i++; } fclose(file); }
// Reads all memory pages // need to write to file int CmdHF15Dump(const char*Cmd) { uint8_t fileNameLen = 0; char filename[FILE_PATH_SIZE] = {0}; char * fptr = filename; bool errors = false; uint8_t cmdp = 0; uint8_t uid[8] = {0,0,0,0,0,0,0,0}; while(param_getchar(Cmd, cmdp) != 0x00 && !errors) { switch(param_getchar(Cmd, cmdp)) { case 'h': case 'H': return usage_15_dump(); case 'f': case 'F': fileNameLen = param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE); cmdp += 2; break; default: PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp)); errors = true; break; } } //Validations if (errors) return usage_15_dump(); if (fileNameLen < 1) { PrintAndLogEx(INFO, "Using UID as filename"); if (!getUID(uid)) { PrintAndLogEx(WARNING, "No tag found."); return 1; } fptr += sprintf(fptr, "hf-15-"); FillFileNameByUID(fptr,uid,"-dump",sizeof(uid)); } // detect blocksize from card :) PrintAndLogEx(NORMAL, "Reading memory from tag UID %s", sprintUID(NULL, uid)); int blocknum = 0; uint8_t *recv = NULL; // memory. t15memory mem[256]; uint8_t data[256*4] = {0}; memset(data, 0, sizeof(data)); UsbCommand resp; UsbCommand c = {CMD_ISO_15693_COMMAND, {0, 1, 1}}; // len,speed,recv? uint8_t *req = c.d.asBytes; req[0] = ISO15_REQ_SUBCARRIER_SINGLE | ISO15_REQ_DATARATE_HIGH | ISO15_REQ_NONINVENTORY | ISO15_REQ_ADDRESS; req[1] = ISO15_CMD_READ; // copy uid to read command memcpy(req+2, uid, sizeof(uid)); for (int retry = 0; retry < 5; retry++) { req[10] = blocknum; AddCrc(req, 11); c.arg[0] = 13; clearCommandBuffer(); SendCommand(&c); if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) { uint8_t len = resp.arg[0]; if ( len < 2 ) { PrintAndLogEx(FAILED, "iso15693 card select failed"); continue; } recv = resp.d.asBytes; if ( !CheckCrc(recv, len) ) { PrintAndLogEx(FAILED, "crc fail"); continue; } if (recv[0] & ISO15_RES_ERROR) { PrintAndLogEx(FAILED, "Tag returned Error %i: %s", recv[1], TagErrorStr(recv[1]) ); break; } mem[blocknum].lock = resp.d.asBytes[0]; memcpy(mem[blocknum].block, resp.d.asBytes + 1, 4); memcpy(data + (blocknum * 4), resp.d.asBytes + 1, 4); retry = 0; blocknum++; printf("."); fflush(stdout); } } PrintAndLogEx(NORMAL, "\n"); PrintAndLogEx(NORMAL, "block# | data |lck| ascii"); PrintAndLogEx(NORMAL, "---------+--------------+---+----------"); for (int i = 0; i < blocknum; i++) { PrintAndLogEx(NORMAL, "%3d/0x%02X | %s | %d | %s", i, i, sprint_hex(mem[i].block, 4 ), mem[i].lock, sprint_ascii(mem[i].block, 4) ); } PrintAndLogEx(NORMAL, "\n"); size_t datalen = blocknum * 4; saveFileEML(filename, "eml", data, datalen, 4); saveFile(filename, "bin", data, datalen); return 0; }