mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
chg: 'trace load'
chg: 'trace save' all from @pwpivi PR in offical pm3 repo https://github.com/Proxmark/proxmark3/pull/577 Adapted for bigger filesizes and offline/online detection. Currently a bug somewhere....
This commit is contained in:
parent
71ce6e07ee
commit
7ecd35943c
1 changed files with 178 additions and 55 deletions
|
@ -11,11 +11,17 @@
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
// trace pointer
|
||||||
|
uint8_t *trace;
|
||||||
|
long traceLen = 0;
|
||||||
|
bool preRDV40 = true;
|
||||||
|
|
||||||
int usage_trace_list(){
|
int usage_trace_list(){
|
||||||
PrintAndLogEx(NORMAL, "List protocol data in trace buffer.");
|
PrintAndLogEx(NORMAL, "List protocol data in trace buffer.");
|
||||||
PrintAndLogEx(NORMAL, "Usage: trace list <protocol> [f][c]");
|
PrintAndLogEx(NORMAL, "Usage: trace list <protocol> [f][c| <0|1>");
|
||||||
PrintAndLogEx(NORMAL, " f - show frame delay times as well");
|
PrintAndLogEx(NORMAL, " f - show frame delay times as well");
|
||||||
PrintAndLogEx(NORMAL, " c - mark CRC bytes");
|
PrintAndLogEx(NORMAL, " c - mark CRC bytes");
|
||||||
|
PrintAndLogEx(NORMAL, " <0|1> - use data from Tracebuffer, if not set, try reading data from tag.");
|
||||||
PrintAndLogEx(NORMAL, "Supported <protocol> values:");
|
PrintAndLogEx(NORMAL, "Supported <protocol> values:");
|
||||||
PrintAndLogEx(NORMAL, " raw - just show raw data without annotations");
|
PrintAndLogEx(NORMAL, " raw - just show raw data without annotations");
|
||||||
PrintAndLogEx(NORMAL, " 14a - interpret data as iso14443a communications");
|
PrintAndLogEx(NORMAL, " 14a - interpret data as iso14443a communications");
|
||||||
|
@ -39,10 +45,16 @@ int usage_trace_list(){
|
||||||
}
|
}
|
||||||
int usage_trace_load(){
|
int usage_trace_load(){
|
||||||
PrintAndLogEx(NORMAL, "Load protocol data from file to trace buffer.");
|
PrintAndLogEx(NORMAL, "Load protocol data from file to trace buffer.");
|
||||||
|
PrintAndLogEx(NORMAL, "Usage: trace load <filename>");
|
||||||
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
|
PrintAndLogEx(NORMAL, " trace lload mytracefile.bin");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int usage_trace_save(){
|
int usage_trace_save(){
|
||||||
PrintAndLogEx(NORMAL, "Save protocol data from trace buffer to file.");
|
PrintAndLogEx(NORMAL, "Save protocol data from trace buffer to file.");
|
||||||
|
PrintAndLogEx(NORMAL, "Usage: trace save <filename>");
|
||||||
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
|
PrintAndLogEx(NORMAL, " trace save mytracefile.bin");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -383,75 +395,110 @@ void printFelica(uint16_t traceLen, uint8_t *trace) {
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sanity check. Don't use proxmark if it is offline and you didn't specify useTraceBuffer
|
||||||
|
static int SanityOfflineCheck( bool useTraceBuffer ){
|
||||||
|
if ( !useTraceBuffer && offline) {
|
||||||
|
PrintAndLogEx(NORMAL, "Your proxmark3 device is offline. Specify [1] to use TraceBuffer data instead");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int CmdTraceList(const char *Cmd) {
|
int CmdTraceList(const char *Cmd) {
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
|
|
||||||
bool showWaitCycles = false;
|
bool showWaitCycles = false;
|
||||||
bool markCRCBytes = false;
|
bool markCRCBytes = false;
|
||||||
char type[10] = {0};
|
bool isOnline = true;
|
||||||
//int tlen = param_getstr(Cmd,0,type);
|
|
||||||
char param1 = param_getchar(Cmd, 1);
|
|
||||||
char param2 = param_getchar(Cmd, 2);
|
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
uint8_t protocol = 0;
|
uint8_t protocol = 0;
|
||||||
|
char type[10] = {0};
|
||||||
|
|
||||||
//Validate params H or empty
|
//int tlen = param_getstr(Cmd,0,type);
|
||||||
if (strlen(Cmd) < 1 || param1 == 'h' || param1 == 'H') return usage_trace_list();
|
//char param1 = param_getchar(Cmd, 1);
|
||||||
|
//char param2 = param_getchar(Cmd, 2);
|
||||||
//Validate params F,C
|
|
||||||
if(
|
char cmdp = 0;
|
||||||
(param1 != 0 && param1 != 'f' && param1 != 'c') ||
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
(param2 != 0 && param2 != 'f' && param2 != 'c')
|
|
||||||
) {
|
int slen = param_getstr(Cmd, cmdp, type, sizeof(type) );
|
||||||
return usage_trace_list();
|
if ( slen == 1) {
|
||||||
|
|
||||||
|
switch ( tolower(param_getchar(Cmd, cmdp))) {
|
||||||
|
case 'h':
|
||||||
|
return usage_trace_list();
|
||||||
|
case 'f':
|
||||||
|
showWaitCycles = true;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
markCRCBytes = true;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
isOnline = false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
str_lower(type);
|
||||||
|
PrintAndLogEx(WARNING, "to lower");
|
||||||
|
|
||||||
|
// validate type of output
|
||||||
|
if (strcmp(type, "iclass") == 0) protocol = ICLASS;
|
||||||
|
else if(strcmp(type, "14a") == 0) protocol = ISO_14443A;
|
||||||
|
else if(strcmp(type, "14b") == 0) protocol = ISO_14443B;
|
||||||
|
else if(strcmp(type, "topaz") == 0) protocol = TOPAZ;
|
||||||
|
else if(strcmp(type, "7816") == 0) protocol = ISO_7816_4;
|
||||||
|
else if(strcmp(type, "des") == 0) protocol = MFDES;
|
||||||
|
else if(strcmp(type, "legic") == 0) protocol = LEGIC;
|
||||||
|
else if(strcmp(type, "15") == 0) protocol = ISO_15693;
|
||||||
|
else if(strcmp(type, "felica") == 0) protocol = FELICA;
|
||||||
|
else if(strcmp(type, "mf") == 0) protocol = PROTO_MIFARE;
|
||||||
|
else if(strcmp(type, "raw") == 0) protocol = -1;//No crc, no annotations
|
||||||
|
else errors = true;
|
||||||
|
|
||||||
|
cmdp++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
param_getstr(Cmd, 0, type, sizeof(type) );
|
|
||||||
|
|
||||||
// validate type of output
|
if (!SanityOfflineCheck(isOnline)) return 1;
|
||||||
if (strcmp(type, "iclass") == 0) protocol = ICLASS;
|
|
||||||
else if(strcmp(type, "14a") == 0) protocol = ISO_14443A;
|
//Validations
|
||||||
else if(strcmp(type, "14b") == 0) protocol = ISO_14443B;
|
|
||||||
else if(strcmp(type, "topaz") == 0) protocol = TOPAZ;
|
|
||||||
else if(strcmp(type, "7816") == 0) protocol = ISO_7816_4;
|
|
||||||
else if(strcmp(type, "des") == 0) protocol = MFDES;
|
|
||||||
else if(strcmp(type, "legic") == 0) protocol = LEGIC;
|
|
||||||
else if(strcmp(type, "15") == 0) protocol = ISO_15693;
|
|
||||||
else if(strcmp(type, "felica") == 0) protocol = FELICA;
|
|
||||||
else if(strcmp(type, "mf") == 0) protocol = PROTO_MIFARE;
|
|
||||||
else if(strcmp(type, "raw") == 0) protocol = -1;//No crc, no annotations
|
|
||||||
else errors = true;
|
|
||||||
|
|
||||||
if (errors) return usage_trace_list();
|
if (errors) return usage_trace_list();
|
||||||
|
|
||||||
if (param1 == 'f' || param2 == 'f') showWaitCycles = true;
|
|
||||||
if (param1 == 'c' || param2 == 'c') markCRCBytes = true;
|
|
||||||
|
|
||||||
uint8_t *trace;
|
|
||||||
uint16_t tracepos = 0;
|
uint16_t tracepos = 0;
|
||||||
trace = malloc(USB_CMD_DATA_SIZE);
|
|
||||||
|
|
||||||
// Query for the size of the trace
|
|
||||||
UsbCommand response;
|
|
||||||
GetFromBigBuf(trace, USB_CMD_DATA_SIZE, 0);
|
|
||||||
if ( !WaitForResponseTimeout(CMD_ACK, &response, 4000) ) {
|
|
||||||
PrintAndLogEx(FAILED, "timeout while waiting for reply.");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t traceLen = response.arg[2];
|
if ( !isOnline ) {
|
||||||
if (traceLen > USB_CMD_DATA_SIZE) {
|
// Query for the size of the trace
|
||||||
uint8_t *p = realloc(trace, traceLen);
|
UsbCommand response;
|
||||||
if (p == NULL) {
|
GetFromBigBuf(trace, USB_CMD_DATA_SIZE, 0);
|
||||||
PrintAndLogEx(FAILED, "Cannot allocate memory for trace");
|
if ( !WaitForResponseTimeout(CMD_ACK, &response, 4000) ) {
|
||||||
free(trace);
|
PrintAndLogEx(FAILED, "timeout while waiting for reply.");
|
||||||
return 2;
|
return 1;
|
||||||
}
|
}
|
||||||
trace = p;
|
|
||||||
GetFromBigBuf(trace, traceLen, 0);
|
traceLen = response.arg[2];
|
||||||
WaitForResponse(CMD_ACK, NULL);
|
if (traceLen > USB_CMD_DATA_SIZE) {
|
||||||
|
uint8_t *p = realloc(trace, traceLen);
|
||||||
|
if (p == NULL) {
|
||||||
|
PrintAndLogEx(FAILED, "Cannot allocate memory for trace");
|
||||||
|
free(trace);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
trace = p;
|
||||||
|
GetFromBigBuf(trace, traceLen, 0);
|
||||||
|
WaitForResponse(CMD_ACK, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLogEx(NORMAL, "Recorded Activity (TraceLen = %d bytes)", traceLen);
|
PrintAndLogEx(NORMAL, "Recorded Activity (TraceLen = %d bytes)", traceLen);
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
if (protocol == FELICA) {
|
if (protocol == FELICA) {
|
||||||
|
@ -483,10 +530,86 @@ int CmdTraceList(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdTraceLoad(const char *Cmd) {
|
int CmdTraceLoad(const char *Cmd) {
|
||||||
|
|
||||||
|
FILE *f = NULL;
|
||||||
|
size_t bytes_read;
|
||||||
|
uint8_t buf[2];
|
||||||
|
char filename[FILE_PATH_SIZE];
|
||||||
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_trace_load();
|
||||||
|
|
||||||
|
param_getstr(Cmd, 0, filename, sizeof(filename));
|
||||||
|
|
||||||
|
if ((f = fopen(filename,"rb")) == NULL) {
|
||||||
|
PrintAndLog("Could not open file %s", filename);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get filesize in order to malloc memory
|
||||||
|
fseek(f, 0, SEEK_END);
|
||||||
|
long fsize = ftell(f);
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
|
|
||||||
|
if (fsize < 0) {
|
||||||
|
PrintAndLogDevice(WARNING, "error, when getting filesize");
|
||||||
|
fclose(f);
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
// iceman, RDV40 be able to log much bigger than 64kb.
|
||||||
|
// so this two byte limit will have a magic value (above 40kb limit from bigbuff)
|
||||||
|
// or we just skip this limit at all
|
||||||
|
bytes_read = fread(buf, 1, 2, f);
|
||||||
|
if (bytes_read != 2) {
|
||||||
|
PrintAndLog("File reading error.");
|
||||||
|
fclose(f);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RDV40 will have bigger traces
|
||||||
|
if (fsize > traceLen + 2 ){
|
||||||
|
traceLen = fsize;
|
||||||
|
trace = malloc(fsize);
|
||||||
|
} else {
|
||||||
|
traceLen = bytes_to_num(buf, 2); // little endian in file
|
||||||
|
trace = malloc(traceLen+2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (trace == NULL) {
|
||||||
|
PrintAndLog("Cannot allocate memory for trace");
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes_read = fread(trace, 1, traceLen, f);
|
||||||
|
if (bytes_read != traceLen) {
|
||||||
|
PrintAndLog("File reading error.");
|
||||||
|
fclose(f);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdTraceSave(const char *Cmd) {
|
int CmdTraceSave(const char *Cmd) {
|
||||||
|
FILE *f = NULL;
|
||||||
|
uint8_t buf[2] = {0x01, 0xCE};
|
||||||
|
char filename[FILE_PATH_SIZE];
|
||||||
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') return usage_trace_save();
|
||||||
|
|
||||||
|
param_getstr(Cmd, 0, filename, sizeof(filename));
|
||||||
|
|
||||||
|
if ((f = fopen(filename, "wb")) == NULL) {
|
||||||
|
PrintAndLog("Could not create file %s", filename);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 40kb bigbuffer limit
|
||||||
|
if ( 40000 <= traceLen ){
|
||||||
|
num_to_bytes(traceLen, 2, buf);
|
||||||
|
}
|
||||||
|
fwrite(buf, 1, 2, f);
|
||||||
|
fwrite(trace, 1, traceLen, f);
|
||||||
|
PrintAndLog("Recorded Activity (TraceLen = %d bytes) written to file %s", traceLen, filename);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue