From 03fa7573952e4177c425fe46ba772194365764d7 Mon Sep 17 00:00:00 2001 From: Markus Walter Date: Thu, 1 Sep 2022 16:12:22 +0200 Subject: [PATCH] Implement `hf 15 eload` command to move image dump to emulator. --- armsrc/appmain.c | 14 ++++++ armsrc/iso15693.c | 14 ++++++ armsrc/iso15693.h | 2 + client/src/cmdhf15.c | 111 +++++++++++++++++++++++++++++++++++++++++++ include/pm3_cmd.h | 2 + 5 files changed, 143 insertions(+) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 0eccd418a..69961cc7d 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1256,6 +1256,20 @@ static void PacketReceived(PacketCommandNG *packet) { ReaderIso15693(NULL); break; } + case CMD_HF_ISO15693_EML_CLEAR: { + EmlClearIso15693(); + break; + } + case CMD_HF_ISO15693_EML_SETMEM: { + struct p { + uint32_t offset; + uint8_t count; + uint8_t data[]; + } PACKED; + struct p *payload = (struct p *) packet->data.asBytes; + EmlSetMemIso15693(payload->count, payload->data, payload->offset); + break; + } case CMD_HF_ISO15693_SIMULATE: { struct p { uint8_t uid[8]; diff --git a/armsrc/iso15693.c b/armsrc/iso15693.c index d894e3c1f..92c6f2e4e 100644 --- a/armsrc/iso15693.c +++ b/armsrc/iso15693.c @@ -2097,6 +2097,20 @@ void Iso15693InitTag(void) { StartCountSspClk(); } + +void EmlClearIso15693(void) { + // Resetting the bitstream also frees the BigBuf memory, so we do this here to prevent + // an inconvenient reset in the future by Iso15693InitTag + FpgaDownloadAndGo(FPGA_BITSTREAM_HF_15); + BigBuf_Clear_EM(); + reply_ng(CMD_HF_ISO15693_EML_CLEAR, PM3_SUCCESS, NULL, 0); +} + +void EmlSetMemIso15693(uint8_t count, uint8_t *data, uint32_t offset) { + uint8_t *emCARD = BigBuf_get_EM_addr(); + memcpy(emCARD + offset, data, count); +} + // Simulate an ISO15693 TAG, perform anti-collision and then print any reader commands // all demodulation performed in arm rather than host. - greg void SimTagIso15693(uint8_t *uid, uint8_t block_size, int image_length, uint8_t *image) { diff --git a/armsrc/iso15693.h b/armsrc/iso15693.h index 3fd40e49a..4f1800dc7 100644 --- a/armsrc/iso15693.h +++ b/armsrc/iso15693.h @@ -46,6 +46,8 @@ int GetIso15693AnswerFromTag(uint8_t *response, uint16_t max_len, uint16_t timeo //void RecordRawAdcSamplesIso15693(void); void AcquireRawAdcSamplesIso15693(void); void ReaderIso15693(iso15_card_select_t *p_card); // ISO15693 reader +void EmlClearIso15693(void); +void EmlSetMemIso15693(uint8_t count, uint8_t *data, uint32_t offset); void SimTagIso15693(uint8_t *uid, uint8_t block_size, int payload_length, uint8_t *payload); // simulate an ISO15693 tag void BruteforceIso15693Afi(uint32_t speed); // find an AFI of a tag void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint8_t *data); // send arbitrary commands from CLI diff --git a/client/src/cmdhf15.c b/client/src/cmdhf15.c index c5a5677f2..417ad1fe5 100644 --- a/client/src/cmdhf15.c +++ b/client/src/cmdhf15.c @@ -47,6 +47,7 @@ #define Logic0 Iso15693Logic0 #define Logic1 Iso15693Logic1 #define FrameEOF Iso15693FrameEOF +#define CARD_MEMORY_SIZE 4096 #ifndef Crc15 # define Crc15(data, len) Crc16ex(CRC_15693, (data), (len)) @@ -988,6 +989,115 @@ static int CmdHF15Reader(const char *Cmd) { return PM3_SUCCESS; } +static int hf15EmlClear(void) { + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_EML_CLEAR, NULL, 0); + PacketResponseNG resp; + WaitForResponse(CMD_HF_ISO15693_EML_CLEAR, &resp); + return PM3_SUCCESS; +} + +static int hf15EmlSetMem(uint8_t *data, uint8_t count, size_t offset) { + struct p { + uint32_t offset; + uint8_t count; + uint8_t data[]; + } PACKED; + + size_t size = count; + if (size > (PM3_CMD_DATA_SIZE - sizeof(struct p))) { + return PM3_ESOFT; + } + + size_t paylen = sizeof(struct p) + size; + struct p *payload = calloc(1, paylen); + + payload->offset = offset; + payload->count = count; + memcpy(payload->data, data, size); + + clearCommandBuffer(); + SendCommandNG(CMD_HF_ISO15693_EML_SETMEM, (uint8_t *)payload, paylen); + free(payload); + return PM3_SUCCESS; +} + +static int CmdHF15ELoad(const char *Cmd) { + + CLIParserContext *ctx; + CLIParserInit(&ctx, "hf 15 eload", + "Load memory image from file to be used with 'hf 15 sim'", + "hf 15 eload -f hf-15-01020304.bin\n" + ); + void *argtable[] = { + arg_param_begin, + arg_str1("f", "file", "", "filename of image"), + arg_param_end + }; + CLIExecWithReturn(ctx, Cmd, argtable, false); + + int fnlen = 0; + char filename[FILE_PATH_SIZE]; + CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen); + CLIParserFree(ctx); + + uint8_t *data = NULL; + size_t bytes_read = 0; + int res = loadFile_safe(filename, ".bin", (void **)&data, &bytes_read); + if (res != PM3_SUCCESS) { + return res; + } + + if (bytes_read > CARD_MEMORY_SIZE) { + PrintAndLogEx(FAILED, "Memory image too large."); + free(data); + return PM3_EINVARG; + } + if (bytes_read == 0) { + PrintAndLogEx(FAILED, "Memory image empty."); + free(data); + return PM3_EINVARG; + } + + PrintAndLogEx(INFO, "Clearing emulator memory"); + fflush(stdout); + hf15EmlClear(); + + PrintAndLogEx(INFO, "Uploading to emulator memory"); + PrintAndLogEx(INFO, "." NOLF); + + // fast push mode + g_conn.block_after_ACK = true; + + int chuncksize = 64; + size_t offset = 0; + + while (bytes_read > 0) { + if (bytes_read <= chuncksize) { + // Disable fast mode on last packet + g_conn.block_after_ACK = false; + } + + int tosend = MIN(chuncksize, bytes_read); + if (hf15EmlSetMem(data + offset, tosend, offset) != PM3_SUCCESS) { + PrintAndLogEx(FAILED, "Can't set emulator memory at offest: 0x%x", offset); + free(data); + return PM3_ESOFT; + } + PrintAndLogEx(NORMAL, "." NOLF); + fflush(stdout); + + offset += tosend; + bytes_read -= tosend; + } + free(data); + PrintAndLogEx(NORMAL, ""); + + PrintAndLogEx(HINT, "You are ready to simulate. See " _YELLOW_("`hf 15 sim -h`")); + PrintAndLogEx(INFO, "Done!"); + return PM3_SUCCESS; +} + // Simulation is still not working very good // helptext static int CmdHF15Sim(const char *Cmd) { @@ -2208,6 +2318,7 @@ static command_t CommandTable[] = { {"reader", CmdHF15Reader, IfPm3Iso15693, "Act like an ISO-15693 reader"}, {"restore", CmdHF15Restore, IfPm3Iso15693, "Restore from file to all memory pages of an ISO-15693 tag"}, {"samples", CmdHF15Samples, IfPm3Iso15693, "Acquire samples as reader (enables carrier, sends inquiry)"}, + {"eload", CmdHF15ELoad, IfPm3Iso15693, "Load image file to be used by 'sim' command"}, {"sim", CmdHF15Sim, IfPm3Iso15693, "Fake an ISO-15693 tag"}, {"slixdisable", CmdHF15SlixDisable, IfPm3Iso15693, "Disable privacy mode on SLIX ISO-15693 tag"}, {"wrbl", CmdHF15Write, IfPm3Iso15693, "Write a block"}, diff --git a/include/pm3_cmd.h b/include/pm3_cmd.h index f2a8bc56a..f2e9f0607 100644 --- a/include/pm3_cmd.h +++ b/include/pm3_cmd.h @@ -527,6 +527,8 @@ typedef struct { #define CMD_HF_ISO15693_SLIX_L_DISABLE_PRIVACY 0x0317 #define CMD_HF_ISO15693_SLIX_L_DISABLE_AESAFI 0x0318 #define CMD_HF_TEXKOM_SIMULATE 0x0320 +#define CMD_HF_ISO15693_EML_CLEAR 0x0330 +#define CMD_HF_ISO15693_EML_SETMEM 0x0331 #define CMD_LF_SNIFF_RAW_ADC 0x0360