// High frequency Legic commands
//-----------------------------------------------------------------------------
+#include "cmdhflegic.h"
+
#include <stdio.h>
#include <string.h>
-#include "proxusb.h"
-#include "proxmark3.h"
-#include "data.h"
+#include <inttypes.h>
+#include "comms.h"
#include "ui.h"
#include "cmdparser.h"
-#include "cmdhflegic.h"
#include "cmdmain.h"
+#include "util.h"
static int CmdHelp(const char *Cmd);
{"reader", CmdLegicRFRead, 0, "[offset [length]] -- read bytes from a LEGIC card"},
{"save", CmdLegicSave, 0, "<filename> [<length>] -- Store samples"},
{"load", CmdLegicLoad, 0, "<filename> -- Restore samples"},
- {"sim", CmdLegicRfSim, 0, "[phase drift [frame drift [req/resp drift]]] Start tag simulator (use after load or read)"},
+ {"sim", CmdLegicRfSim, 0, "[tagtype, 0:MIM22, 1:MIM256, 2:MIM1024] Start tag simulator (use after load or read)"},
{"write", CmdLegicRfWrite,0, "<offset> <length> -- Write sample buffer (user after load or read)"},
{"fill", CmdLegicRfFill, 0, "<offset> <length> <value> -- Fill/Write tag with constant value"},
{NULL, NULL, 0, NULL}
*/
int CmdLegicDecode(const char *Cmd)
{
- int h, i, j, k, n;
+ int i, j, k, n;
int segment_len = 0;
int segment_flag = 0;
int stamp_len = 0;
int crc = 0;
int wrp = 0;
int wrc = 0;
- int data_buf[1032]; // receiver buffer
+ uint8_t data_buf[1053]; // receiver buffer
char out_string[3076]; // just use big buffer - bad practice
char token_type[4];
- int delivered = 0;
-
- h = 0;
// copy data from proxmark into buffer
- for (i = 0; i < 256; i += 12, h += 48) {
- UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
- SendCommand(&c);
- WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, NULL);
-
- for (j = 0; j < 48; j += 8) {
- for (k = 0; k < 8; k++) {
- data_buf[h+j+k] = sample_buf[j+k];
- }
- delivered += 8;
- if (delivered >= 1024)
- break;
- }
- }
+ GetFromBigBuf(data_buf, sizeof(data_buf), 0, NULL, -1, false);
// Output CDF System area (9 bytes) plus remaining header area (12 bytes)
int CmdLegicLoad(const char *Cmd)
{
- FILE *f = fopen(Cmd, "r");
+ char filename[FILE_PATH_SIZE] = {0x00};
+ int len = 0;
+
+ if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {
+ PrintAndLog("It loads datasamples from the file `filename`");
+ PrintAndLog("Usage: hf legic load <file name>");
+ PrintAndLog(" sample: hf legic load filename");
+ return 0;
+ }
+
+ len = strlen(Cmd);
+ if (len > FILE_PATH_SIZE) {
+ PrintAndLog("Filepath too long (was %s bytes), max allowed is %s ", len, FILE_PATH_SIZE);
+ return 0;
+ }
+ memcpy(filename, Cmd, len);
+
+ FILE *f = fopen(filename, "r");
if(!f) {
PrintAndLog("couldn't open '%s'", Cmd);
return -1;
fclose(f);
return -1;
}
- UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {offset, 0, 0}};
+ UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {offset, 1, 0}};
int j; for(j = 0; j < 8; j++) {
c.d.asBytes[j] = data[j];
}
int CmdLegicSave(const char *Cmd)
{
- int n;
int requested = 1024;
int offset = 0;
- char filename[1024];
- sscanf(Cmd, " %s %i %i", filename, &requested, &offset);
- if (offset % 4 != 0) {
- PrintAndLog("Offset must be a multiple of 4");
- return 0;
- }
- offset = offset/4;
-
int delivered = 0;
+ char filename[FILE_PATH_SIZE];
+ uint8_t got[1024];
+
+ sscanf(Cmd, " %s %i %i", filename, &requested, &offset);
+ /* If no length given save entire legic read buffer */
+ /* round up to nearest 8 bytes so the saved data can be used with legicload */
if (requested == 0) {
- n = 12;
- requested = 12;
- } else {
- n = requested/4;
+ requested = 1024;
}
-
+ if (requested % 8 != 0) {
+ int remainder = requested % 8;
+ requested = requested + 8 - remainder;
+ }
+ if (offset + requested > sizeof(got)) {
+ PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > 1024");
+ return 0;
+ }
+
FILE *f = fopen(filename, "w");
if(!f) {
PrintAndLog("couldn't open '%s'", Cmd+1);
return -1;
}
- for (int i = offset; i < n+offset; i += 12) {
- UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
- SendCommand(&c);
- WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, NULL);
- for (int j = 0; j < 48; j += 8) {
- fprintf(f, "%02x %02x %02x %02x %02x %02x %02x %02x\n",
- sample_buf[j+0],
- sample_buf[j+1],
- sample_buf[j+2],
- sample_buf[j+3],
- sample_buf[j+4],
- sample_buf[j+5],
- sample_buf[j+6],
- sample_buf[j+7]
- );
- delivered += 8;
- if (delivered >= requested)
- break;
- }
+ GetFromBigBuf(got, requested, offset, NULL, -1, false);
+
+ for (int j = 0; j < requested; j += 8) {
+ fprintf(f, "%02x %02x %02x %02x %02x %02x %02x %02x\n",
+ got[j+0],
+ got[j+1],
+ got[j+2],
+ got[j+3],
+ got[j+4],
+ got[j+5],
+ got[j+6],
+ got[j+7]
+ );
+ delivered += 8;
if (delivered >= requested)
break;
}
int CmdLegicRfSim(const char *Cmd)
{
UsbCommand c={CMD_SIMULATE_TAG_LEGIC_RF};
- c.arg[0] = 6;
- c.arg[1] = 3;
- c.arg[2] = 0;
- sscanf(Cmd, " %i %i %i", &c.arg[0], &c.arg[1], &c.arg[2]);
+ c.arg[0] = 1;
+ sscanf(Cmd, " %" SCNi64, &c.arg[0]);
SendCommand(&c);
return 0;
}
int CmdLegicRfWrite(const char *Cmd)
{
UsbCommand c={CMD_WRITER_LEGIC_RF};
- int res = sscanf(Cmd, " 0x%x 0x%x", &c.arg[0], &c.arg[1]);
+ int res = sscanf(Cmd, " 0x%" SCNx64 " 0x%" SCNx64, &c.arg[0], &c.arg[1]);
if(res != 2) {
PrintAndLog("Please specify the offset and length as two hex strings");
return -1;
int CmdLegicRfFill(const char *Cmd)
{
UsbCommand cmd ={CMD_WRITER_LEGIC_RF};
- int res = sscanf(Cmd, " 0x%x 0x%x 0x%x", &cmd.arg[0], &cmd.arg[1], &cmd.arg[2]);
+ int res = sscanf(Cmd, " 0x%" SCNx64 " 0x%" SCNx64 " 0x%" SCNx64, &cmd.arg[0], &cmd.arg[1], &cmd.arg[2]);
if(res != 3) {
PrintAndLog("Please specify the offset, length and value as two hex strings");
return -1;
}
int i;
- UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {0, 0, 0}};
+ UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {0, 1, 0}};
for(i = 0; i < 48; i++) {
c.d.asBytes[i] = cmd.arg[2];
}