mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
adapted hf iclass list to new trace format
This commit is contained in:
parent
db4de4d82f
commit
545f203826
2 changed files with 111 additions and 216 deletions
|
@ -78,6 +78,10 @@ int CmdHF14AList(const char *Cmd)
|
||||||
if(tracepos == 0) {
|
if(tracepos == 0) {
|
||||||
first_timestamp = timestamp;
|
first_timestamp = timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Break and stick with current result if buffer was not completely full
|
||||||
|
if (timestamp == 0x44444444) break;
|
||||||
|
|
||||||
tracepos += 4;
|
tracepos += 4;
|
||||||
duration = *((uint16_t *)(trace + tracepos));
|
duration = *((uint16_t *)(trace + tracepos));
|
||||||
tracepos += 2;
|
tracepos += 2;
|
||||||
|
@ -102,9 +106,6 @@ int CmdHF14AList(const char *Cmd)
|
||||||
uint8_t *parityBytes = trace + tracepos;
|
uint8_t *parityBytes = trace + tracepos;
|
||||||
tracepos += parity_len;
|
tracepos += parity_len;
|
||||||
|
|
||||||
// Break and stick with current result if buffer was not completely full
|
|
||||||
if (timestamp == 0x44444444) break;
|
|
||||||
|
|
||||||
char line[16][110];
|
char line[16][110];
|
||||||
for (int j = 0; j < data_len; j++) {
|
for (int j = 0; j < data_len; j++) {
|
||||||
int oddparity = 0x01;
|
int oddparity = 0x01;
|
||||||
|
|
|
@ -44,7 +44,6 @@ int xorbits_8(uint8_t val)
|
||||||
|
|
||||||
int CmdHFiClassList(const char *Cmd)
|
int CmdHFiClassList(const char *Cmd)
|
||||||
{
|
{
|
||||||
|
|
||||||
bool ShowWaitCycles = false;
|
bool ShowWaitCycles = false;
|
||||||
char param = param_getchar(Cmd, 0);
|
char param = param_getchar(Cmd, 0);
|
||||||
|
|
||||||
|
@ -56,164 +55,70 @@ int CmdHFiClassList(const char *Cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t got[1920];
|
// for the time being. Need better Bigbuf handling.
|
||||||
GetFromBigBuf(got,sizeof(got),0);
|
#define TRACE_SIZE 3000
|
||||||
WaitForResponse(CMD_ACK,NULL);
|
|
||||||
|
uint8_t trace[TRACE_SIZE];
|
||||||
|
GetFromBigBuf(trace, TRACE_SIZE, 0);
|
||||||
|
WaitForResponse(CMD_ACK, NULL);
|
||||||
|
|
||||||
PrintAndLog("Recorded Activity");
|
PrintAndLog("Recorded Activity");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer");
|
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("All times are in carrier periods (1/13.56Mhz)");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
PrintAndLog(" Start | End | Src | Data");
|
PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC ");
|
||||||
PrintAndLog("-----------|-----------|-----|--------");
|
PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------------");
|
||||||
|
|
||||||
int i;
|
uint16_t tracepos = 0;
|
||||||
uint32_t first_timestamp = 0;
|
uint16_t duration;
|
||||||
|
uint16_t data_len;
|
||||||
|
uint16_t parity_len;
|
||||||
|
bool isResponse;
|
||||||
uint32_t timestamp;
|
uint32_t timestamp;
|
||||||
bool tagToReader;
|
uint32_t first_timestamp;
|
||||||
uint32_t parityBits;
|
uint32_t EndOfTransmissionTimestamp;
|
||||||
uint8_t len;
|
|
||||||
uint8_t *frame;
|
|
||||||
uint32_t EndOfTransmissionTimestamp = 0;
|
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
|
||||||
for( i=0; i < 1900;)
|
if(tracepos >= TRACE_SIZE) {
|
||||||
{
|
break;
|
||||||
//First 32 bits contain
|
}
|
||||||
// isResponse (1 bit)
|
|
||||||
// timestamp (remaining)
|
|
||||||
//Then paritybits
|
|
||||||
//Then length
|
|
||||||
timestamp = *((uint32_t *)(got+i));
|
|
||||||
parityBits = *((uint32_t *)(got+i+4));
|
|
||||||
len = got[i+8];
|
|
||||||
frame = (got+i+9);
|
|
||||||
uint32_t next_timestamp = (*((uint32_t *)(got+i+9))) & 0x7fffffff;
|
|
||||||
|
|
||||||
tagToReader = timestamp & 0x80000000;
|
timestamp = *((uint32_t *)(trace + tracepos));
|
||||||
timestamp &= 0x7fffffff;
|
if(tracepos == 0) {
|
||||||
|
|
||||||
if(i==0) {
|
|
||||||
first_timestamp = timestamp;
|
first_timestamp = timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Break and stick with current result idf buffer was not completely full
|
|
||||||
if (frame[0] == 0x44 && frame[1] == 0x44 && frame[2] == 0x44 && frame[3] == 0x44) break;
|
|
||||||
|
|
||||||
char line[1000] = "";
|
|
||||||
|
|
||||||
if(len)//We have some data to display
|
|
||||||
{
|
|
||||||
int j,oddparity;
|
|
||||||
|
|
||||||
for(j = 0; j < len ; j++)
|
|
||||||
{
|
|
||||||
oddparity = 0x01 ^ xorbits_8(frame[j] & 0xFF);
|
|
||||||
|
|
||||||
if (tagToReader && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
|
|
||||||
sprintf(line+(j*4), "%02x! ", frame[j]);
|
|
||||||
} else {
|
|
||||||
sprintf(line+(j*4), "%02x ", frame[j]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}else
|
|
||||||
{
|
|
||||||
if (ShowWaitCycles) {
|
|
||||||
sprintf(line, "fdt (Frame Delay Time): %d", (next_timestamp - timestamp));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char *crc = "";
|
|
||||||
|
|
||||||
if(len > 2)
|
|
||||||
{
|
|
||||||
uint8_t b1, b2;
|
|
||||||
if(!tagToReader && 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], len-3, &b1, &b2);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// For other data.. CRC might not be applicable (UPDATE commands etc.)
|
|
||||||
ComputeCrc14443(CRC_ICLASS, frame, len-2, &b1, &b2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b1 != frame[len-2] || b2 != frame[len-1]) {
|
|
||||||
crc = (tagToReader & (len < 8)) ? "" : " !crc";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
i += (len + 9);
|
|
||||||
EndOfTransmissionTimestamp = (*((uint32_t *)(got+i))) & 0x7fffffff;
|
|
||||||
|
|
||||||
// Not implemented for iclass on the ARM-side
|
|
||||||
//if (!ShowWaitCycles) i += 9;
|
|
||||||
|
|
||||||
PrintAndLog(" %9d | %9d | %s | %s %s",
|
|
||||||
(timestamp - first_timestamp),
|
|
||||||
(EndOfTransmissionTimestamp - first_timestamp),
|
|
||||||
(len?(tagToReader ? "Tag" : "Rdr"):" "),
|
|
||||||
line, crc);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int CmdHFiClassListOld(const char *Cmd)
|
|
||||||
{
|
|
||||||
uint8_t got[1920];
|
|
||||||
GetFromBigBuf(got,sizeof(got),0);
|
|
||||||
|
|
||||||
PrintAndLog("recorded activity:");
|
|
||||||
PrintAndLog(" ETU :rssi: who bytes");
|
|
||||||
PrintAndLog("---------+----+----+-----------");
|
|
||||||
|
|
||||||
int i = 0;
|
|
||||||
int prev = -1;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
if(i >= 1900) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isResponse;
|
|
||||||
int timestamp = *((uint32_t *)(got+i));
|
|
||||||
if (timestamp & 0x80000000) {
|
|
||||||
timestamp &= 0x7fffffff;
|
|
||||||
isResponse = 1;
|
|
||||||
} else {
|
|
||||||
isResponse = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int metric = 0;
|
|
||||||
|
|
||||||
int parityBits = *((uint32_t *)(got+i+4));
|
|
||||||
// 4 bytes of additional information...
|
|
||||||
// maximum of 32 additional parity bit information
|
|
||||||
//
|
|
||||||
// TODO:
|
|
||||||
// at each quarter bit period we can send power level (16 levels)
|
|
||||||
// or each half bit period in 256 levels.
|
|
||||||
|
|
||||||
|
|
||||||
int len = got[i+8];
|
|
||||||
|
|
||||||
if (len > 100) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (i + len >= 1900) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t *frame = (got+i+9);
|
|
||||||
|
|
||||||
// Break and stick with current result if buffer was not completely full
|
// Break and stick with current result if buffer was not completely full
|
||||||
if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
|
if (timestamp == 0x44444444) break;
|
||||||
|
|
||||||
char line[1000] = "";
|
tracepos += 4;
|
||||||
int j;
|
duration = *((uint16_t *)(trace + tracepos));
|
||||||
for (j = 0; j < len; j++) {
|
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 oddparity = 0x01;
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
|
@ -221,79 +126,68 @@ int CmdHFiClassListOld(const char *Cmd)
|
||||||
oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
|
oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if((parityBits >> (len - j - 1)) & 0x01) {
|
uint8_t parityBits = parityBytes[j>>3];
|
||||||
if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
|
if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
|
||||||
sprintf(line+(j*4), "%02x! ", frame[j]);
|
sprintf(line[j/16]+((j%16)*4), "%02x! ", frame[j]);
|
||||||
}
|
} else {
|
||||||
else {
|
sprintf(line[j/16]+((j%16)*4), "%02x ", frame[j]);
|
||||||
sprintf(line+(j*4), "%02x ", frame[j]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *crc;
|
}
|
||||||
crc = "";
|
|
||||||
if (len > 2) {
|
char *crc = "";
|
||||||
|
if (data_len > 2) {
|
||||||
uint8_t b1, b2;
|
uint8_t b1, b2;
|
||||||
for (j = 0; j < (len - 1); j++) {
|
if(!isResponse && data_len == 4 ) {
|
||||||
// gives problems... search for the reason..
|
|
||||||
/*if(frame[j] == 0xAA) {
|
|
||||||
switch(frame[j+1]) {
|
|
||||||
case 0x01:
|
|
||||||
crc = "[1] Two drops close after each other";
|
|
||||||
break;
|
|
||||||
case 0x02:
|
|
||||||
crc = "[2] Potential SOC with a drop in second half of bitperiod";
|
|
||||||
break;
|
|
||||||
case 0x03:
|
|
||||||
crc = "[3] Segment Z after segment X is not possible";
|
|
||||||
break;
|
|
||||||
case 0x04:
|
|
||||||
crc = "[4] Parity bit of a fully received byte was wrong";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
crc = "[?] Unknown error";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen(crc)==0) {
|
|
||||||
if(!isResponse && len == 4) {
|
|
||||||
// Rough guess that this is a command from the reader
|
// Rough guess that this is a command from the reader
|
||||||
// For iClass the command byte is not part of the CRC
|
// For iClass the command byte is not part of the CRC
|
||||||
ComputeCrc14443(CRC_ICLASS, &frame[1], len-3, &b1, &b2);
|
ComputeCrc14443(CRC_ICLASS, &frame[1], data_len-3, &b1, &b2);
|
||||||
|
if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
|
||||||
|
crc = "!crc";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// For other data.. CRC might not be applicable (UPDATE commands etc.)
|
// For other data.. CRC might not be applicable (UPDATE commands etc.)
|
||||||
ComputeCrc14443(CRC_ICLASS, frame, len-2, &b1, &b2);
|
ComputeCrc14443(CRC_ICLASS, frame, data_len-2, &b1, &b2);
|
||||||
}
|
if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
|
||||||
//printf("%1x %1x",(unsigned)b1,(unsigned)b2);
|
crc = "!crc";
|
||||||
if (b1 != frame[len-2] || b2 != frame[len-1]) {
|
|
||||||
crc = (isResponse & (len < 8)) ? "" : " !crc";
|
|
||||||
} else {
|
|
||||||
crc = "";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
crc = ""; // SHORT
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char metricString[100];
|
EndOfTransmissionTimestamp = timestamp + duration;
|
||||||
if (isResponse) {
|
|
||||||
sprintf(metricString, "%3d", metric);
|
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",
|
||||||
|
(timestamp - first_timestamp),
|
||||||
|
(EndOfTransmissionTimestamp - first_timestamp),
|
||||||
|
(isResponse ? "Tag" : "Rdr"),
|
||||||
|
line[j],
|
||||||
|
(j == num_lines-1)?crc:"");
|
||||||
} else {
|
} else {
|
||||||
strcpy(metricString, " ");
|
PrintAndLog(" | | | %-64s| %s",
|
||||||
|
line[j],
|
||||||
|
(j == num_lines-1)?crc:"");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLog(" +%7d: %s: %s %s %s",
|
bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
|
||||||
(prev < 0 ? 0 : (timestamp - prev)),
|
|
||||||
metricString,
|
|
||||||
(isResponse ? "TAG" : " "), line, crc);
|
|
||||||
|
|
||||||
prev = timestamp;
|
if (ShowWaitCycles && !isResponse && next_isResponse) {
|
||||||
i += (len + 9);
|
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));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue