diff --git a/armsrc/appmain.c b/armsrc/appmain.c index ec4770927..053abf0d9 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1122,10 +1122,6 @@ static void PacketReceived(PacketCommandNG *packet) { em4x50_login((uint32_t *)packet->data.asBytes); break; } - case CMD_LF_EM4X50_RESTORE: { - em4x50_restore((em4x50_data_t *)packet->data.asBytes); - break; - } case CMD_LF_EM4X50_SIM: { em4x50_sim(); break; diff --git a/armsrc/em4x50.c b/armsrc/em4x50.c index 905b935c0..409cd7ba8 100644 --- a/armsrc/em4x50.c +++ b/armsrc/em4x50.c @@ -1310,80 +1310,6 @@ void em4x50_writepwd(em4x50_data_t *etd) { reply_ng(CMD_LF_EM4X50_WRITEPWD, status, 0, 0); } -void em4x50_restore(em4x50_data_t *etd) { - - // restore em4x50 dump file to tag - - bool bsuccess = false; - int status = PM3_SUCCESS; - int start_word = 3; // first block/address with user data - uint8_t em4x50_mem[DUMP_FILESIZE] = {0x0}; - uint32_t addresses = 0x00001F01; // from fwr = 1 to lwr = 31 (0x1F) - uint32_t words_client[EM4X50_NO_WORDS] = {0x0}; - uint32_t words_read[EM4X50_NO_WORDS] = {0x0}; - - //----------------------------------------------------------------------------- - // Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_LF) here although FPGA is not - // involved in dealing with emulator memory. But if it is called later, it will - // destroy the Emulator Memory. - //----------------------------------------------------------------------------- - FpgaDownloadAndGo(FPGA_BITSTREAM_LF); - - // read data from flash memory - Flash_ReadData(0, em4x50_mem, 4 * EM4X50_NO_WORDS); - for (int i = 0; i < EM4X50_NO_WORDS; i++) - words_client[i] = reflect32(bytes_to_num(em4x50_mem + (i * 4), 4)); - - em4x50_setup_read(); - - // set gHigh and gLow - if (get_signalproperties() && find_em4x50_tag()) { - - // login first if password is available - if (etd->pwd_given) { - if ((status = login(etd->password1)) == PM3_SUCCESS) { - - // successful login allows words 1 and 2 to be written - start_word = 1; - } - } - - if (status == PM3_SUCCESS) { - - // write data to each address but ignore addresses - // 0 -> password, 32 -> serial, 33 -> uid - for (int i = start_word; i < EM4X50_NO_WORDS - 2; i++) { - status = write(words_client[i], i); - if (status == PM3_ETEAROFF) { - lf_finalize(); - return; - } - } - - // to verify result -> reset EM4x50 - if (reset() == PM3_SUCCESS) { - - // login not necessary because protected word has been set to 0 - // -> no read protected words - // -> selective read can be called immediately - if (selective_read(addresses, words_read) == PM3_SUCCESS) { - - // check if everything is zero - bsuccess = true; - for (int i = start_word; i < EM4X50_NO_WORDS - 2; i++) - bsuccess &= (reflect32(words_read[i]) == words_client[i]); - } - } - } - } - - if (bsuccess) - status = PM3_SUCCESS; - - lf_finalize(); - reply_ng(CMD_LF_EM4X50_RESTORE, status, 0, 0); -} - //============================================================================== // simulate functions //============================================================================== diff --git a/armsrc/em4x50.h b/armsrc/em4x50.h index 1169bb986..9b029647d 100644 --- a/armsrc/em4x50.h +++ b/armsrc/em4x50.h @@ -24,7 +24,6 @@ void em4x50_writepwd(em4x50_data_t *etd); void em4x50_read(em4x50_data_t *etd); void em4x50_brute(em4x50_data_t *etd); void em4x50_login(uint32_t *password); -void em4x50_restore(em4x50_data_t *etd); void em4x50_sim(void); void em4x50_reader(void); void em4x50_chk(uint32_t *numkeys); diff --git a/client/src/cmdlfem4x50.c b/client/src/cmdlfem4x50.c index e8bc6bbd9..342227e56 100644 --- a/client/src/cmdlfem4x50.c +++ b/client/src/cmdlfem4x50.c @@ -156,6 +156,7 @@ static int em4x50_load_file(const char *filename, uint8_t *data, size_t data_len } static void em4x50_seteml(uint8_t *src, uint32_t offset, uint32_t numofbytes) { + // fast push mode conn.block_after_ACK = true; for (size_t i = offset; i < numofbytes; i += PM3_CMD_DATA_SIZE) { @@ -1194,27 +1195,34 @@ int CmdEM4x50Restore(const char *Cmd) { if (em4x50_load_file(filename, data, DUMP_FILESIZE, &bytes_read) != PM3_SUCCESS) return PM3_EFILE; - // upload to flash memory - status = em4x50_write_flash(data, 0, bytes_read); - if (status != PM3_SUCCESS) { - PrintAndLogEx(WARNING, "Error uploading to flash."); - return status; + for (int i = 1; i < EM4X50_DEVICE_SERIAL; i++) { + + PrintAndLogEx(INPLACE, "Restoring block %i", i); + + etd.addresses = i << 8 | i; + etd.word = reflect32(BYTES2UINT32((data + 4 * i))); + + clearCommandBuffer(); + SendCommandNG(CMD_LF_EM4X50_WRITE, (uint8_t *)&etd, sizeof(etd)); + if (!WaitForResponseTimeout(CMD_LF_EM4X50_WRITE, &resp, TIMEOUT)) { + PrintAndLogEx(WARNING, "Timeout while waiting for reply."); + return PM3_ETIMEOUT; + } + + status = resp.status; + if (status != PM3_SUCCESS) { + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(FAILED, "Restoring data " _RED_("failed")); + return PM3_ESOFT; + } } - clearCommandBuffer(); - SendCommandNG(CMD_LF_EM4X50_RESTORE, (uint8_t *)&etd, sizeof(etd)); - if (!WaitForResponseTimeout(CMD_LF_EM4X50_RESTORE, &resp, 2 * TIMEOUT)) { - PrintAndLogEx(FAILED, "Timeout while waiting for reply."); - return PM3_ETIMEOUT; - } + PrintAndLogEx(NORMAL, ""); + PrintAndLogEx(SUCCESS, "Restoring data " _GREEN_("ok")); + + PrintAndLogEx(INFO, "Done"); - status = resp.status; - if (status == PM3_SUCCESS) - PrintAndLogEx(SUCCESS, "Restore " _GREEN_("ok")); - else - PrintAndLogEx(FAILED, "Restore " _RED_("failed")); - - return status; + return PM3_SUCCESS; } //============================================================================== diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index f929bca41..bce9b57d7 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -511,7 +511,6 @@ typedef struct { #define CMD_LF_EM4X50_READ 0x0243 #define CMD_LF_EM4X50_BRUTE 0x0245 #define CMD_LF_EM4X50_LOGIN 0x0246 -#define CMD_LF_EM4X50_RESTORE 0x0249 #define CMD_LF_EM4X50_SIM 0x0250 #define CMD_LF_EM4X50_READER 0x0251 #define CMD_LF_EM4X50_ESET 0x0252