mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-22 06:13:51 -07:00
added new function 4x50_restore + unified cosmetic adaptions
This commit is contained in:
parent
10aabebec5
commit
8ca8c307ad
1 changed files with 146 additions and 34 deletions
|
@ -13,6 +13,7 @@
|
||||||
#include "fileutils.h"
|
#include "fileutils.h"
|
||||||
#include "comms.h"
|
#include "comms.h"
|
||||||
#include "commonutil.h"
|
#include "commonutil.h"
|
||||||
|
#include "cmdparser.h"
|
||||||
#include "em4x50.h"
|
#include "em4x50.h"
|
||||||
|
|
||||||
static int usage_lf_em4x50_info(void) {
|
static int usage_lf_em4x50_info(void) {
|
||||||
|
@ -144,6 +145,22 @@ static int usage_lf_em4x50_watch(void) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
static int usage_lf_em4x50_restore(void) {
|
||||||
|
PrintAndLogEx(NORMAL, "Restore EM4x50 dump to tag. Tag must be on antenna. ");
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
PrintAndLogEx(NORMAL, "Usage: lf em 4x50_restore [h]");
|
||||||
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
|
PrintAndLogEx(NORMAL, " h - this help");
|
||||||
|
PrintAndLogEx(NORMAL, " u <UID> - uid, try to restore from lf-4x50-<UID>-dump.bin");
|
||||||
|
PrintAndLogEx(NORMAL, " f <filename prefix> - data filename <filename>.<prefix> (optional)");
|
||||||
|
PrintAndLogEx(NORMAL, " p <pwd> - password (hex, lsb) (optional)");
|
||||||
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
|
PrintAndLogEx(NORMAL, _YELLOW_(" lf em 4x50_restore h"));
|
||||||
|
PrintAndLogEx(NORMAL, _YELLOW_(" lf em 4x50_restore f em4x50dump"));
|
||||||
|
PrintAndLogEx(NORMAL, _YELLOW_(" lf em 4x50_restore f em4x50dump p 12345678"));
|
||||||
|
PrintAndLogEx(NORMAL, "");
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static void prepare_result(const uint8_t *data, int fwr, int lwr, em4x50_word_t *words) {
|
static void prepare_result(const uint8_t *data, int fwr, int lwr, em4x50_word_t *words) {
|
||||||
|
|
||||||
|
@ -308,7 +325,7 @@ int CmdEM4x50Info(const char *Cmd) {
|
||||||
|
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
if (!WaitForResponseTimeout(CMD_LF_EM4X50_INFO, &resp, TIMEOUT)) {
|
if (!WaitForResponseTimeout(CMD_LF_EM4X50_INFO, &resp, TIMEOUT)) {
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
PrintAndLogEx(WARNING, "Timeout while waiting for reply.");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,7 +335,7 @@ int CmdEM4x50Info(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(FAILED, "reading tag " _RED_("failed"));
|
PrintAndLogEx(FAILED, "Reading tag " _RED_("failed"));
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,7 +373,7 @@ int CmdEM4x50Write(const char *Cmd) {
|
||||||
|
|
||||||
// validation
|
// validation
|
||||||
if (address < 1 || address > 31) {
|
if (address < 1 || address > 31) {
|
||||||
PrintAndLogEx(FAILED, "error, address has to be in range [1-31]\n");
|
PrintAndLogEx(FAILED, "Error, address has to be in range [1-31]");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
etd.addresses = address; // lwr
|
etd.addresses = address; // lwr
|
||||||
|
@ -367,7 +384,7 @@ int CmdEM4x50Write(const char *Cmd) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
errors = true;
|
errors = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -381,7 +398,7 @@ int CmdEM4x50Write(const char *Cmd) {
|
||||||
SendCommandNG(CMD_LF_EM4X50_WRITE, (uint8_t *)&etd, sizeof(etd));
|
SendCommandNG(CMD_LF_EM4X50_WRITE, (uint8_t *)&etd, sizeof(etd));
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
if (!WaitForResponseTimeout(CMD_LF_EM4X50_WRITE, &resp, TIMEOUT)) {
|
if (!WaitForResponseTimeout(CMD_LF_EM4X50_WRITE, &resp, TIMEOUT)) {
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
PrintAndLogEx(WARNING, "Timeout while waiting for reply.");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -390,17 +407,17 @@ int CmdEM4x50Write(const char *Cmd) {
|
||||||
|
|
||||||
bool isOK = (resp.status & STATUS_SUCCESS) >> 1;
|
bool isOK = (resp.status & STATUS_SUCCESS) >> 1;
|
||||||
if (isOK == false) {
|
if (isOK == false) {
|
||||||
PrintAndLogEx(FAILED, "writing " _RED_("failed"));
|
PrintAndLogEx(FAILED, "Writing " _RED_("failed"));
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (etd.pwd_given) {
|
if (etd.pwd_given) {
|
||||||
bool login = resp.status & STATUS_LOGIN;
|
bool login = resp.status & STATUS_LOGIN;
|
||||||
if (login == false) {
|
if (login == false) {
|
||||||
PrintAndLogEx(FAILED, "login failed");
|
PrintAndLogEx(FAILED, "Login failed");
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
PrintAndLogEx(SUCCESS, "login with password " _YELLOW_("%08x"), etd.password1);
|
PrintAndLogEx(SUCCESS, "Login with password " _YELLOW_("%08x"), etd.password1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// display result of writing operation in structured format
|
// display result of writing operation in structured format
|
||||||
|
@ -446,7 +463,7 @@ int CmdEM4x50WritePassword(const char *Cmd) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
errors = true;
|
errors = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -459,7 +476,7 @@ int CmdEM4x50WritePassword(const char *Cmd) {
|
||||||
SendCommandNG(CMD_LF_EM4X50_WRITE_PASSWORD, (uint8_t *)&etd, sizeof(etd));
|
SendCommandNG(CMD_LF_EM4X50_WRITE_PASSWORD, (uint8_t *)&etd, sizeof(etd));
|
||||||
|
|
||||||
if (!WaitForResponseTimeout(CMD_LF_EM4X50_WRITE_PASSWORD, &resp, TIMEOUT)) {
|
if (!WaitForResponseTimeout(CMD_LF_EM4X50_WRITE_PASSWORD, &resp, TIMEOUT)) {
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
PrintAndLogEx(WARNING, "Timeout while waiting for reply.");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,9 +487,9 @@ int CmdEM4x50WritePassword(const char *Cmd) {
|
||||||
|
|
||||||
// print response
|
// print response
|
||||||
if (success)
|
if (success)
|
||||||
PrintAndLogEx(SUCCESS, "\nwriting new password " _GREEN_("ok") "\n");
|
PrintAndLogEx(SUCCESS, "Writing new password " _GREEN_("ok"));
|
||||||
else
|
else
|
||||||
PrintAndLogEx(FAILED, "\nwriting password " _RED_("failed") "\n");
|
PrintAndLogEx(FAILED, "Writing password " _RED_("failed"));
|
||||||
|
|
||||||
return (success) ? PM3_SUCCESS : PM3_ESOFT;
|
return (success) ? PM3_SUCCESS : PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
@ -502,7 +519,7 @@ int em4x50_read(em4x50_data_t *etd, em4x50_word_t *out, bool verbose) {
|
||||||
bool isOK = (resp.status & STATUS_SUCCESS) >> 1;
|
bool isOK = (resp.status & STATUS_SUCCESS) >> 1;
|
||||||
if (isOK == false) {
|
if (isOK == false) {
|
||||||
if (verbose)
|
if (verbose)
|
||||||
PrintAndLogEx(FAILED, "reading " _RED_("failed"));
|
PrintAndLogEx(FAILED, "Reading " _RED_("failed"));
|
||||||
|
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
@ -510,10 +527,10 @@ int em4x50_read(em4x50_data_t *etd, em4x50_word_t *out, bool verbose) {
|
||||||
if (edata.pwd_given) {
|
if (edata.pwd_given) {
|
||||||
bool login = resp.status & STATUS_LOGIN;
|
bool login = resp.status & STATUS_LOGIN;
|
||||||
if (login == false) {
|
if (login == false) {
|
||||||
PrintAndLogEx(FAILED, "login failed");
|
PrintAndLogEx(FAILED, "Login failed");
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
PrintAndLogEx(SUCCESS, "login with password " _YELLOW_("%08x"), etd->password1);
|
PrintAndLogEx(SUCCESS, "Login with password " _YELLOW_("%08x"), etd->password1);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *data = resp.data.asBytes;
|
uint8_t *data = resp.data.asBytes;
|
||||||
|
@ -564,7 +581,7 @@ int CmdEM4x50Read(const char *Cmd) {
|
||||||
|
|
||||||
// validation
|
// validation
|
||||||
if (address <= 0 || address >= EM4X50_NO_WORDS) {
|
if (address <= 0 || address >= EM4X50_NO_WORDS) {
|
||||||
PrintAndLogEx(FAILED, "error, address has to be in range [1-33]\n");
|
PrintAndLogEx(FAILED, "Error, address has to be in range [1-33]");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
etd.addr_given = true;
|
etd.addr_given = true;
|
||||||
|
@ -578,7 +595,7 @@ int CmdEM4x50Read(const char *Cmd) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
errors = true;
|
errors = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -631,18 +648,18 @@ int CmdEM4x50Dump(const char *Cmd) {
|
||||||
if (errors)
|
if (errors)
|
||||||
return usage_lf_em4x50_dump();
|
return usage_lf_em4x50_dump();
|
||||||
|
|
||||||
PrintAndLogEx(INFO, "reading EM4x50 tag");
|
PrintAndLogEx(INFO, "Reading EM4x50 tag");
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_LF_EM4X50_INFO, (uint8_t *)&etd, sizeof(etd));
|
SendCommandNG(CMD_LF_EM4X50_INFO, (uint8_t *)&etd, sizeof(etd));
|
||||||
PacketResponseNG resp;
|
PacketResponseNG resp;
|
||||||
if (!WaitForResponseTimeout(CMD_LF_EM4X50_INFO, &resp, TIMEOUT)) {
|
if (!WaitForResponseTimeout(CMD_LF_EM4X50_INFO, &resp, TIMEOUT)) {
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
PrintAndLogEx(WARNING, "Timeout while waiting for reply.");
|
||||||
return PM3_ETIMEOUT;
|
return PM3_ETIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = (resp.status & STATUS_SUCCESS) >> 1;
|
bool success = (resp.status & STATUS_SUCCESS) >> 1;
|
||||||
if (success == false) {
|
if (success == false) {
|
||||||
PrintAndLogEx(FAILED, "reading tag " _RED_("failed"));
|
PrintAndLogEx(FAILED, "Reading tag " _RED_("failed"));
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -696,7 +713,7 @@ int CmdEM4x50Wipe(const char *Cmd) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
errors = true;
|
errors = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -707,14 +724,14 @@ int CmdEM4x50Wipe(const char *Cmd) {
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_LF_EM4X50_WIPE, (uint8_t *)&password, sizeof(password));
|
SendCommandNG(CMD_LF_EM4X50_WIPE, (uint8_t *)&password, sizeof(password));
|
||||||
WaitForResponse(CMD_ACK, &resp);
|
WaitForResponse(CMD_LF_EM4X50_WIPE, &resp);
|
||||||
|
|
||||||
// print response
|
// print response
|
||||||
bool isOK = resp.status;
|
bool isOK = resp.status;
|
||||||
if (isOK) {
|
if (isOK) {
|
||||||
PrintAndLogEx(SUCCESS, "\nwiping data " _GREEN_("ok") "\n");
|
PrintAndLogEx(SUCCESS, "Wiping data " _GREEN_("ok"));
|
||||||
} else {
|
} else {
|
||||||
PrintAndLogEx(FAILED, "\nwiping data " _RED_("failed") "\n");
|
PrintAndLogEx(FAILED, "Wiping data " _RED_("failed"));
|
||||||
return PM3_ESOFT;
|
return PM3_ESOFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -750,7 +767,7 @@ int CmdEM4x50Brute(const char *Cmd) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
errors = true;
|
errors = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -765,9 +782,9 @@ int CmdEM4x50Brute(const char *Cmd) {
|
||||||
dur_h = dur_s / 3600;
|
dur_h = dur_s / 3600;
|
||||||
dur_m = (dur_s - dur_h * 3600) / 60;
|
dur_m = (dur_s - dur_h * 3600) / 60;
|
||||||
dur_s -= dur_h * 3600 + dur_m * 60;
|
dur_s -= dur_h * 3600 + dur_m * 60;
|
||||||
PrintAndLogEx(INFO, "trying %i passwords in range [0x%08x, 0x%08x]",
|
PrintAndLogEx(INFO, "Trying %i passwords in range [0x%08x, 0x%08x]",
|
||||||
no_iter, etd.password1, etd.password2);
|
no_iter, etd.password1, etd.password2);
|
||||||
PrintAndLogEx(INFO, "estimated duration: %ih%im%is", dur_h, dur_m, dur_s);
|
PrintAndLogEx(INFO, "Estimated duration: %ih%im%is", dur_h, dur_m, dur_s);
|
||||||
|
|
||||||
// start
|
// start
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
|
@ -776,9 +793,9 @@ int CmdEM4x50Brute(const char *Cmd) {
|
||||||
|
|
||||||
// print response
|
// print response
|
||||||
if ((bool)resp.status)
|
if ((bool)resp.status)
|
||||||
PrintAndLogEx(SUCCESS, "\npassword " _GREEN_("found") ": 0x%08x\n", resp.data.asDwords[0]);
|
PrintAndLogEx(SUCCESS, "Password " _GREEN_("found") ": 0x%08x", resp.data.asDwords[0]);
|
||||||
else
|
else
|
||||||
PrintAndLogEx(FAILED, "\npassword: " _RED_("not found") "\n");
|
PrintAndLogEx(FAILED, "Password: " _RED_("not found"));
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -820,9 +837,9 @@ int CmdEM4x50Login(const char *Cmd) {
|
||||||
|
|
||||||
// print response
|
// print response
|
||||||
if ((bool)resp.status)
|
if ((bool)resp.status)
|
||||||
PrintAndLogEx(SUCCESS, "\nlogin " _GREEN_("ok") "\n");
|
PrintAndLogEx(SUCCESS, "Login " _GREEN_("ok"));
|
||||||
else
|
else
|
||||||
PrintAndLogEx(FAILED, "\nlogin " _RED_("failed") "\n");
|
PrintAndLogEx(FAILED, "Login " _RED_("failed"));
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -841,7 +858,7 @@ int CmdEM4x50Reset(const char *Cmd) {
|
||||||
return usage_lf_em4x50_reset();
|
return usage_lf_em4x50_reset();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'\n", param_getchar(Cmd, cmdp));
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
errors = true;
|
errors = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -857,9 +874,9 @@ int CmdEM4x50Reset(const char *Cmd) {
|
||||||
|
|
||||||
// print response
|
// print response
|
||||||
if ((bool)resp.status)
|
if ((bool)resp.status)
|
||||||
PrintAndLogEx(SUCCESS, "\nreset " _GREEN_("ok") "\n");
|
PrintAndLogEx(SUCCESS, "Reset " _GREEN_("ok"));
|
||||||
else
|
else
|
||||||
PrintAndLogEx(FAILED, "\nreset " _RED_("failed") "\n");
|
PrintAndLogEx(FAILED, "Reset " _RED_("failed"));
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -899,3 +916,98 @@ int CmdEM4x50Watch(const char *Cmd) {
|
||||||
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CmdEM4x50Restore(const char *Cmd) {
|
||||||
|
|
||||||
|
//uint8_t data[136] = {0x0};
|
||||||
|
size_t bytes_read = 0;
|
||||||
|
char filename[FILE_PATH_SIZE] = {0x00};
|
||||||
|
char szTemp[FILE_PATH_SIZE - 20] = {0x00};
|
||||||
|
FILE *fdump;
|
||||||
|
|
||||||
|
em4x50_data_t etd;
|
||||||
|
etd.pwd_given = false;
|
||||||
|
|
||||||
|
bool errors = false;
|
||||||
|
uint8_t cmdp = 0;
|
||||||
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
|
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
return usage_lf_em4x50_restore();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'u':
|
||||||
|
param_getstr(Cmd, cmdp + 1, szTemp, FILE_PATH_SIZE - 20);
|
||||||
|
if (filename[0] == 0x00)
|
||||||
|
snprintf(filename, FILE_PATH_SIZE, "lf-4x50-%s-dump.bin", szTemp);
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE);
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'p':
|
||||||
|
etd.password1 = param_get32ex(Cmd, cmdp + 1, 0, 16);
|
||||||
|
etd.pwd_given = true;
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// validation
|
||||||
|
if (errors)
|
||||||
|
return usage_lf_em4x50_restore();
|
||||||
|
|
||||||
|
// open dump file
|
||||||
|
if ((fdump = fopen(filename, "rb")) == NULL) {
|
||||||
|
PrintAndLogEx(WARNING, "Could not find file " _YELLOW_("%s"), filename);
|
||||||
|
return PM3_EFILE;
|
||||||
|
}
|
||||||
|
PrintAndLogEx(INFO, "Restoring " _YELLOW_("%s")" to card", filename);
|
||||||
|
|
||||||
|
// read data from dump file
|
||||||
|
bytes_read = fread(&etd.data, sizeof(uint8_t), sizeof(etd.data), fdump);
|
||||||
|
if (bytes_read != sizeof(etd.data)) {
|
||||||
|
PrintAndLogEx(FAILED, "Read error");
|
||||||
|
return PM3_EFILE;
|
||||||
|
}
|
||||||
|
fclose(fdump);
|
||||||
|
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommandNG(CMD_LF_EM4X50_RESTORE, (uint8_t *)&etd, sizeof(etd));
|
||||||
|
PacketResponseNG resp;
|
||||||
|
if (!WaitForResponseTimeout(CMD_LF_EM4X50_RESTORE, &resp, 2 * TIMEOUT)) {
|
||||||
|
PrintAndLogEx(FAILED, "Timeout while waiting for reply.");
|
||||||
|
return PM3_ETIMEOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resp.status == PM3_ETEAROFF)
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
|
||||||
|
bool isOK = (resp.status & STATUS_SUCCESS) >> 1;
|
||||||
|
if (isOK == false) {
|
||||||
|
PrintAndLogEx(FAILED, "Restore " _RED_("failed"));
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (etd.pwd_given) {
|
||||||
|
bool login = resp.status & STATUS_LOGIN;
|
||||||
|
if (login == false) {
|
||||||
|
PrintAndLogEx(FAILED, "Login failed");
|
||||||
|
return PM3_ESOFT;
|
||||||
|
}
|
||||||
|
PrintAndLogEx(SUCCESS, "Login with password " _YELLOW_("%08x"), etd.password1);
|
||||||
|
}
|
||||||
|
PrintAndLogEx(SUCCESS, "Restore " _GREEN_("ok"));
|
||||||
|
PrintAndLogEx(INFO, "Finish restore");
|
||||||
|
|
||||||
|
return PM3_SUCCESS;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue