+//-----------------------------------------------------------------------------
+// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
+//
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// Data and Graph commands
+//-----------------------------------------------------------------------------
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
-#include "proxusb.h"
+#include "proxmark3.h"
#include "data.h"
#include "ui.h"
#include "graph.h"
#include "cmdparser.h"
+#include "util.h"
#include "cmdmain.h"
#include "cmddata.h"
+
static int CmdHelp(const char *Cmd);
int CmdAmp(const char *Cmd)
int i;
int c, high = 0, low = 0;
- // TODO: complain if we do not give 2 arguments here !
- // (AL - this doesn't make sense! we're only using one argument!!!)
sscanf(Cmd, "%i", &c);
- /* Detect high and lows and clock */
- // (AL - clock???)
+ if (c != 0 && c != 1) {
+ PrintAndLog("Invalid argument: %s", Cmd);
+ return 0;
+ }
+
+ /* Detect high and lows */
for (i = 0; i < GraphTraceLen; ++i)
{
if (GraphBuffer[i] > high)
else if (GraphBuffer[i] < low)
low = GraphBuffer[i];
}
- if (c != 0 && c != 1) {
- PrintAndLog("Invalid argument: %s", Cmd);
- return 0;
- }
-
+
if (GraphBuffer[0] > 0) {
GraphBuffer[0] = 1-c;
} else {
int CmdBitsamples(const char *Cmd)
{
int cnt = 0;
- int n = 3072;
-
- for (int i = 0; i < n; i += 12) {
- UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
- SendCommand(&c);
- WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
+ uint8_t got[12288];
+
+ GetFromBigBuf(got,sizeof(got),0);
+ WaitForResponse(CMD_ACK,NULL);
- for (int j = 0; j < 48; j++) {
+ for (int j = 0; j < sizeof(got); j++) {
for (int k = 0; k < 8; k++) {
- if(sample_buf[j] & (1 << (7 - k))) {
+ if(got[j] & (1 << (7 - k))) {
GraphBuffer[cnt++] = 1;
} else {
GraphBuffer[cnt++] = 0;
}
}
- }
}
GraphTraceLen = cnt;
RepaintGraphWindow();
int CmdGrid(const char *Cmd)
{
sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY);
+ PlotGridXdefault= PlotGridX;
+ PlotGridYdefault= PlotGridY;
RepaintGraphWindow();
return 0;
}
int CmdHexsamples(const char *Cmd)
{
- int n;
+ int i, j;
int requested = 0;
int offset = 0;
+ char string_buf[25];
+ char* string_ptr = string_buf;
+ uint8_t got[40000];
+
sscanf(Cmd, "%i %i", &requested, &offset);
- if (offset % 4 != 0) {
- PrintAndLog("Offset must be a multiple of 4");
- return 0;
- }
- offset = offset/4;
-
- int delivered = 0;
+ /* if no args send something */
if (requested == 0) {
- n = 12;
- requested = 12;
- } else {
- n = requested/4;
- }
-
- 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);
- for (int j = 0; j < 48; j += 8) {
- PrintAndLog("%02x %02x %02x %02x %02x %02x %02x %02x",
- 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],
- sample_buf[j+8]
- );
- delivered += 8;
- if (delivered >= requested)
- break;
+ requested = 8;
+ }
+ if (offset + requested > sizeof(got)) {
+ PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > 40000");
+ return 0;
+ }
+
+ GetFromBigBuf(got,requested,offset);
+ WaitForResponse(CMD_ACK,NULL);
+
+ i = 0;
+ for (j = 0; j < requested; j++) {
+ i++;
+ string_ptr += sprintf(string_ptr, "%02x ", got[j]);
+ if (i == 8) {
+ *(string_ptr - 1) = '\0'; // remove the trailing space
+ PrintAndLog("%s", string_buf);
+ string_buf[0] = '\0';
+ string_ptr = string_buf;
+ i = 0;
}
- if (delivered >= requested)
- break;
+ if (j == requested - 1 && string_buf[0] != '\0') { // print any remaining bytes
+ *(string_ptr - 1) = '\0';
+ PrintAndLog("%s", string_buf);
+ string_buf[0] = '\0';
+ }
}
return 0;
}
int CmdSamples(const char *Cmd)
{
- int cnt = 0;
- int n;
-
- n = strtol(Cmd, NULL, 0);
- if (n == 0) n = 128;
- if (n > 16000) n = 16000;
-
- PrintAndLog("Reading %d samples\n", n);
- for (int i = 0; i < n; i += 12) {
- UsbCommand c = {CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K, {i, 0, 0}};
- SendCommand(&c);
- WaitForResponse(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K);
- for (int j = 0; j < 48; j++) {
- GraphBuffer[cnt++] = ((int)sample_buf[j]) - 128;
- }
- }
- PrintAndLog("Done!\n");
- GraphTraceLen = n*4;
- RepaintGraphWindow();
- return 0;
+ uint8_t got[36440] = {0x00};
+
+ int n = strtol(Cmd, NULL, 0);
+ if (n == 0)
+ n = 512;
+ if (n > sizeof(got))
+ n = sizeof(got);
+
+ PrintAndLog("Reading %d samples from device memory\n", n);
+ GetFromBigBuf(got,n,3560);
+ WaitForResponse(CMD_ACK,NULL);
+ for (int j = 0; j < n; ++j) {
+ GraphBuffer[j] = ((int)got[j]) - 128;
+ }
+ GraphTraceLen = n;
+ RepaintGraphWindow();
+ return 0;
}
int CmdLoad(const char *Cmd)
{
- FILE *f = fopen(Cmd + 1, "r");
+ FILE *f = fopen(Cmd, "r");
if (!f) {
- PrintAndLog("couldn't open '%s'", Cmd + 1);
+ PrintAndLog("couldn't open '%s'", Cmd);
return 0;
}
int i, j, invert= 0;
int bit;
int clock;
- int lastval;
+ int lastval = 0;
int low = 0;
int high = 0;
int hithigh, hitlow, first;
int warnings = 0;
/* check if we're inverting output */
- if (*(Cmd + 1) == 'i')
+ if (*Cmd == 'i')
{
PrintAndLog("Inverting output");
invert = 1;
/* But it does not work if compiling on WIndows: therefore we just allocate a */
/* large array */
- int BitStream[MAX_GRAPH_TRACE_LEN];
+ uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0x00};
/* Detect high and lows */
for (i = 0; i < GraphTraceLen; i++)
}
/* Get our clock */
- clock = GetClock(Cmd, high, 1);
-
+ clock = GetClock(Cmd, high, 1);
int tolerance = clock/4;
/* Detect first transition */
break;
}
}
-
+
/* If we're not working with 1/0s, demod based off clock */
if (high != 1)
{
+ PrintAndLog("Entering path A");
bit = 0; /* We assume the 1st bit is zero, it may not be
* the case: this routine (I think) has an init problem.
* Ed.
- */
+ */
for (; i < (int)(GraphTraceLen / clock); i++)
{
hithigh = 0;
// At this stage, we now have a bitstream of "01" ("1") or "10" ("0"), parse it into final decoded bitstream
// Actually, we overwrite BitStream with the new decoded bitstream, we just need to be careful
// to stop output at the final bitidx2 value, not bitidx
- for (i = 0; i < bitidx; i += 2) {
+
+ //http://www.proxmark.org/forum/viewtopic.php?id=403
+ for (i = 1; i < bitidx; i += 2) {
if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) {
BitStream[bit2idx++] = 1 ^ invert;
} else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) {
// We cannot end up in this state, this means we are unsynchronized,
// move up 1 bit:
i++;
- warnings++;
+ warnings++;
PrintAndLog("Unsynchronized, resync...");
PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)");
BitStream[i+14],
BitStream[i+15]);
}
- return 0;
+ return bit2idx;
}
/* Modulate our data into manchester */
int CmdManchesterMod(const char *Cmd)
{
int i, j;
- int clock;
int bit, lastbit, wave;
-
- /* Get our clock */
- clock = GetClock(Cmd, 0, 1);
-
+ int clock = GetClock(Cmd, 0, 1);
+ int clock1 = GetT55x7Clock( GraphBuffer, GraphTraceLen, 0 );
+ PrintAndLog("MAN MOD CLOCKS: %d ice %d", clock,clock1);
+
+ int half = (int)(clock/2);
+
wave = 0;
lastbit = 1;
for (i = 0; i < (int)(GraphTraceLen / clock); i++)
{
bit = GraphBuffer[i * clock] ^ 1;
- for (j = 0; j < (int)(clock/2); j++)
+ for (j = 0; j < half; ++j)
GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave;
- for (j = (int)(clock/2); j < clock; j++)
+ for (j = half; j < clock; ++j)
GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave ^ 1;
/* Keep track of how we start our wave and if we changed or not this time */
if (GraphBuffer[i] >= threshold)
GraphBuffer[i] = 1;
else
- GraphBuffer[i] =- 1;
+ GraphBuffer[i] = -1;
+ }
+ RepaintGraphWindow();
+ return 0;
+}
+
+int CmdDirectionalThreshold(const char *Cmd)
+{
+ int8_t upThres = param_get8(Cmd, 0);
+ int8_t downThres = param_get8(Cmd, 1);
+
+ printf("Applying Up Threshold: %d, Down Threshold: %d\n", upThres, downThres);
+
+ int lastValue = GraphBuffer[0];
+ GraphBuffer[0] = 0; // Will be changed at the end, but init 0 as we adjust to last samples value if no threshold kicks in.
+
+ for (int i = 1; i < GraphTraceLen; ++i) {
+ // Apply first threshold to samples heading up
+ if (GraphBuffer[i] >= upThres && GraphBuffer[i] > lastValue)
+ {
+ lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
+ GraphBuffer[i] = 1;
+ }
+ // Apply second threshold to samples heading down
+ else if (GraphBuffer[i] <= downThres && GraphBuffer[i] < lastValue)
+ {
+ lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
+ GraphBuffer[i] = -1;
+ }
+ else
+ {
+ lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
+ GraphBuffer[i] = GraphBuffer[i-1];
+
+ }
}
+ GraphBuffer[0] = GraphBuffer[1]; // Aline with first edited sample.
RepaintGraphWindow();
return 0;
}
{"detectclock", CmdDetectClockRate, 1, "Detect clock rate"},
{"fskdemod", CmdFSKdemod, 1, "Demodulate graph window as a HID FSK"},
{"grid", CmdGrid, 1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
- {"hexsamples", CmdHexsamples, 0, "<blocks> [<offset>] -- Dump big buffer as hex bytes"},
+ {"hexsamples", CmdHexsamples, 0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
{"hide", CmdHide, 1, "Hide graph window"},
{"hpf", CmdHpf, 1, "Remove DC offset from trace"},
{"load", CmdLoad, 1, "<filename> -- Load trace (to graph window"},
{"mandemod", CmdManchesterDemod, 1, "[i] [clock rate] -- Manchester demodulate binary stream (option 'i' to invert output)"},
{"manmod", CmdManchesterMod, 1, "[clock rate] -- Manchester modulate a binary stream"},
{"norm", CmdNorm, 1, "Normalize max/min to +/-500"},
- {"plot", CmdPlot, 1, "Show graph window"},
- {"samples", CmdSamples, 0, "[128 - 16000] -- Get raw samples for graph window"},
+ {"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"},
+ {"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window"},
{"save", CmdSave, 1, "<filename> -- Save trace (from graph window)"},
{"scale", CmdScale, 1, "<int> -- Set cursor display scale"},
{"threshold", CmdThreshold, 1, "<threshold> -- Maximize/minimize every value in the graph window depending on threshold"},
{"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"},
+ {"dirthreshold", CmdDirectionalThreshold, 1, "<thres up> <thres down> -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."},
{NULL, NULL, 0, NULL}
};