chg: 'hf 15 restore' - now also can use addressed mode

This commit is contained in:
iceman1001 2020-06-03 12:06:41 +02:00
parent cfa176dd3e
commit 4683f84991

View file

@ -469,8 +469,8 @@ static int usage_15_restore(void) {
{"h", "this help"}, {"h", "this help"},
{"-2", "use slower '1 out of 256' mode"}, {"-2", "use slower '1 out of 256' mode"},
{"-o", "set OPTION Flag (needed for TI)"}, {"-o", "set OPTION Flag (needed for TI)"},
{"a", "use addressed mode"},
{"r <NUM>", "numbers of retries on error, default is 3"}, {"r <NUM>", "numbers of retries on error, default is 3"},
{"u <UID>", "load hf-15-<UID>-dump.bin"},
{"f <filename>", "load <filename>"}, {"f <filename>", "load <filename>"},
{"b <block size>", "block size, default is 4"} {"b <block size>", "block size, default is 4"}
}; };
@ -1617,34 +1617,29 @@ static int CmdHF15Write(const char *Cmd) {
} }
static int CmdHF15Restore(const char *Cmd) { static int CmdHF15Restore(const char *Cmd) {
FILE *f;
uint8_t uid[8] = {0x00}; char newPrefix[60] = {0x00};
char filename[FILE_PATH_SIZE] = {0x00}; char filename[FILE_PATH_SIZE] = {0x00};
char buff[255] = {0x00};
size_t blocksize = 4; size_t blocksize = 4;
uint8_t cmdp = 0; uint8_t cmdp = 0, retries = 3;
char newCmdPrefix[FILE_PATH_SIZE + 1] = {0x00}, tmpCmd[FILE_PATH_SIZE + 262] = {0x00}; bool addressed_mode = false;
char param[FILE_PATH_SIZE] = "";
char hex[255] = "";
uint8_t retries = 3, i = 0;
int retval = 0;
while (param_getchar(Cmd, cmdp) != 0x00) { while (param_getchar(Cmd, cmdp) != 0x00) {
switch (tolower(param_getchar(Cmd, cmdp))) { switch (tolower(param_getchar(Cmd, cmdp))) {
case '-': case '-': {
char param[3] = "";
param_getstr(Cmd, cmdp, param, sizeof(param)); param_getstr(Cmd, cmdp, param, sizeof(param));
switch (param[1]) { switch (param[1]) {
case '2': case '2':
case 'o': case 'o':
strncpy(newCmdPrefix, " ", sizeof(newCmdPrefix) - 1); sprintf(newPrefix, " %s", param);
strncat(newCmdPrefix, param, sizeof(newCmdPrefix) - strlen(newCmdPrefix) - 1);
break; break;
default: default:
PrintAndLogEx(WARNING, "Unknown parameter '%s'", param); PrintAndLogEx(WARNING, "11 Unknown parameter " _YELLOW_("'%s'"), param);
return usage_15_restore(); return usage_15_restore();
} }
break; break;
}
case 'f': case 'f':
param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE); param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE);
cmdp++; cmdp++;
@ -1657,15 +1652,13 @@ static int CmdHF15Restore(const char *Cmd) {
blocksize = param_get8ex(Cmd, cmdp + 1, 4, 10); blocksize = param_get8ex(Cmd, cmdp + 1, 4, 10);
cmdp++; cmdp++;
break; break;
case 'u': case 'a':
param_getstr(Cmd, cmdp + 1, buff, FILE_PATH_SIZE); addressed_mode = true;
cmdp++;
snprintf(filename, sizeof(filename), "hf-15-%s-dump.bin", buff);
break; break;
case 'h': case 'h':
return usage_15_restore(); return usage_15_restore();
default: default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp)); PrintAndLogEx(WARNING, "Unknown parameter " _YELLOW_("'%c'"), param_getchar(Cmd, cmdp));
return usage_15_restore(); return usage_15_restore();
} }
cmdp++; cmdp++;
@ -1678,62 +1671,64 @@ static int CmdHF15Restore(const char *Cmd) {
return usage_15_restore(); return usage_15_restore();
} }
if ((f = fopen(filename, "rb")) == NULL) { uint8_t uid[8] = {0x00};
if (!getUID(uid)) {
PrintAndLogEx(WARNING, "No tag found");
return PM3_ESOFT;
}
PrintAndLogEx(WARNING, "Could not find file %s", filename); size_t datalen = 0;
uint8_t *data = NULL;
if (loadFile_safe(filename, ".bin", (void **)&data, &datalen) != PM3_SUCCESS) {
PrintAndLogEx(WARNING, "Could not find file " _YELLOW_("%s"), filename);
return PM3_EFILE; return PM3_EFILE;
} }
if (!getUID(uid)) { if ((datalen % blocksize) != 0) {
PrintAndLogEx(WARNING, "No tag found"); PrintAndLogEx(WARNING, "Datalen %zu isn't dividable with blocksize %zu", datalen, blocksize);
fclose(f);
return PM3_ESOFT; return PM3_ESOFT;
} }
PrintAndLogEx(INFO, "Restoring data blocks."); PrintAndLogEx(INFO, "Restoring data blocks.");
while (1) { int retval = PM3_SUCCESS;
uint8_t tried = 0; size_t bytes = 0;
hex[0] = 0x00; uint16_t i = 0;
tmpCmd[0] = 0x00; while (bytes < datalen) {
size_t bytes_read = fread(buff, 1, blocksize, f); uint8_t tried = 0;
if (bytes_read == 0) { char hex[40] = {0x00};
PrintAndLogEx(SUCCESS, "File reading done `%s`", filename); char tmpCmd[200] = {0x00};
fclose(f);
return PM3_SUCCESS; if (addressed_mode) {
} else if (bytes_read != blocksize) { char uidhex[17] = {0x00};
PrintAndLogEx(ERR, "File reading error (%s), %zu bytes read instead of %zu bytes.", filename, bytes_read, blocksize); hex_to_buffer((uint8_t *)uidhex, uid, sizeof(uid), sizeof(uidhex) - 1, 0, false, true);
fclose(f); hex_to_buffer((uint8_t *)hex, data + i, blocksize, sizeof(hex) - 1, 0, false, true);
return PM3_EFILE; snprintf(tmpCmd, sizeof(tmpCmd), "%s %s %u %s", newPrefix, uidhex, i, hex);
} else {
hex_to_buffer((uint8_t *)hex, data + i, blocksize, sizeof(hex) - 1, 0, false, true);
snprintf(tmpCmd, sizeof(tmpCmd), "%s u %u %s", newPrefix, i, hex);
} }
for (int j = 0; j < blocksize; j++) PrintAndLogEx(DEBUG, "hf 15 write %s", tmpCmd);
snprintf(hex + j * 2, 3, "%02X", buff[j]);
for (int j = 0; j < ARRAYLEN(uid); 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 %u %s", newCmdPrefix, i, hex);
PrintAndLogEx(DEBUG, "Command to be sent| %s", tmpCmd);
for (tried = 0; tried < retries; tried++) { for (tried = 0; tried < retries; tried++) {
if (!(retval = CmdHF15Write(tmpCmd))) { if (!(retval = CmdHF15Write(tmpCmd))) {
break; break;
} }
} }
if (tried >= retries) { if (tried >= retries) {
fclose(f); free(data);
PrintAndLogEx(FAILED, "Restore failed. Too many retries."); PrintAndLogEx(FAILED, "Restore failed. Too many retries.");
return retval; return retval;
} }
bytes += blocksize;
i++; i++;
} }
fclose(f); free(data);
PrintAndLogEx(INFO, "Finish restore"); PrintAndLogEx(INFO, "done");
PrintAndLogEx(HINT, "Try reading your card to verify with " _YELLOW_("`hf 15 dump`") );
return PM3_SUCCESS; return PM3_SUCCESS;
} }