BigBuf and tracing rework: allow much longer traces in in hf commands

- provided a BigBuf_malloc() function to dynamically allocate parts of BigBuf
  e.g. for DMA-Buffers, Frame-Buffers, Emulator-Memory
- the whole rest of BigBuf is now available for traces (instead of a small fixed amount)
- send actual traceLen together with trace data
- changed client side to cope with varying traceLen
- changed small buffers to automatic variables instead of parts of BigBuf
This commit is contained in:
pwpiwi 2015-01-27 08:34:48 +01:00
commit f71f4deb8f
22 changed files with 485 additions and 400 deletions

View file

@ -1426,7 +1426,7 @@ int CmdHexsamples(const char *Cmd)
int offset = 0;
char string_buf[25];
char* string_ptr = string_buf;
uint8_t got[40000];
uint8_t got[BIGBUF_SIZE];
sscanf(Cmd, "%i %i", &requested, &offset);
@ -1435,7 +1435,7 @@ int CmdHexsamples(const char *Cmd)
requested = 8;
}
if (offset + requested > sizeof(got)) {
PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > 40000");
PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > %d", BIGBUF_SIZE);
return 0;
}
@ -1485,7 +1485,7 @@ int CmdHpf(const char *Cmd)
int CmdSamples(const char *Cmd)
{
uint8_t got[40000] = {0x00};
uint8_t got[BIGBUF_SIZE] = {0x00};
int n = strtol(Cmd, NULL, 0);
if (n == 0)
@ -1495,14 +1495,14 @@ int CmdSamples(const char *Cmd)
n = sizeof(got);
PrintAndLog("Reading %d samples from device memory\n", n);
GetFromBigBuf(got,n,0);
WaitForResponse(CMD_ACK,NULL);
GetFromBigBuf(got,n,0);
WaitForResponse(CMD_ACK,NULL);
for (int j = 0; j < n; j++) {
GraphBuffer[j] = ((int)got[j]) - 128;
}
GraphTraceLen = n;
RepaintGraphWindow();
return 0;
}
GraphTraceLen = n;
RepaintGraphWindow();
return 0;
}
int CmdTuneSamples(const char *Cmd)

View file

@ -60,4 +60,6 @@ int CmdIndalaDecode(const char *Cmd);
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
extern int DemodBufferLen;
#define BIGBUF_SIZE 40000
#endif

View file

@ -32,8 +32,6 @@ int CmdHFTune(const char *Cmd)
SendCommand(&c);
return 0;
}
// for the time being. Need better Bigbuf handling.
#define TRACE_SIZE 3000
//The following data is taken from http://www.proxmark.org/forum/viewtopic.php?pid=13501#p13501
/*
@ -384,18 +382,18 @@ uint8_t iclass_CRC_check(bool isResponse, uint8_t* data, uint8_t len)
}
}
uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, bool showWaitCycles)
uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, uint8_t protocol, bool showWaitCycles)
{
bool isResponse;
uint16_t duration, data_len,parity_len;
uint16_t duration, data_len, parity_len;
uint32_t timestamp, first_timestamp, EndOfTransmissionTimestamp;
char explanation[30] = {0};
if (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen) return traceLen;
first_timestamp = *((uint32_t *)(trace));
timestamp = *((uint32_t *)(trace + tracepos));
// Break and stick with current result if buffer was not completely full
if (timestamp == 0x44444444) return TRACE_SIZE;
tracepos += 4;
duration = *((uint16_t *)(trace + tracepos));
@ -411,8 +409,8 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, boo
}
parity_len = (data_len-1)/8 + 1;
if (tracepos + data_len + parity_len >= TRACE_SIZE) {
return TRACE_SIZE;
if (tracepos + data_len + parity_len > traceLen) {
return traceLen;
}
uint8_t *frame = trace + tracepos;
@ -498,6 +496,8 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, boo
}
}
if (tracepos + sizeof(uint32_t) + sizeof(uint16_t) + sizeof(uint16_t) > traceLen) return traceLen;
bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
if (showWaitCycles && !isResponse && next_isResponse) {
@ -510,9 +510,11 @@ uint16_t printTraceLine(uint16_t tracepos, uint8_t* trace, uint8_t protocol, boo
(next_timestamp - EndOfTransmissionTimestamp));
}
}
return tracepos;
}
int CmdHFList(const char *Cmd)
{
bool showWaitCycles = false;
@ -570,12 +572,28 @@ int CmdHFList(const char *Cmd)
}
uint8_t trace[TRACE_SIZE];
uint8_t *trace;
uint16_t tracepos = 0;
GetFromBigBuf(trace, TRACE_SIZE, 0);
WaitForResponse(CMD_ACK, NULL);
trace = malloc(USB_CMD_DATA_SIZE);
PrintAndLog("Recorded Activity");
// Query for the size of the trace
UsbCommand response;
GetFromBigBuf(trace, USB_CMD_DATA_SIZE, 0);
WaitForResponse(CMD_ACK, &response);
uint16_t traceLen = response.arg[2];
if (traceLen > USB_CMD_DATA_SIZE) {
uint8_t *p = realloc(trace, traceLen);
if (p == NULL) {
PrintAndLog("Cannot allocate memory for trace");
free(trace);
return 2;
}
trace = p;
GetFromBigBuf(trace, traceLen, 0);
WaitForResponse(CMD_ACK, NULL);
}
PrintAndLog("Recorded Activity (TraceLen = %d bytes)", traceLen);
PrintAndLog("");
PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer");
PrintAndLog("iso14443a - All times are in carrier periods (1/13.56Mhz)");
@ -584,10 +602,12 @@ int CmdHFList(const char *Cmd)
PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC | Annotation |");
PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------|-----|--------------------|");
while(tracepos < TRACE_SIZE)
while(tracepos < traceLen)
{
tracepos = printTraceLine(tracepos, trace, protocol, showWaitCycles);
tracepos = printTraceLine(tracepos, traceLen, trace, protocol, showWaitCycles);
}
free(trace);
return 0;
}

View file

@ -145,11 +145,25 @@ demodError:
int CmdHF14BList(const char *Cmd)
{
uint8_t got[TRACE_BUFFER_SIZE];
GetFromBigBuf(got,sizeof(got),0);
WaitForResponse(CMD_ACK,NULL);
uint8_t *got = malloc(USB_CMD_DATA_SIZE);
PrintAndLog("recorded activity:");
// Query for the actual size of the trace
UsbCommand response;
GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0);
WaitForResponse(CMD_ACK, &response);
uint16_t traceLen = response.arg[2];
if (traceLen > USB_CMD_DATA_SIZE) {
uint8_t *p = realloc(got, traceLen);
if (p == NULL) {
PrintAndLog("Cannot allocate memory for trace");
free(got);
return 2;
}
got = p;
GetFromBigBuf(got, traceLen, 0);
WaitForResponse(CMD_ACK,NULL);
}
PrintAndLog("recorded activity: (TraceLen = %d bytes)", traceLen);
PrintAndLog(" time :rssi: who bytes");
PrintAndLog("---------+----+----+-----------");
@ -158,7 +172,7 @@ int CmdHF14BList(const char *Cmd)
for(;;) {
if(i >= TRACE_BUFFER_SIZE) { break; }
if(i >= traceLen) { break; }
bool isResponse;
int timestamp = *((uint32_t *)(got+i));
@ -175,7 +189,7 @@ int CmdHF14BList(const char *Cmd)
if(len > 100) {
break;
}
if(i + len >= TRACE_BUFFER_SIZE) {
if(i + len >= traceLen) {
break;
}
@ -218,6 +232,7 @@ int CmdHF14BList(const char *Cmd)
prev = timestamp;
i += (len + 9);
}
free(got);
return 0;
}

View file

@ -1765,15 +1765,16 @@ int CmdHF14AMfSniff(const char *Cmd){
int res = 0;
int len = 0;
int blockLen = 0;
int num = 0;
int pckNum = 0;
uint8_t uid[7] = {0x00};
int num = 0;
uint8_t uid[7];
uint8_t uid_len;
uint8_t atqa[2] = {0x00};
uint8_t sak;
bool isTag;
uint8_t buf[3000] = {0x00};
uint8_t * bufPtr = buf;
uint8_t *buf = NULL;
uint16_t bufsize = 0;
uint8_t *bufPtr = NULL;
char ctmp = param_getchar(Cmd, 0);
if ( ctmp == 'h' || ctmp == 'H' ) {
@ -1816,32 +1817,47 @@ int CmdHF14AMfSniff(const char *Cmd){
break;
}
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) {
UsbCommand resp;
if (WaitForResponseTimeout(CMD_ACK,&resp,2000)) {
res = resp.arg[0] & 0xff;
len = resp.arg[1];
num = resp.arg[2];
if (res == 0) return 0;
if (res == 1) {
if (num ==0) {
uint16_t traceLen = resp.arg[1];
len = resp.arg[2];
if (res == 0) return 0; // we are done
if (res == 1) { // there is (more) data to be transferred
if (pckNum == 0) { // first packet, (re)allocate necessary buffer
if (traceLen > bufsize) {
uint8_t *p;
if (buf == NULL) { // not yet allocated
p = malloc(traceLen);
} else { // need more memory
p = realloc(buf, traceLen);
}
if (p == NULL) {
PrintAndLog("Cannot allocate memory for trace");
free(buf);
return 2;
}
buf = p;
}
bufPtr = buf;
memset(buf, 0x00, 3000);
bufsize = traceLen;
memset(buf, 0x00, traceLen);
}
memcpy(bufPtr, resp.d.asBytes, len);
bufPtr += len;
pckNum++;
}
if (res == 2) {
if (res == 2) { // received all data, start displaying
blockLen = bufPtr - buf;
bufPtr = buf;
printf(">\n");
PrintAndLog("received trace len: %d packages: %d", blockLen, pckNum);
num = 0;
while (bufPtr - buf < blockLen) {
bufPtr += 6;
bufPtr += 6; // skip (void) timing information
len = *((uint16_t *)bufPtr);
if(len & 0x8000) {
isTag = true;
len &= 0x7fff;
@ -1850,12 +1866,10 @@ int CmdHF14AMfSniff(const char *Cmd){
}
bufPtr += 2;
if ((len == 14) && (bufPtr[0] == 0xff) && (bufPtr[1] == 0xff) && (bufPtr[12] == 0xff) && (bufPtr[13] == 0xff)) {
memcpy(uid, bufPtr + 2, 7);
memcpy(atqa, bufPtr + 2 + 7, 2);
uid_len = (atqa[0] & 0xC0) == 0x40 ? 7 : 4;
sak = bufPtr[11];
PrintAndLog("tag select uid:%s atqa:0x%02x%02x sak:0x%02x",
sprint_hex(uid + (7 - uid_len), uid_len),
atqa[1],
@ -1873,18 +1887,21 @@ int CmdHF14AMfSniff(const char *Cmd){
AddLogHex(logHexFileName, isTag ? "TAG: ":"RDR: ", bufPtr, len);
if (wantDecrypt)
mfTraceDecode(bufPtr, len, wantSaveToEmlFile);
num++;
}
bufPtr += len;
bufPtr += ((len-1)/8+1); // ignore parity
num++;
}
pckNum = 0;
}
} // resp not NULL
} // while (true)
free(buf);
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},

View file

@ -29,110 +29,125 @@ size_t nbytes(size_t nbits) {
int CmdLFHitagList(const char *Cmd)
{
uint8_t got[TRACE_BUFFER_SIZE];
GetFromBigBuf(got,sizeof(got),0);
WaitForResponse(CMD_ACK,NULL);
uint8_t *got = malloc(USB_CMD_DATA_SIZE);
PrintAndLog("recorded activity:");
PrintAndLog(" ETU :nbits: who bytes");
PrintAndLog("---------+-----+----+-----------");
int i = 0;
int prev = -1;
int len = strlen(Cmd);
char filename[FILE_PATH_SIZE] = { 0x00 };
FILE* pf = NULL;
if (len > FILE_PATH_SIZE)
len = FILE_PATH_SIZE;
memcpy(filename, Cmd, len);
if (strlen(filename) > 0) {
if ((pf = fopen(filename,"wb")) == NULL) {
PrintAndLog("Error: Could not open file [%s]",filename);
return 1;
// Query for the actual size of the trace
UsbCommand response;
GetFromBigBuf(got, USB_CMD_DATA_SIZE, 0);
WaitForResponse(CMD_ACK, &response);
uint16_t traceLen = response.arg[2];
if (traceLen > USB_CMD_DATA_SIZE) {
uint8_t *p = realloc(got, traceLen);
if (p == NULL) {
PrintAndLog("Cannot allocate memory for trace");
free(got);
return 2;
}
got = p;
GetFromBigBuf(got, traceLen, 0);
WaitForResponse(CMD_ACK,NULL);
}
}
for (;;) {
if(i >= TRACE_BUFFER_SIZE) { break; }
bool isResponse;
int timestamp = *((uint32_t *)(got+i));
if (timestamp & 0x80000000) {
timestamp &= 0x7fffffff;
isResponse = 1;
} else {
isResponse = 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 bits = got[i+8];
int len = nbytes(got[i+8]);
if (len > 100) {
break;
}
if (i + len >= TRACE_BUFFER_SIZE) { break;}
uint8_t *frame = (got+i+9);
// Break and stick with current result if buffer was not completely full
if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
char line[1000] = "";
int j;
for (j = 0; j < len; j++) {
int oddparity = 0x01;
int k;
for (k=0;k<8;k++) {
oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
}
//if((parityBits >> (len - j - 1)) & 0x01) {
if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
sprintf(line+(j*4), "%02x! ", frame[j]);
}
else {
sprintf(line+(j*4), "%02x ", frame[j]);
}
}
PrintAndLog(" +%7d: %3d: %s %s",
(prev < 0 ? 0 : (timestamp - prev)),
bits,
(isResponse ? "TAG" : " "),
line);
if (pf) {
fprintf(pf," +%7d: %3d: %s %s\n",
(prev < 0 ? 0 : (timestamp - prev)),
bits,
(isResponse ? "TAG" : " "),
line);
}
prev = timestamp;
i += (len + 9);
}
if (pf) {
fclose(pf);
PrintAndLog("Recorded activity succesfully written to file: %s", filename);
}
PrintAndLog("recorded activity (TraceLen = %d bytes):");
PrintAndLog(" ETU :nbits: who bytes");
PrintAndLog("---------+-----+----+-----------");
return 0;
int i = 0;
int prev = -1;
int len = strlen(Cmd);
char filename[FILE_PATH_SIZE] = { 0x00 };
FILE* pf = NULL;
if (len > FILE_PATH_SIZE)
len = FILE_PATH_SIZE;
memcpy(filename, Cmd, len);
if (strlen(filename) > 0) {
if ((pf = fopen(filename,"wb")) == NULL) {
PrintAndLog("Error: Could not open file [%s]",filename);
return 1;
}
}
for (;;) {
if(i > traceLen) { break; }
bool isResponse;
int timestamp = *((uint32_t *)(got+i));
if (timestamp & 0x80000000) {
timestamp &= 0x7fffffff;
isResponse = 1;
} else {
isResponse = 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 bits = got[i+8];
int len = nbytes(got[i+8]);
if (len > 100) {
break;
}
if (i + len > traceLen) { break;}
uint8_t *frame = (got+i+9);
// Break and stick with current result if buffer was not completely full
if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
char line[1000] = "";
int j;
for (j = 0; j < len; j++) {
int oddparity = 0x01;
int k;
for (k=0;k<8;k++) {
oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
}
//if((parityBits >> (len - j - 1)) & 0x01) {
if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
sprintf(line+(j*4), "%02x! ", frame[j]);
}
else {
sprintf(line+(j*4), "%02x ", frame[j]);
}
}
PrintAndLog(" +%7d: %3d: %s %s",
(prev < 0 ? 0 : (timestamp - prev)),
bits,
(isResponse ? "TAG" : " "),
line);
if (pf) {
fprintf(pf," +%7d: %3d: %s %s\n",
(prev < 0 ? 0 : (timestamp - prev)),
bits,
(isResponse ? "TAG" : " "),
line);
}
prev = timestamp;
i += (len + 9);
}
if (pf) {
fclose(pf);
PrintAndLog("Recorded activity succesfully written to file: %s", filename);
}
free(got);
return 0;
}
int CmdLFHitagSnoop(const char *Cmd) {

View file

@ -188,7 +188,6 @@ void UsbCommandReceived(UsbCommand *UC)
} break;
case CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K: {
sample_buf_len += UC->arg[1];
memcpy(sample_buf+(UC->arg[0]),UC->d.asBytes,UC->arg[1]);
} break;

View file

@ -16,11 +16,9 @@
#include "cmdmain.h"
uint8_t* sample_buf;
size_t sample_buf_len;
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index)
{
sample_buf_len = 0;
sample_buf = dest;
UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {start_index, bytes, 0}};
SendCommand(&c);

View file

@ -13,13 +13,9 @@
#include <stdint.h>
//trace buffer size as defined in armsrc/apps.h TRACE_SIZE
#define TRACE_BUFFER_SIZE 4096
#define FILE_PATH_SIZE 1000
#define SAMPLE_BUFFER_SIZE 64
extern uint8_t* sample_buf;
extern size_t sample_buf_len;
#define arraylen(x) (sizeof(x)/sizeof((x)[0]))
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index);