transferring data of dump file to device via

- em4x50_eload or
	- file option "-f <filename>":
		- via spiffs if flash memory is available
		- via emulator memory if flash memory is not available
This commit is contained in:
tharexde 2020-12-06 01:53:43 +01:00
commit 314450b738
2 changed files with 51 additions and 105 deletions

View file

@ -922,7 +922,6 @@ void em4x50_chk(uint8_t *filename) {
// check passwords from dictionary content in flash memory
int status = PM3_EFAILED;
uint16_t pwd_count = 0;
uint32_t pwd = 0x0;
#ifdef WITH_FLASH
@ -930,6 +929,7 @@ void em4x50_chk(uint8_t *filename) {
BigBuf_free();
int changed = rdv40_spiffs_lazy_mount();
uint16_t pwd_count = 0;
uint32_t size = size_in_spiffs((char *)filename);
pwd_count = size / 4;
uint8_t *pwds = BigBuf_malloc(size);
@ -1304,29 +1304,41 @@ void em4x50_writepwd(em4x50_data_t *etd) {
// simulate functions
//==============================================================================
void em4x50_sim(void) {
void em4x50_sim(uint8_t *filename) {
// simulate uploaded data in flash memory
// (currently only a one-way communication is possible)
// simulate uploaded data in emulator memory
// (currently simulation allows only a one-way communication)
int status = PM3_SUCCESS;
uint8_t em4x50_mem[DUMP_FILESIZE] = {0x0};
uint8_t *em4x50_mem = BigBuf_get_EM_addr();
uint32_t words[EM4X50_NO_WORDS] = {0x0};
#ifdef WITH_FLASH
//-----------------------------------------------------------------------------
// 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);
if (strlen((char *)filename) != 0) {
BigBuf_free();
int changed = rdv40_spiffs_lazy_mount();
uint32_t size = size_in_spiffs((char *)filename);
em4x50_mem = BigBuf_malloc(size);
rdv40_spiffs_read_as_filetype((char *)filename, em4x50_mem, size, RDV40_SPIFFS_SAFETY_SAFE);
if (changed)
rdv40_spiffs_lazy_unmount();
Dbprintf("bin tatsächlich durchs #define gelaufen.");
}
#endif
// read data from flash memory
Flash_ReadData(0, em4x50_mem, 4 * EM4X50_NO_WORDS);
for (int i = 0; i < EM4X50_NO_WORDS; i++)
words[i] = reflect32(bytes_to_num(em4x50_mem + (i * 4), 4));
em4x50_setup_sim();
for (int i = 0; i < EM4X50_NO_WORDS; i++)
Dbprintf("%i %08x", i, words[i]);
// only if valid em4x50 data (e.g. uid == serial)
if (words[EM4X50_DEVICE_SERIAL] != words[EM4X50_DEVICE_ID]) {
@ -1337,6 +1349,8 @@ void em4x50_sim(void) {
int fwrp = words[EM4X50_PROTECTION] & 0xFF; // first word read protected
int lwrp = (words[EM4X50_PROTECTION] >> 8) & 0xFF; // last word read protected
em4x50_setup_sim();
while (!BUTTON_PRESS()) {
WDT_HIT();

View file

@ -171,74 +171,6 @@ static void em4x50_seteml(uint8_t *src, uint32_t offset, uint32_t numofbytes) {
}
}
static int em4x50_wipe_flash(int page) {
int isok = 0;
clearCommandBuffer();
SendCommandMIX(CMD_FLASHMEM_WIPE, page, false, 0, NULL, 0);
PacketResponseNG resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 8000)) {
PrintAndLogEx(WARNING, "Timeout while waiting for reply.");
return PM3_ETIMEOUT;
}
isok = resp.oldarg[0] & 0xFF;
if (!isok) {
PrintAndLogEx(WARNING, "Flash error");
return PM3_EFLASH;
}
return PM3_SUCCESS;
}
static int em4x50_write_flash(uint8_t *data, int offset, size_t datalen) {
int isok = 0;
uint32_t bytes_sent = 0;
uint32_t bytes_remaining = datalen;
uint32_t bytes_in_packet = 0;
PacketResponseNG resp;
// wipe
em4x50_wipe_flash(0);
em4x50_wipe_flash(1);
em4x50_wipe_flash(2);
// fast push mode
conn.block_after_ACK = true;
while (bytes_remaining > 0) {
bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining);
clearCommandBuffer();
SendCommandOLD(CMD_FLASHMEM_WRITE, offset + bytes_sent, bytes_in_packet, 0, data + bytes_sent, bytes_in_packet);
bytes_remaining -= bytes_in_packet;
bytes_sent += bytes_in_packet;
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) {
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
conn.block_after_ACK = false;
return PM3_ETIMEOUT;
}
isok = resp.oldarg[0] & 0xFF;
if (!isok) {
conn.block_after_ACK = false;
PrintAndLogEx(FAILED, "Flash write fail [offset %u]", bytes_sent);
return PM3_EFLASH;
}
}
conn.block_after_ACK = false;
return PM3_SUCCESS;
}
int CmdEM4x50ELoad(const char *Cmd) {
int slen = 0;
@ -1210,16 +1142,18 @@ int CmdEM4x50Restore(const char *Cmd) {
int CmdEM4x50Sim(const char *Cmd) {
int slen = 0, res = 0;
int slen = 0, status = 0;
size_t bytes_read = 0;
uint8_t data[DUMP_FILESIZE] = {0x0};
uint8_t destfn[32] = {0};
char filename[FILE_PATH_SIZE] = {0};
PacketResponseNG resp;
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf em 4x50_sim",
"Simulates a EM4x50 tag",
"lf em 4x50_sim -> simulates EM4x50 data in flash memory.\n"
"lf em 4x50_sim -> simulates EM4x50 data in memory (upload via em4x50_eload).\n"
"lf em 4x50_sim -f mydump.eml -> simulates content of file ./mydump\n"
);
@ -1242,36 +1176,34 @@ int CmdEM4x50Sim(const char *Cmd) {
return PM3_EFILE;
}
if (bytes_read * 8 > FLASH_MEM_MAX_SIZE) {
PrintAndLogEx(FAILED, "Filesize is larger than available memory");
return PM3_EOVFLOW;
}
PrintAndLogEx(INFO, "Uploading dump " _YELLOW_("%s") " to flash memory", filename);
if (res != PM3_SUCCESS) {
PrintAndLogEx(WARNING, "Error wiping flash.");
return res;
}
PrintAndLogEx(INFO, "Uploading dump " _YELLOW_("%s") " to davice", filename);
// upload to device
res = em4x50_write_flash(data, 0, bytes_read);
if (res != PM3_SUCCESS) {
PrintAndLogEx(WARNING, "Error uploading to flash.");
return res;
if (IfPm3Flash()) {
sprintf((char *)destfn, "em4x50_sim.bin");
status = flashmem_spiffs_load(destfn, data, DUMP_FILESIZE);
if (status != PM3_SUCCESS) {
PrintAndLogEx(WARNING, "SPIFFS upload failed");
return status;
}
} else {
em4x50_seteml(data, 0, DUMP_FILESIZE);
}
PrintAndLogEx(INFO, "Simulating data from " _YELLOW_("%s"), filename);
} else {
PrintAndLogEx(INFO, "Simulating data from emulator memory");
}
PrintAndLogEx(INFO, "Simulating data in " _YELLOW_("%s"), filename);
clearCommandBuffer();
SendCommandNG(CMD_LF_EM4X50_SIM, 0, 0);
SendCommandNG(CMD_LF_EM4X50_SIM, destfn, sizeof(destfn));
WaitForResponse(CMD_LF_EM4X50_SIM, &resp);
if (resp.status == PM3_SUCCESS)
status = resp.status;
if (status == PM3_SUCCESS)
PrintAndLogEx(INFO, "Done");
else
PrintAndLogEx(FAILED, "No valid em4x50 data in flash memory.");
PrintAndLogEx(FAILED, "No valid em4x50 data in memory.");
return resp.status;
}