mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 18:48:13 -07:00
Reworked how 'hf 14a list' and 'hf iclass list' works, to use the same method. Now. use 'hf list 14a' and 'hf list iclass' instead. Plus, the output is now annotated (although the annotation-engine could use a bit more love from someone more familiar with the available commands
This commit is contained in:
parent
c8dd9b092e
commit
4c3de57ad2
4 changed files with 283 additions and 290 deletions
|
@ -80,151 +80,7 @@ void explain(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
|||
|
||||
int CmdHFiClassList(const char *Cmd)
|
||||
{
|
||||
bool ShowWaitCycles = false;
|
||||
char param = param_getchar(Cmd, 0);
|
||||
|
||||
if (param != 0) {
|
||||
PrintAndLog("List data in trace buffer.");
|
||||
PrintAndLog("Usage: hf iclass list");
|
||||
PrintAndLog("h - help");
|
||||
PrintAndLog("sample: hf iclass list");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// for the time being. Need better Bigbuf handling.
|
||||
#define TRACE_SIZE 3000
|
||||
|
||||
uint8_t trace[TRACE_SIZE];
|
||||
GetFromBigBuf(trace, TRACE_SIZE, 0);
|
||||
WaitForResponse(CMD_ACK, NULL);
|
||||
|
||||
PrintAndLog("Recorded Activity");
|
||||
PrintAndLog("");
|
||||
PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer");
|
||||
PrintAndLog("All times are in carrier periods (1/13.56Mhz)");
|
||||
PrintAndLog("");
|
||||
PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC | Explanation|");
|
||||
PrintAndLog("-----------|-----------|-----|-------------------------------------------------------------------------------------");
|
||||
|
||||
uint16_t tracepos = 0;
|
||||
uint16_t duration;
|
||||
uint16_t data_len;
|
||||
uint16_t parity_len;
|
||||
bool isResponse;
|
||||
uint32_t timestamp;
|
||||
uint32_t first_timestamp;
|
||||
uint32_t EndOfTransmissionTimestamp;
|
||||
char explanation[20] = {0};
|
||||
for (;;) {
|
||||
|
||||
if(tracepos >= TRACE_SIZE) {
|
||||
break;
|
||||
}
|
||||
|
||||
timestamp = *((uint32_t *)(trace + tracepos));
|
||||
if(tracepos == 0) {
|
||||
first_timestamp = timestamp;
|
||||
}
|
||||
|
||||
// Break and stick with current result if buffer was not completely full
|
||||
if (timestamp == 0x44444444) break;
|
||||
|
||||
tracepos += 4;
|
||||
duration = *((uint16_t *)(trace + tracepos));
|
||||
tracepos += 2;
|
||||
data_len = *((uint16_t *)(trace + tracepos));
|
||||
tracepos += 2;
|
||||
|
||||
if (data_len & 0x8000) {
|
||||
data_len &= 0x7fff;
|
||||
isResponse = true;
|
||||
} else {
|
||||
isResponse = false;
|
||||
}
|
||||
|
||||
parity_len = (data_len-1)/8 + 1;
|
||||
|
||||
if (tracepos + data_len + parity_len >= TRACE_SIZE) {
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t *frame = trace + tracepos;
|
||||
tracepos += data_len;
|
||||
uint8_t *parityBytes = trace + tracepos;
|
||||
tracepos += parity_len;
|
||||
|
||||
char line[16][110];
|
||||
for (int j = 0; j < data_len; j++) {
|
||||
int oddparity = 0x01;
|
||||
int k;
|
||||
|
||||
for (k=0;k<8;k++) {
|
||||
oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
|
||||
}
|
||||
|
||||
uint8_t parityBits = parityBytes[j>>3];
|
||||
if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
|
||||
sprintf(line[j/16]+((j%16)*4), "%02x! ", frame[j]);
|
||||
} else {
|
||||
sprintf(line[j/16]+((j%16)*4), "%02x ", frame[j]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
char *crc = " ";
|
||||
if (data_len > 2) {
|
||||
uint8_t b1, b2;
|
||||
if(!isResponse && data_len == 4 ) {
|
||||
// Rough guess that this is a command from the reader
|
||||
// For iClass the command byte is not part of the CRC
|
||||
ComputeCrc14443(CRC_ICLASS, &frame[1], data_len-3, &b1, &b2);
|
||||
if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
|
||||
crc = "!crc";
|
||||
}
|
||||
}
|
||||
else {
|
||||
// For other data.. CRC might not be applicable (UPDATE commands etc.)
|
||||
ComputeCrc14443(CRC_ICLASS, frame, data_len-2, &b1, &b2);
|
||||
if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
|
||||
crc = "!crc";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EndOfTransmissionTimestamp = timestamp + duration;
|
||||
explain(explanation,sizeof(explanation),frame,data_len);
|
||||
int num_lines = (data_len - 1)/16 + 1;
|
||||
for (int j = 0; j < num_lines; j++) {
|
||||
if (j == 0) {
|
||||
PrintAndLog(" %9d | %9d | %s | %-64s| %s| %s",
|
||||
(timestamp - first_timestamp),
|
||||
(EndOfTransmissionTimestamp - first_timestamp),
|
||||
(isResponse ? "Tag" : "Rdr"),
|
||||
line[j],
|
||||
(j == num_lines-1)?crc:" ",
|
||||
explanation);
|
||||
} else {
|
||||
PrintAndLog(" | | | %-64s| %s",
|
||||
line[j],
|
||||
(j == num_lines-1)?crc:" ");
|
||||
}
|
||||
}
|
||||
|
||||
bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
|
||||
|
||||
if (ShowWaitCycles && !isResponse && next_isResponse) {
|
||||
uint32_t next_timestamp = *((uint32_t *)(trace + tracepos));
|
||||
if (next_timestamp != 0x44444444) {
|
||||
PrintAndLog(" %9d | %9d | %s | fdt (Frame Delay Time): %d",
|
||||
(EndOfTransmissionTimestamp - first_timestamp),
|
||||
(next_timestamp - first_timestamp),
|
||||
" ",
|
||||
(next_timestamp - EndOfTransmissionTimestamp));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
PrintAndLog("Deprecated command, use 'hf list iclass' instead");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -619,7 +475,7 @@ int CmdHFiClass_iso14443A_write(const char *Cmd)
|
|||
static command_t CommandTable[] =
|
||||
{
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"list", CmdHFiClassList, 0, "List iClass history"},
|
||||
{"list", CmdHFiClassList, 0, "[Deprecated] List iClass history"},
|
||||
{"snoop", CmdHFiClassSnoop, 0, "Eavesdrop iClass communication"},
|
||||
{"sim", CmdHFiClassSim, 0, "Simulate iClass tag"},
|
||||
{"reader",CmdHFiClassReader, 0, "Read an iClass tag"},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue