mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-03-20 03:48:33 +08:00
Merge pull request #1772 from markus-oehme-pg40/iso15693-improvements
Iso15693 improvements
This commit is contained in:
commit
1a6c127f0d
4 changed files with 184 additions and 34 deletions
|
@ -3,6 +3,10 @@ All notable changes to this project will be documented in this file.
|
|||
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
|
||||
|
||||
## [unreleased][unreleased]
|
||||
- Added `hf 15 eview` and `hf 15 esave` - Retrieve emulator image for ISO15693 simulation (@markus-oehme-pg40)
|
||||
- Changed `hf 15 sim` - now supports reader writes (@markus-oehme-pg40)
|
||||
- Added `hf 15 eload` - specify memory image for ISO15693 simulation (@markus-oehme-pg40)
|
||||
- Added `hf 15 sim --blocksize` - configure block size for simulation (@markus-oehme-pg40)
|
||||
- Fixed buffer overflow in mfu ndef decode (@mwalker)
|
||||
- Changed spiffs write/append to send in 8192 chunks to ensure its eraised (@mwalker)
|
||||
- Fixed spiffs dump to ensure to fails correctly if no big_buff was allocated (@mwalker)
|
||||
|
@ -90,8 +94,6 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
|||
- Added new standalone mode `lf_em4100rsww` (@zabszk)
|
||||
- Fixed `hf 15 slixdisable` wrong pass id (@r1ddl3rz)
|
||||
- Added `script run hf_mf_hid_sim.lua` (@micsen)
|
||||
- Added `hf 15 sim --blocksize` - configure block size for simulation (@markus-oehme-pg40)
|
||||
- Added `hf 15 eload` - specify memory image for ISO15693 simulation (@markus-oehme-pg40)
|
||||
|
||||
|
||||
## [Frostbit.4.14831][2022-01-11]
|
||||
|
|
|
@ -2111,6 +2111,11 @@ void EmlSetMemIso15693(uint8_t count, uint8_t *data, uint32_t offset) {
|
|||
memcpy(emCARD + offset, data, count);
|
||||
}
|
||||
|
||||
void EmlGetMemIso15693(uint8_t count, uint8_t *output, uint32_t offset) {
|
||||
uint8_t *emCARD = BigBuf_get_EM_addr();
|
||||
memcpy(output, emCARD + offset, 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) {
|
||||
|
@ -2235,29 +2240,19 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size) {
|
|||
// READ_BLOCK and READ_MULTI_BLOCK
|
||||
if ((cmd[1] == ISO15693_READBLOCK) || (cmd[1] == ISO15693_READ_MULTI_BLOCK)) {
|
||||
bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH);
|
||||
bool addressed = cmd[0] & ISO15_REQ_ADDRESS;
|
||||
bool option = cmd[0] & ISO15_REQ_OPTION;
|
||||
uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM;
|
||||
|
||||
uint8_t block_idx = 0;
|
||||
uint8_t address_offset = 0;
|
||||
if (addressed) {
|
||||
address_offset = 8;
|
||||
}
|
||||
|
||||
uint8_t block_idx = cmd[2 + address_offset];
|
||||
uint8_t block_count = 1;
|
||||
if (cmd[1] == ISO15693_READBLOCK) {
|
||||
if (cmd_len == 13) {
|
||||
// addressed mode
|
||||
block_idx= cmd[10];
|
||||
} else if (cmd_len == 5) {
|
||||
// non-addressed mode
|
||||
block_idx = cmd[2];
|
||||
}
|
||||
} else if (cmd[1] == ISO15693_READ_MULTI_BLOCK) {
|
||||
if (cmd_len == 14) {
|
||||
// addressed mode
|
||||
block_idx= cmd[10];
|
||||
block_count= cmd[11] + 1;
|
||||
} else if (cmd_len == 6) {
|
||||
// non-addressed mode
|
||||
block_idx = cmd[2];
|
||||
block_count = cmd[3] + 1;
|
||||
}
|
||||
if (cmd[1] == ISO15693_READ_MULTI_BLOCK) {
|
||||
block_count = cmd[3 + address_offset] + 1;
|
||||
}
|
||||
|
||||
// Build READ_(MULTI_)BLOCK response
|
||||
|
@ -2268,11 +2263,8 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size) {
|
|||
security_offset = 1;
|
||||
}
|
||||
uint8_t resp_readblock[response_length];
|
||||
for (int i = 0; i < response_length; i++) {
|
||||
resp_readblock[i] = 0;
|
||||
}
|
||||
memset(resp_readblock, 0, response_length);
|
||||
|
||||
uint8_t *emCARD = BigBuf_get_EM_addr();
|
||||
resp_readblock[0] = 0; // Response flags
|
||||
for (int j = 0; j < block_count; j++) {
|
||||
// where to put the data of the current block
|
||||
|
@ -2280,13 +2272,12 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size) {
|
|||
if (option) {
|
||||
resp_readblock[work_offset] = 0; // Security status
|
||||
}
|
||||
for (int i = 0; i < block_size; i++) {
|
||||
// Block data
|
||||
if (block_size * (block_idx + j + 1) <= CARD_MEMORY_SIZE) {
|
||||
resp_readblock[work_offset + security_offset + i] = emCARD[block_size * (block_idx + j) + i];
|
||||
} else {
|
||||
resp_readblock[work_offset + security_offset + i] = 0;
|
||||
}
|
||||
// Block data
|
||||
if (block_size * (block_idx + j + 1) <= CARD_MEMORY_SIZE) {
|
||||
EmlGetMemIso15693(block_size, resp_readblock + (work_offset + security_offset),
|
||||
block_size * (block_idx + j));
|
||||
} else {
|
||||
memset(resp_readblock + work_offset + security_offset, 0, block_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2299,6 +2290,45 @@ void SimTagIso15693(uint8_t *uid, uint8_t block_size) {
|
|||
TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow);
|
||||
LogTrace_ISO15693(resp_readblock, response_length, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false);
|
||||
}
|
||||
|
||||
// WRITE_BLOCK and WRITE_MULTI_BLOCK
|
||||
if ((cmd[1] == ISO15693_WRITEBLOCK) || (cmd[1] == ISO15693_WRITE_MULTI_BLOCK)) {
|
||||
bool slow = !(cmd[0] & ISO15_REQ_DATARATE_HIGH);
|
||||
bool addressed = cmd[0] & ISO15_REQ_ADDRESS;
|
||||
uint32_t response_time = reader_eof_time + DELAY_ISO15693_VCD_TO_VICC_SIM;
|
||||
|
||||
uint8_t address_offset = 0;
|
||||
if (addressed) {
|
||||
address_offset = 8;
|
||||
}
|
||||
|
||||
uint8_t block_idx = cmd[2 + address_offset];
|
||||
uint8_t block_count = 1;
|
||||
uint8_t multi_offset = 0;
|
||||
if (cmd[1] == ISO15693_WRITE_MULTI_BLOCK) {
|
||||
block_count = cmd[3 + address_offset] + 1;
|
||||
multi_offset = 1;
|
||||
}
|
||||
uint8_t *data = cmd + 3 + address_offset + multi_offset;
|
||||
|
||||
// write data
|
||||
EmlSetMemIso15693(block_count * block_size, data, block_idx * block_size);
|
||||
|
||||
// Build WRITE_(MULTI_)BLOCK response
|
||||
int response_length = 3;
|
||||
uint8_t resp_writeblock[response_length];
|
||||
memset(resp_writeblock, 0, response_length);
|
||||
resp_writeblock[0] = 0; // Response flags
|
||||
|
||||
// CRC
|
||||
AddCrc15(resp_writeblock, response_length - 2);
|
||||
CodeIso15693AsTag(resp_writeblock, response_length);
|
||||
|
||||
tosend_t *ts = get_tosend();
|
||||
|
||||
TransmitTo15693Reader(ts->buf, ts->max, &response_time, 0, slow);
|
||||
LogTrace_ISO15693(resp_writeblock, response_length, response_time * 32, (response_time * 32) + (ts->max * 32 * 64), NULL, false);
|
||||
}
|
||||
}
|
||||
|
||||
switch_off();
|
||||
|
|
|
@ -48,6 +48,7 @@ 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 EmlGetMemIso15693(uint8_t count, uint8_t *output, uint32_t offset);
|
||||
void SimTagIso15693(uint8_t *uid, uint8_t block_size); // 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
|
||||
|
|
|
@ -1043,7 +1043,7 @@ static int CmdHF15ELoad(const char *Cmd) {
|
|||
|
||||
uint8_t *data = NULL;
|
||||
size_t bytes_read = 0;
|
||||
int res = loadFile_safe(filename, ".bin", (void **)&data, &bytes_read);
|
||||
int res = pm3_load_dump(filename, (void **)&data, &bytes_read, CARD_MEMORY_SIZE);
|
||||
if (res != PM3_SUCCESS) {
|
||||
return res;
|
||||
}
|
||||
|
@ -1098,6 +1098,121 @@ static int CmdHF15ELoad(const char *Cmd) {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdHF15ESave(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf 15 esave",
|
||||
"Save emulator memory into three files (BIN/EML/JSON) ",
|
||||
"hf 15 esave -f hf-15-01020304"
|
||||
"hf 15 esave -b 8 -c 42 -f hf-15-01020304"
|
||||
);
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_str1("f", "file", "<fn>", "filename of dump"),
|
||||
arg_int0("b", "blocksize", "<dec>", "block size, defaults to 4"),
|
||||
arg_int0("c", "count", "<dec>", "number of blocks to export, defaults to all"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
int fnlen = 0;
|
||||
char filename[FILE_PATH_SIZE];
|
||||
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||
int blocksize = arg_get_int_def(ctx, 2, 4);
|
||||
int count = arg_get_int_def(ctx, 3, -1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
int bytes = CARD_MEMORY_SIZE;
|
||||
if (count > 0 && count * blocksize <= bytes) {
|
||||
bytes = count * blocksize;
|
||||
}
|
||||
|
||||
// reserve memory
|
||||
uint8_t *dump = calloc(bytes, sizeof(uint8_t));
|
||||
if (dump == NULL) {
|
||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "Downloading %u bytes from emulator memory", bytes);
|
||||
if (!GetFromDevice(BIG_BUF_EML, dump, bytes, 0, NULL, 0, NULL, 2500, false)) {
|
||||
PrintAndLogEx(WARNING, "Fail, transfer from device time-out");
|
||||
free(dump);
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
pm3_save_dump(filename, dump, bytes, jsf15, blocksize);
|
||||
free(dump);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static void print_hrule(int blocksize) {
|
||||
char dashes[] = "------------------------------------------------------------";
|
||||
PrintAndLogEx(INFO, "-----+%.*s-+-%.*s-", 3*blocksize, dashes, blocksize, dashes);
|
||||
}
|
||||
|
||||
static void print_blocks_15693(uint8_t *data, uint16_t bytes, int blocksize) {
|
||||
int blocks = bytes / blocksize;
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
print_hrule(blocksize);
|
||||
char spaces[] = " ";
|
||||
PrintAndLogEx(INFO, " blk | data %.*s| ascii", MAX(0, 3*blocksize - 5), spaces);
|
||||
print_hrule(blocksize);
|
||||
for (int i = 0; i < blocks; i++) {
|
||||
PrintAndLogEx(INFO, "%4d | %s ", i, sprint_hex_ascii(data + (i * blocksize), blocksize));
|
||||
|
||||
}
|
||||
if (bytes % blocksize != 0) {
|
||||
// If there is something left over print it too
|
||||
// This will have a broken layout, but should not happen anyway
|
||||
PrintAndLogEx(INFO, "%4d | %s ", blocks, sprint_hex_ascii(data + (blocks * blocksize),
|
||||
bytes % blocksize));
|
||||
}
|
||||
print_hrule(blocksize);
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
}
|
||||
|
||||
static int CmdHF15EView(const char *Cmd) {
|
||||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf 15 eview",
|
||||
"It displays emulator memory",
|
||||
"hf 15 eview\n"
|
||||
"hf 15 eview -b 8 -c 60\n"
|
||||
);
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_int0("b", "blocksize", "<dec>", "block size, defaults to 4"),
|
||||
arg_int0("c", "count", "<dec>", "number of blocks to display, defaults to all"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
int blocksize = arg_get_int_def(ctx, 1, 4);
|
||||
int count = arg_get_int_def(ctx, 2, -1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
int bytes = CARD_MEMORY_SIZE;
|
||||
if (count > 0 && count * blocksize <= bytes) {
|
||||
bytes = count * blocksize;
|
||||
}
|
||||
|
||||
uint8_t *dump = calloc(bytes, sizeof(uint8_t));
|
||||
if (dump == NULL) {
|
||||
PrintAndLogEx(WARNING, "Fail, cannot allocate memory");
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "Downloading %u bytes from emulator memory", bytes);
|
||||
if (!GetFromDevice(BIG_BUF_EML, dump, bytes, 0, NULL, 0, NULL, 2500, false)) {
|
||||
PrintAndLogEx(WARNING, "Fail, transfer from device time-out");
|
||||
free(dump);
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
|
||||
print_blocks_15693(dump, bytes, blocksize);
|
||||
free(dump);
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// Simulation is still not working very good
|
||||
// helptext
|
||||
static int CmdHF15Sim(const char *Cmd) {
|
||||
|
@ -2289,7 +2404,9 @@ 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"},
|
||||
{"eload", CmdHF15ELoad, IfPm3Iso15693, "Load image file into emulator to be used by 'sim' command"},
|
||||
{"esave", CmdHF15ESave, IfPm3Iso15693, "Save emulator memory into image file"},
|
||||
{"eview", CmdHF15EView, IfPm3Iso15693, "View emulator memory"},
|
||||
{"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"},
|
||||
|
|
Loading…
Add table
Reference in a new issue