Client cleanup and restructuring. Stage 1...

Next Step is refactoring some of the giant functions which are
just copy/paste of some other ones with just a few line changes,
removing unnecessary 'goto' etc.

The MS Windows version is broken with this commit but will be fixed
soon. Everything can't be done all at once :P

The commands are now hierarchical, for example:
"hf 14a read" vs. "hf 14b read".
You can also request help:
"hf help", "data help", "hf 15 help" etc.

Indents are now space-based, not tab-based anymore. Hopefully
no one will be trolling about it, considering the suicide-prone work
being done here ;)

client/cmdhw.c, client/proxusb.c, client/cmdhw.h, client/proxusb.h,
client/cmdmain.c, client/cmdlfhid.c, client/cmdmain.h, client/cmdlfhid.h,
client/data.c, client/data.h, client/cmdhf.c, client/cmdlf.c,
client/cmdhf.h, client/cmdhf15.c, client/cmdhf14b.c, client/cmdlf.h,
client/cmdhf15.h, client/cmdhf14b.h, client/cmddata.c, client/cmddata.h,
client/ui.c, client/cmdparser.c, client/cmdlfti.c, client/ui.h,
client/cmdlfem4x.c, client/cmdparser.h, client/cmdlfti.h, client/cmdlfem4x.h,
client/graph.c, client/graph.h, client/cmdhf14a.c, client/cmdhf14a.h,
client/cmdhflegic.c, client/cmdhflegic.c: New files.

client/cli.c, client/flasher.c, client/snooper.c, client/proxmark3.c,
client/proxmark3.h, client/Makefile: Update accordingly.

client/flash.h, client/flash.c, client/proxgui.cpp: Cosmetic changes.

client/translate.h, client/command.c, client/gui.c,
client/usb.c, client/prox.h: Remove.

include/usb_cmd.h (CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM): Remove dead cmd.

common/crc16.h: New file.
common/crc16.c: Modify accordingly.
common/iso14443crc.h: New file.
common/iso14443_crc.c: Rename to
common/iso14443crc.c: and modify accordingly.

armsrc/lfops.c, armsrc/iso14443.c,
armsrc/iso14443a.c: include .h files from
the common directory instead of including the c files.

common/Makefile.common, armsrc/Makefile: Modify accordingly.
This commit is contained in:
izsh.f0f 2010-02-04 01:27:07 +00:00
parent 6982ac2612
commit 7fe9b0b742
59 changed files with 4306 additions and 3968 deletions

View file

@ -24,6 +24,8 @@ THUMBSRC = start.c \
# These are to be compiled in ARM mode # These are to be compiled in ARM mode
ARMSRC = fpgaloader.c \ ARMSRC = fpgaloader.c \
legicrf.c \ legicrf.c \
iso14443crc.c \
crc16.c \
$(SRC_ISO14443a) \ $(SRC_ISO14443a) \
$(SRC_ISO14443b) \ $(SRC_ISO14443b) \
crc.c crc.c

View file

@ -6,7 +6,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include <proxmark3.h> #include <proxmark3.h>
#include "apps.h" #include "apps.h"
#include "../common/iso14443_crc.c" #include "iso14443crc.h"
//static void GetSamplesFor14443(BOOL weTx, int n); //static void GetSamplesFor14443(BOOL weTx, int n);

View file

@ -5,7 +5,7 @@
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#include <proxmark3.h> #include <proxmark3.h>
#include "apps.h" #include "apps.h"
#include "../common/iso14443_crc.c" #include "iso14443crc.h"
static BYTE *trace = (BYTE *) BigBuf; static BYTE *trace = (BYTE *) BigBuf;
static int traceLen = 0; static int traceLen = 0;

View file

@ -7,7 +7,7 @@
#include <proxmark3.h> #include <proxmark3.h>
#include "apps.h" #include "apps.h"
#include "hitag2.h" #include "hitag2.h"
#include "../common/crc16.c" #include "crc16.h"
void AcquireRawAdcSamples125k(BOOL at134khz) void AcquireRawAdcSamples125k(BOOL at134khz)
{ {

View file

@ -1,15 +1,38 @@
WINCC=c:\mingw\bin\gcc WINCC=c:\mingw\bin\gcc
#COMMON_FLAGS = -m32 #COMMON_FLAGS = -m32
VPATH = ../common
LDLIBS = -L/opt/local/lib -L/usr/local/lib -lusb -lreadline -lpthread LDLIBS = -L/opt/local/lib -L/usr/local/lib -lusb -lreadline -lpthread
LDFLAGS = $(COMMON_FLAGS) LDFLAGS = $(COMMON_FLAGS)
CFLAGS = -I. -I/opt/local/include -Wall -Wno-unused-function $(COMMON_FLAGS) -g3 CFLAGS = -std=c99 -I. -I../include -I../common -I/opt/local/include -Wall -Wno-unused-function $(COMMON_FLAGS) -g3
WINLIBS = -lgdi32 -lsetupapi WINLIBS = -lgdi32 -lsetupapi
CXXFLAGS = $(shell pkg-config --cflags QtCore QtGui 2>/dev/null) -Wall CXXFLAGS = $(shell pkg-config --cflags QtCore QtGui 2>/dev/null) -Wall
QTLDLIBS = $(shell pkg-config --libs QtCore QtGui 2>/dev/null) QTLDLIBS = $(shell pkg-config --libs QtCore QtGui 2>/dev/null)
CMDSRCS = \
crc16.c \
iso14443crc.c \
data.c \
graph.c \
ui.c \
cmddata.c \
cmdhf.c \
cmdhf14a.c \
cmdhf14b.c \
cmdhf15.c \
cmdhflegic.c \
cmdhw.c \
cmdlf.c \
cmdlfem4x.c \
cmdlfhid.c \
cmdlfti.c \
cmdparser.c \
cmdmain.c
CMDOBJS = $(CMDSRCS:.c=.o)
ifeq ($(shell echo ""),) ifeq ($(shell echo ""),)
ifeq ($(shell uname),Darwin) ifeq ($(shell uname),Darwin)
@ -29,7 +52,7 @@ endif
RM = rm -f RM = rm -f
BINS = proxmark3 snooper cli flasher BINS = proxmark3 snooper cli flasher
CLEAN = cli flasher proxmark3 snooper *.o *.moc.cpp CLEAN = cli flasher proxmark3 snooper *.o $(CMDOBJS) *.moc.cpp
else else
RM = del RM = del
BINS = prox.exe BINS = prox.exe
@ -41,19 +64,17 @@ all: $(BINS)
all-static: LDLIBS:=-static $(LDLIBS) all-static: LDLIBS:=-static $(LDLIBS)
all-static: snooper cli flasher all-static: snooper cli flasher
prox.exe: prox.c wingui.c command.c flash.c prox.exe: prox.c wingui.c $(CMDSRCS) flash.c
$(WINCC) $(CFLAGS) $(DEFINES) -o prox.exe prox.c wingui.c command.c flash.c $(WINLIBS) $(WINCC) $(CFLAGS) $(DEFINES) -o prox.exe prox.c wingui.c $(CMDSRCS) flash.c $(WINLIBS)
proxmark3: LDLIBS+=$(QTLDLIBS) proxmark3: LDLIBS+=$(QTLDLIBS)
proxmark3: proxmark3.o gui.o command.o usb.o $(QTGUI) proxmark3: proxmark3.o $(CMDOBJS) proxusb.o $(QTGUI)
command.o: command.c snooper: snooper.o $(CMDOBJS) proxusb.o guidummy.o
snooper: snooper.o gui.o command.o usb.o guidummy.o cli: cli.o $(CMDOBJS) proxusb.o guidummy.o
cli: cli.o gui.o command.o usb.o guidummy.o flasher: flash.o flasher.o proxusb.o
flasher: flash.o flasher.o usb.o
proxguiqt.moc.cpp: proxguiqt.h proxguiqt.moc.cpp: proxguiqt.h
$(MOC) -o$@ $^ $(MOC) -o$@ $^

View file

@ -1,60 +1,49 @@
#include <usb.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include "ui.h"
#include <stdlib.h> #include "proxusb.h"
#include <strings.h> #include "cmdmain.h"
#include <string.h>
#include <errno.h>
#include "prox.h"
#include "proxmark3.h"
#define HANDLE_ERROR if (error_occured) { \ #define HANDLE_ERROR if (error_occured) { \
error_occured = 0;\ error_occured = 0;\
break;\ break;\
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
if(argc != 3 && argc != 4) if (argc != 3 && argc != 4)
{ {
printf("\n\tusage: cli <command 1> <command 2> [logfile (default cli.log)]\n"); printf("\n\tusage: cli <command 1> <command 2> [logfile (default cli.log)]\n");
printf("\n"); printf("\n");
printf("\texample: cli hi14asnoop hi14alist h14a.log\n"); printf("\texample: cli hi14asnoop hi14alist h14a.log\n");
printf("\n"); printf("\n");
return -1; return -1;
} }
usb_init(); usb_init();
if (argc == 4) if (argc == 4)
setlogfilename(argv[3]); SetLogFilename(argv[3]);
else else
setlogfilename("cli.log"); SetLogFilename("cli.log");
return_on_error = 1; return_on_error = 1;
while(1) { while (1) {
while(!(devh=OpenProxmark(0))) { sleep(1); } while (!OpenProxmark(0)) { sleep(1); }
while (1) {
UsbCommand cmdbuf;
CommandReceived(argv[1]);
HANDLE_ERROR;
ReceiveCommand(&cmdbuf);
HANDLE_ERROR;
for (int i = 0; i < 5; ++i) {
ReceiveCommandPoll(&cmdbuf);
}
HANDLE_ERROR;
CommandReceived(argv[2]);
HANDLE_ERROR;
}
}
while(1) { CloseProxmark();
UsbCommand cmdbuf; return 0;
int i;
CommandReceived(argv[1]);
HANDLE_ERROR
ReceiveCommand(&cmdbuf);
HANDLE_ERROR
for (i=0; i<5; i++) {
ReceiveCommandPoll(&cmdbuf);
}
HANDLE_ERROR
CommandReceived(argv[2]);
HANDLE_ERROR
}
}
CloseProxmark();
return 0;
} }

910
client/cmddata.c Normal file
View file

@ -0,0 +1,910 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "proxusb.h"
#include "data.h"
#include "ui.h"
#include "graph.h"
#include "cmdparser.h"
#include "cmdmain.h"
#include "cmddata.h"
static int CmdHelp(const char *Cmd);
int CmdAmp(const char *Cmd)
{
int i, rising, falling;
int max = INT_MIN, min = INT_MAX;
for (i = 10; i < GraphTraceLen; ++i) {
if (GraphBuffer[i] > max)
max = GraphBuffer[i];
if (GraphBuffer[i] < min)
min = GraphBuffer[i];
}
if (max != min) {
rising = falling= 0;
for (i = 0; i < GraphTraceLen; ++i) {
if (GraphBuffer[i + 1] < GraphBuffer[i]) {
if (rising) {
GraphBuffer[i] = max;
rising = 0;
}
falling = 1;
}
if (GraphBuffer[i + 1] > GraphBuffer[i]) {
if (falling) {
GraphBuffer[i] = min;
falling = 0;
}
rising= 1;
}
}
}
RepaintGraphWindow();
return 0;
}
/*
* Generic command to demodulate ASK.
*
* Argument is convention: positive or negative (High mod means zero
* or high mod means one)
*
* Updates the Graph trace with 0/1 values
*
* Arguments:
* c : 0 or 1
*/
int Cmdaskdemod(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???)
for (i = 0; i < GraphTraceLen; ++i)
{
if (GraphBuffer[i] > high)
high = GraphBuffer[i];
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 {
GraphBuffer[0] = c;
}
for (i = 1; i < GraphTraceLen; ++i) {
/* Transitions are detected at each peak
* Transitions are either:
* - we're low: transition if we hit a high
* - we're high: transition if we hit a low
* (we need to do it this way because some tags keep high or
* low for long periods, others just reach the peak and go
* down)
*/
if ((GraphBuffer[i] == high) && (GraphBuffer[i - 1] == c)) {
GraphBuffer[i] = 1 - c;
} else if ((GraphBuffer[i] == low) && (GraphBuffer[i - 1] == (1 - c))){
GraphBuffer[i] = c;
} else {
/* No transition */
GraphBuffer[i] = GraphBuffer[i - 1];
}
}
RepaintGraphWindow();
return 0;
}
int CmdAutoCorr(const char *Cmd)
{
static int CorrelBuffer[MAX_GRAPH_TRACE_LEN];
int window = atoi(Cmd);
if (window == 0) {
PrintAndLog("needs a window");
return 0;
}
if (window >= GraphTraceLen) {
PrintAndLog("window must be smaller than trace (%d samples)",
GraphTraceLen);
return 0;
}
PrintAndLog("performing %d correlations", GraphTraceLen - window);
for (int i = 0; i < GraphTraceLen - window; ++i) {
int sum = 0;
for (int j = 0; j < window; ++j) {
sum += (GraphBuffer[j]*GraphBuffer[i + j]) / 256;
}
CorrelBuffer[i] = sum;
}
GraphTraceLen = GraphTraceLen - window;
memcpy(GraphBuffer, CorrelBuffer, GraphTraceLen * sizeof (int));
RepaintGraphWindow();
return 0;
}
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);
for (int j = 0; j < 48; j++) {
for (int k = 0; k < 8; k++) {
if(sample_buf[j] & (1 << (7 - k))) {
GraphBuffer[cnt++] = 1;
} else {
GraphBuffer[cnt++] = 0;
}
}
}
}
GraphTraceLen = cnt;
RepaintGraphWindow();
return 0;
}
/*
* Convert to a bitstream
*/
int CmdBitstream(const char *Cmd)
{
int i, j;
int bit;
int gtl;
int clock;
int low = 0;
int high = 0;
int hithigh, hitlow, first;
/* Detect high and lows and clock */
for (i = 0; i < GraphTraceLen; ++i)
{
if (GraphBuffer[i] > high)
high = GraphBuffer[i];
else if (GraphBuffer[i] < low)
low = GraphBuffer[i];
}
/* Get our clock */
clock = GetClock(Cmd, high, 1);
gtl = ClearGraph(0);
bit = 0;
for (i = 0; i < (int)(gtl / clock); ++i)
{
hithigh = 0;
hitlow = 0;
first = 1;
/* Find out if we hit both high and low peaks */
for (j = 0; j < clock; ++j)
{
if (GraphBuffer[(i * clock) + j] == high)
hithigh = 1;
else if (GraphBuffer[(i * clock) + j] == low)
hitlow = 1;
/* it doesn't count if it's the first part of our read
because it's really just trailing from the last sequence */
if (first && (hithigh || hitlow))
hithigh = hitlow = 0;
else
first = 0;
if (hithigh && hitlow)
break;
}
/* If we didn't hit both high and low peaks, we had a bit transition */
if (!hithigh || !hitlow)
bit ^= 1;
AppendGraph(0, clock, bit);
// for (j = 0; j < (int)(clock/2); j++)
// GraphBuffer[(i * clock) + j] = bit ^ 1;
// for (j = (int)(clock/2); j < clock; j++)
// GraphBuffer[(i * clock) + j] = bit;
}
RepaintGraphWindow();
return 0;
}
int CmdBuffClear(const char *Cmd)
{
UsbCommand c = {CMD_BUFF_CLEAR};
SendCommand(&c);
ClearGraph(true);
return 0;
}
int CmdDec(const char *Cmd)
{
for (int i = 0; i < (GraphTraceLen / 2); ++i)
GraphBuffer[i] = GraphBuffer[i * 2];
GraphTraceLen /= 2;
PrintAndLog("decimated by 2");
RepaintGraphWindow();
return 0;
}
/* Print our clock rate */
int CmdDetectClockRate(const char *Cmd)
{
int clock = DetectClock(0);
PrintAndLog("Auto-detected clock rate: %d", clock);
return 0;
}
int CmdFSKdemod(const char *Cmd)
{
static const int LowTone[] = {
1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, -1, -1, -1, -1, -1
};
static const int HighTone[] = {
1, 1, 1, 1, 1, -1, -1, -1, -1,
1, 1, 1, 1, -1, -1, -1, -1,
1, 1, 1, 1, -1, -1, -1, -1,
1, 1, 1, 1, -1, -1, -1, -1,
1, 1, 1, 1, -1, -1, -1, -1,
1, 1, 1, 1, -1, -1, -1, -1, -1,
};
int lowLen = sizeof (LowTone) / sizeof (int);
int highLen = sizeof (HighTone) / sizeof (int);
int convLen = (highLen > lowLen) ? highLen : lowLen;
uint32_t hi = 0, lo = 0;
int i, j;
int minMark = 0, maxMark = 0;
for (i = 0; i < GraphTraceLen - convLen; ++i) {
int lowSum = 0, highSum = 0;
for (j = 0; j < lowLen; ++j) {
lowSum += LowTone[j]*GraphBuffer[i+j];
}
for (j = 0; j < highLen; ++j) {
highSum += HighTone[j] * GraphBuffer[i + j];
}
lowSum = abs(100 * lowSum / lowLen);
highSum = abs(100 * highSum / highLen);
GraphBuffer[i] = (highSum << 16) | lowSum;
}
for(i = 0; i < GraphTraceLen - convLen - 16; ++i) {
int lowTot = 0, highTot = 0;
// 10 and 8 are f_s divided by f_l and f_h, rounded
for (j = 0; j < 10; ++j) {
lowTot += (GraphBuffer[i+j] & 0xffff);
}
for (j = 0; j < 8; j++) {
highTot += (GraphBuffer[i + j] >> 16);
}
GraphBuffer[i] = lowTot - highTot;
if (GraphBuffer[i] > maxMark) maxMark = GraphBuffer[i];
if (GraphBuffer[i] < minMark) minMark = GraphBuffer[i];
}
GraphTraceLen -= (convLen + 16);
RepaintGraphWindow();
// Find bit-sync (3 lo followed by 3 high)
int max = 0, maxPos = 0;
for (i = 0; i < 6000; ++i) {
int dec = 0;
for (j = 0; j < 3 * lowLen; ++j) {
dec -= GraphBuffer[i + j];
}
for (; j < 3 * (lowLen + highLen ); ++j) {
dec += GraphBuffer[i + j];
}
if (dec > max) {
max = dec;
maxPos = i;
}
}
// place start of bit sync marker in graph
GraphBuffer[maxPos] = maxMark;
GraphBuffer[maxPos + 1] = minMark;
maxPos += j;
// place end of bit sync marker in graph
GraphBuffer[maxPos] = maxMark;
GraphBuffer[maxPos+1] = minMark;
PrintAndLog("actual data bits start at sample %d", maxPos);
PrintAndLog("length %d/%d", highLen, lowLen);
uint8_t bits[46];
bits[sizeof(bits)-1] = '\0';
// find bit pairs and manchester decode them
for (i = 0; i < arraylen(bits) - 1; ++i) {
int dec = 0;
for (j = 0; j < lowLen; ++j) {
dec -= GraphBuffer[maxPos + j];
}
for (; j < lowLen + highLen; ++j) {
dec += GraphBuffer[maxPos + j];
}
maxPos += j;
// place inter bit marker in graph
GraphBuffer[maxPos] = maxMark;
GraphBuffer[maxPos + 1] = minMark;
// hi and lo form a 64 bit pair
hi = (hi << 1) | (lo >> 31);
lo = (lo << 1);
// store decoded bit as binary (in hi/lo) and text (in bits[])
if(dec < 0) {
bits[i] = '1';
lo |= 1;
} else {
bits[i] = '0';
}
}
PrintAndLog("bits: '%s'", bits);
PrintAndLog("hex: %08x %08x", hi, lo);
return 0;
}
int CmdGrid(const char *Cmd)
{
sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY);
RepaintGraphWindow();
return 0;
}
int CmdHexsamples(const char *Cmd)
{
int n;
int requested = 0;
int offset = 0;
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 (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;
}
if (delivered >= requested)
break;
}
return 0;
}
int CmdHFSamples(const char *Cmd)
{
int cnt = 0;
int n = strtol(Cmd, NULL, 0);
if(n == 0) {
n = 1000;
} else {
n/= 4;
}
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]);
}
}
GraphTraceLen = cnt;
RepaintGraphWindow();
return 0;
}
int CmdHide(const char *Cmd)
{
HideGraphWindow();
return 0;
}
int CmdHpf(const char *Cmd)
{
int i;
int accum = 0;
for (i = 10; i < GraphTraceLen; ++i)
accum += GraphBuffer[i];
accum /= (GraphTraceLen - 10);
for (i = 0; i < GraphTraceLen; ++i)
GraphBuffer[i] -= accum;
RepaintGraphWindow();
return 0;
}
int CmdLFSamples(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;
}
int CmdLoad(const char *Cmd)
{
FILE *f = fopen(Cmd, "r");
if (!f) {
PrintAndLog("couldn't open '%s'", Cmd);
return 0;
}
GraphTraceLen = 0;
char line[80];
while (fgets(line, sizeof (line), f)) {
GraphBuffer[GraphTraceLen] = atoi(line);
GraphTraceLen++;
}
fclose(f);
PrintAndLog("loaded %d samples", GraphTraceLen);
RepaintGraphWindow();
return 0;
}
int CmdLtrim(const char *Cmd)
{
int ds = atoi(Cmd);
for (int i = ds; i < GraphTraceLen; ++i)
GraphBuffer[i-ds] = GraphBuffer[i];
GraphTraceLen -= ds;
RepaintGraphWindow();
return 0;
}
/*
* Manchester demodulate a bitstream. The bitstream needs to be already in
* the GraphBuffer as 0 and 1 values
*
* Give the clock rate as argument in order to help the sync - the algorithm
* resyncs at each pulse anyway.
*
* Not optimized by any means, this is the 1st time I'm writing this type of
* routine, feel free to improve...
*
* 1st argument: clock rate (as number of samples per clock rate)
* Typical values can be 64, 32, 128...
*/
int CmdManchesterDemod(const char *Cmd)
{
int i, j, invert= 0;
int bit;
int clock;
int lastval;
int low = 0;
int high = 0;
int hithigh, hitlow, first;
int lc = 0;
int bitidx = 0;
int bit2idx = 0;
int warnings = 0;
/* check if we're inverting output */
if (*Cmd == 'i')
{
PrintAndLog("Inverting output");
invert = 1;
do
++Cmd;
while(*Cmd == ' '); // in case a 2nd argument was given
}
/* Holds the decoded bitstream: each clock period contains 2 bits */
/* later simplified to 1 bit after manchester decoding. */
/* Add 10 bits to allow for noisy / uncertain traces without aborting */
/* int BitStream[GraphTraceLen*2/clock+10]; */
/* But it does not work if compiling on WIndows: therefore we just allocate a */
/* large array */
int BitStream[MAX_GRAPH_TRACE_LEN];
/* Detect high and lows */
for (i = 0; i < GraphTraceLen; i++)
{
if (GraphBuffer[i] > high)
high = GraphBuffer[i];
else if (GraphBuffer[i] < low)
low = GraphBuffer[i];
}
/* Get our clock */
clock = GetClock(Cmd, high, 1);
int tolerance = clock/4;
/* Detect first transition */
/* Lo-Hi (arbitrary) */
/* skip to the first high */
for (i= 0; i < GraphTraceLen; i++)
if (GraphBuffer[i] == high)
break;
/* now look for the first low */
for (; i < GraphTraceLen; i++)
{
if (GraphBuffer[i] == low)
{
lastval = i;
break;
}
}
/* If we're not working with 1/0s, demod based off clock */
if (high != 1)
{
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;
hitlow = 0;
first = 1;
/* Find out if we hit both high and low peaks */
for (j = 0; j < clock; j++)
{
if (GraphBuffer[(i * clock) + j] == high)
hithigh = 1;
else if (GraphBuffer[(i * clock) + j] == low)
hitlow = 1;
/* it doesn't count if it's the first part of our read
because it's really just trailing from the last sequence */
if (first && (hithigh || hitlow))
hithigh = hitlow = 0;
else
first = 0;
if (hithigh && hitlow)
break;
}
/* If we didn't hit both high and low peaks, we had a bit transition */
if (!hithigh || !hitlow)
bit ^= 1;
BitStream[bit2idx++] = bit ^ invert;
}
}
/* standard 1/0 bitstream */
else
{
/* Then detect duration between 2 successive transitions */
for (bitidx = 1; i < GraphTraceLen; i++)
{
if (GraphBuffer[i-1] != GraphBuffer[i])
{
lc = i-lastval;
lastval = i;
// Error check: if bitidx becomes too large, we do not
// have a Manchester encoded bitstream or the clock is really
// wrong!
if (bitidx > (GraphTraceLen*2/clock+8) ) {
PrintAndLog("Error: the clock you gave is probably wrong, aborting.");
return 0;
}
// Then switch depending on lc length:
// Tolerance is 1/4 of clock rate (arbitrary)
if (abs(lc-clock/2) < tolerance) {
// Short pulse : either "1" or "0"
BitStream[bitidx++]=GraphBuffer[i-1];
} else if (abs(lc-clock) < tolerance) {
// Long pulse: either "11" or "00"
BitStream[bitidx++]=GraphBuffer[i-1];
BitStream[bitidx++]=GraphBuffer[i-1];
} else {
// Error
warnings++;
PrintAndLog("Warning: Manchester decode error for pulse width detection.");
PrintAndLog("(too many of those messages mean either the stream is not Manchester encoded, or clock is wrong)");
if (warnings > 10)
{
PrintAndLog("Error: too many detection errors, aborting.");
return 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) {
if ((BitStream[i] == 0) && (BitStream[i+1] == 1)) {
BitStream[bit2idx++] = 1 ^ invert;
} else if ((BitStream[i] == 1) && (BitStream[i+1] == 0)) {
BitStream[bit2idx++] = 0 ^ invert;
} else {
// We cannot end up in this state, this means we are unsynchronized,
// move up 1 bit:
i++;
warnings++;
PrintAndLog("Unsynchronized, resync...");
PrintAndLog("(too many of those messages mean the stream is not Manchester encoded)");
if (warnings > 10)
{
PrintAndLog("Error: too many decode errors, aborting.");
return 0;
}
}
}
}
PrintAndLog("Manchester decoded bitstream");
// Now output the bitstream to the scrollback by line of 16 bits
for (i = 0; i < (bit2idx-16); i+=16) {
PrintAndLog("%i %i %i %i %i %i %i %i %i %i %i %i %i %i %i %i",
BitStream[i],
BitStream[i+1],
BitStream[i+2],
BitStream[i+3],
BitStream[i+4],
BitStream[i+5],
BitStream[i+6],
BitStream[i+7],
BitStream[i+8],
BitStream[i+9],
BitStream[i+10],
BitStream[i+11],
BitStream[i+12],
BitStream[i+13],
BitStream[i+14],
BitStream[i+15]);
}
return 0;
}
/* 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);
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++)
GraphBuffer[(i * clock) + j] = bit ^ lastbit ^ wave;
for (j = (int)(clock/2); 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 */
wave ^= bit ^ lastbit;
lastbit = bit;
}
RepaintGraphWindow();
return 0;
}
int CmdNorm(const char *Cmd)
{
int i;
int max = INT_MIN, min = INT_MAX;
for (i = 10; i < GraphTraceLen; ++i) {
if (GraphBuffer[i] > max)
max = GraphBuffer[i];
if (GraphBuffer[i] < min)
min = GraphBuffer[i];
}
if (max != min) {
for (i = 0; i < GraphTraceLen; ++i) {
GraphBuffer[i] = (GraphBuffer[i] - ((max + min) / 2)) * 1000 /
(max - min);
}
}
RepaintGraphWindow();
return 0;
}
int CmdPlot(const char *Cmd)
{
ShowGraphWindow();
return 0;
}
int CmdSave(const char *Cmd)
{
FILE *f = fopen(Cmd, "w");
if(!f) {
PrintAndLog("couldn't open '%s'", Cmd);
return 0;
}
int i;
for (i = 0; i < GraphTraceLen; i++) {
fprintf(f, "%d\n", GraphBuffer[i]);
}
fclose(f);
PrintAndLog("saved to '%s'", Cmd);
return 0;
}
int CmdScale(const char *Cmd)
{
CursorScaleFactor = atoi(Cmd);
if (CursorScaleFactor == 0) {
PrintAndLog("bad, can't have zero scale");
CursorScaleFactor = 1;
}
RepaintGraphWindow();
return 0;
}
int CmdThreshold(const char *Cmd)
{
int threshold = atoi(Cmd);
for (int i = 0; i < GraphTraceLen; ++i) {
if (GraphBuffer[i] >= threshold)
GraphBuffer[i] = 1;
else
GraphBuffer[i] =- 1;
}
RepaintGraphWindow();
return 0;
}
int CmdZerocrossings(const char *Cmd)
{
// Zero-crossings aren't meaningful unless the signal is zero-mean.
CmdHpf("");
int sign = 1;
int zc = 0;
int lastZc = 0;
for (int i = 0; i < GraphTraceLen; ++i) {
if (GraphBuffer[i] * sign >= 0) {
// No change in sign, reproduce the previous sample count.
zc++;
GraphBuffer[i] = lastZc;
} else {
// Change in sign, reset the sample count.
sign = -sign;
GraphBuffer[i] = lastZc;
if (sign > 0) {
lastZc = zc;
zc = 0;
}
}
}
RepaintGraphWindow();
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"amp", CmdAmp, 1, "Amplify peaks"},
{"askdemod", Cmdaskdemod, 1, "<0|1> -- Attempt to demodulate simple ASK tags"},
{"autocorr", CmdAutoCorr, 1, "<window length> -- Autocorrelation over window"},
{"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"},
{"bitstream", CmdBitstream, 1, "[clock rate] -- Convert waveform into a bitstream"},
{"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"},
{"dec", CmdDec, 1, "Decimate samples"},
{"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"},
{"hfsamples", CmdHFSamples, 0, "[nb of samples] Get raw samples for HF tag"},
{"hide", CmdHide, 1, "Hide graph window"},
{"hpf", CmdHpf, 1, "Remove DC offset from trace"},
{"lfsamples", CmdLFSamples, 0, "[128 - 16000] -- Get raw samples for LF tag"},
{"load", CmdLoad, 1, "<filename> -- Load trace (to graph window"},
{"ltrim", CmdLtrim, 1, "<samples> -- Trim samples from left of trace"},
{"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"},
{"save", CmdSave, 1, "<filename> -- Save trace (from graph window)"},
{"scale", CmdScale, 1, "<int> -- Set cursor display scale"},
{"threshold", CmdThreshold, 1, "Maximize/minimize every value in the graph window depending on threshold"},
{"zerocrossings", CmdZerocrossings, 1, "Count time between zero-crossings"},
{NULL, NULL, 0, NULL}
};
int CmdData(const char *Cmd)
{
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

32
client/cmddata.h Normal file
View file

@ -0,0 +1,32 @@
#ifndef CMDDATA_H__
#define CMDDATA_H__
int CmdData(const char *Cmd);
int CmdAmp(const char *Cmd);
int Cmdaskdemod(const char *Cmd);
int CmdAutoCorr(const char *Cmd);
int CmdBitsamples(const char *Cmd);
int CmdBitstream(const char *Cmd);
int CmdBuffClear(const char *Cmd);
int CmdDec(const char *Cmd);
int CmdDetectClockRate(const char *Cmd);
int CmdFSKdemod(const char *Cmd);
int CmdGrid(const char *Cmd);
int CmdHexsamples(const char *Cmd);
int CmdHFSamples(const char *Cmd);
int CmdHide(const char *Cmd);
int CmdHpf(const char *Cmd);
int CmdLFSamples(const char *Cmd);
int CmdLoad(const char *Cmd);
int CmdLtrim(const char *Cmd);
int CmdManchesterDemod(const char *Cmd);
int CmdManchesterMod(const char *Cmd);
int CmdNorm(const char *Cmd);
int CmdPlot(const char *Cmd);
int CmdSave(const char *Cmd);
int CmdScale(const char *Cmd);
int CmdThreshold(const char *Cmd);
int CmdZerocrossings(const char *Cmd);
#endif

41
client/cmdhf.c Normal file
View file

@ -0,0 +1,41 @@
#include <stdio.h>
#include "proxusb.h"
#include "graph.h"
#include "ui.h"
#include "cmdparser.h"
#include "cmdhf.h"
#include "cmdhf14a.h"
#include "cmdhf14b.h"
#include "cmdhf15.h"
#include "cmdhflegic.h"
static int CmdHelp(const char *Cmd);
int CmdHFTune(const char *Cmd)
{
UsbCommand c={CMD_MEASURE_ANTENNA_TUNING_HF};
SendCommand(&c);
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"14a", CmdHF14A, 1, "ISO14443A RFIDs"},
{"14b", CmdHF14B, 1, "ISO14443B RFIDs"},
{"15", CmdHF15, 1, "ISO15693 RFIDs"},
{"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"},
{NULL, NULL, 0, NULL}
};
int CmdHF(const char *Cmd)
{
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

8
client/cmdhf.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef CMDHF_H__
#define CMDHF_H__
int CmdHF(const char *Cmd);
int CmdHFTune(const char *Cmd);
#endif

200
client/cmdhf14a.c Normal file
View file

@ -0,0 +1,200 @@
#include <stdio.h>
#include <string.h>
#include "iso14443crc.h"
#include "data.h"
#include "proxusb.h"
#include "ui.h"
#include "cmdparser.h"
#include "cmdhf14a.h"
static int CmdHelp(const char *Cmd);
int CmdHF14AList(const char *Cmd)
{
uint8_t got[1920];
GetFromBigBuf(got, sizeof(got));
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
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]);
}
}
char *crc;
crc = "";
if (len > 2) {
uint8_t b1, b2;
for (j = 0; j < (len - 1); j++) {
// 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) {
ComputeCrc14443(CRC_14443_A, frame, len-2, &b1, &b2);
if (b1 != frame[len-2] || b2 != frame[len-1]) {
crc = (isResponse & (len < 6)) ? "" : " !crc";
} else {
crc = "";
}
}
} else {
crc = ""; // SHORT
}
char metricString[100];
if (isResponse) {
sprintf(metricString, "%3d", metric);
} else {
strcpy(metricString, " ");
}
PrintAndLog(" +%7d: %s: %s %s %s",
(prev < 0 ? 0 : (timestamp - prev)),
metricString,
(isResponse ? "TAG" : " "), line, crc);
prev = timestamp;
i += (len + 9);
}
return 0;
}
int CmdHF14AMifare(const char *Cmd)
{
UsbCommand c = {CMD_READER_MIFARE, {strtol(Cmd, NULL, 0), 0, 0}};
SendCommand(&c);
return 0;
}
int CmdHF14AReader(const char *Cmd)
{
UsbCommand c = {CMD_READER_ISO_14443a, {strtol(Cmd, NULL, 0), 0, 0}};
SendCommand(&c);
return 0;
}
// ## simulate iso14443a tag
// ## greg - added ability to specify tag UID
int CmdHF14ASim(const char *Cmd)
{
unsigned int hi = 0, lo = 0;
int n = 0, i = 0;
while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
hi= (hi << 4) | (lo >> 28);
lo= (lo << 4) | (n & 0xf);
}
// c.arg should be set to *Cmd or convert *Cmd to the correct format for a uid
UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a, {hi, lo, 0}};
PrintAndLog("Emulating 14443A TAG with UID %x%16x", hi, lo);
SendCommand(&c);
return 0;
}
int CmdHF14ASnoop(const char *Cmd)
{
UsbCommand c = {CMD_SNOOP_ISO_14443a};
SendCommand(&c);
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"list", CmdHF14AList, 0, "List ISO 14443a history"},
{"mifare", CmdHF14AMifare, 0, "Read out sector 0 parity error messages"},
{"reader", CmdHF14AReader, 0, "Act like an ISO14443 Type A reader"},
{"sim", CmdHF14ASim, 0, "<UID> -- Fake ISO 14443a tag"},
{"snoop", CmdHF14ASnoop, 0, "Eavesdrop ISO 14443 Type A"},
{NULL, NULL, 0, NULL}
};
int CmdHF14A(const char *Cmd)
{
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

12
client/cmdhf14a.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef CMDHF14A_H__
#define CMDHF14A_H__
int CmdHF14A(const char *Cmd);
int CmdHF14AList(const char *Cmd);
int CmdHF14AMifare(const char *Cmd);
int CmdHF14AReader(const char *Cmd);
int CmdHF14ASim(const char *Cmd);
int CmdHF14ASnoop(const char *Cmd);
#endif

283
client/cmdhf14b.c Normal file
View file

@ -0,0 +1,283 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#include <stdint.h>
#include "iso14443crc.h"
#include "proxusb.h"
#include "data.h"
#include "graph.h"
#include "ui.h"
#include "cmdparser.h"
#include "cmdhf14b.h"
static int CmdHelp(const char *Cmd);
int CmdHF14BDemod(const char *Cmd)
{
int i, j, iold;
int isum, qsum;
int outOfWeakAt;
bool negateI, negateQ;
uint8_t data[256];
int dataLen = 0;
// As received, the samples are pairs, correlations against I and Q
// square waves. So estimate angle of initial carrier (or just
// quadrant, actually), and then do the demod.
// First, estimate where the tag starts modulating.
for (i = 0; i < GraphTraceLen; i += 2) {
if (abs(GraphBuffer[i]) + abs(GraphBuffer[i + 1]) > 40) {
break;
}
}
if (i >= GraphTraceLen) {
PrintAndLog("too weak to sync");
return 0;
}
PrintAndLog("out of weak at %d", i);
outOfWeakAt = i;
// Now, estimate the phase in the initial modulation of the tag
isum = 0;
qsum = 0;
for (; i < (outOfWeakAt + 16); i += 2) {
isum += GraphBuffer[i + 0];
qsum += GraphBuffer[i + 1];
}
negateI = (isum < 0);
negateQ = (qsum < 0);
// Turn the correlation pairs into soft decisions on the bit.
j = 0;
for (i = 0; i < GraphTraceLen / 2; i++) {
int si = GraphBuffer[j];
int sq = GraphBuffer[j + 1];
if (negateI) si = -si;
if (negateQ) sq = -sq;
GraphBuffer[i] = si + sq;
j += 2;
}
GraphTraceLen = i;
i = outOfWeakAt / 2;
while (GraphBuffer[i] > 0 && i < GraphTraceLen)
i++;
if (i >= GraphTraceLen) goto demodError;
iold = i;
while (GraphBuffer[i] < 0 && i < GraphTraceLen)
i++;
if (i >= GraphTraceLen) goto demodError;
if ((i - iold) > 23) goto demodError;
PrintAndLog("make it to demod loop");
for (;;) {
iold = i;
while (GraphBuffer[i] >= 0 && i < GraphTraceLen)
i++;
if (i >= GraphTraceLen) goto demodError;
if ((i - iold) > 6) goto demodError;
uint16_t shiftReg = 0;
if (i + 20 >= GraphTraceLen) goto demodError;
for (j = 0; j < 10; j++) {
int soft = GraphBuffer[i] + GraphBuffer[i + 1];
if (abs(soft) < (abs(isum) + abs(qsum)) / 20) {
PrintAndLog("weak bit");
}
shiftReg >>= 1;
if(GraphBuffer[i] + GraphBuffer[i+1] >= 0) {
shiftReg |= 0x200;
}
i+= 2;
}
if ((shiftReg & 0x200) && !(shiftReg & 0x001))
{
// valid data byte, start and stop bits okay
PrintAndLog(" %02x", (shiftReg >> 1) & 0xff);
data[dataLen++] = (shiftReg >> 1) & 0xff;
if (dataLen >= sizeof(data)) {
return 0;
}
} else if (shiftReg == 0x000) {
// this is EOF
break;
} else {
goto demodError;
}
}
uint8_t first, second;
ComputeCrc14443(CRC_14443_B, data, dataLen-2, &first, &second);
PrintAndLog("CRC: %02x %02x (%s)\n", first, second,
(first == data[dataLen-2] && second == data[dataLen-1]) ?
"ok" : "****FAIL****");
RepaintGraphWindow();
return 0;
demodError:
PrintAndLog("demod error");
RepaintGraphWindow();
return 0;
}
int CmdHF14BList(const char *Cmd)
{
uint8_t got[960];
GetFromBigBuf(got, sizeof(got));
PrintAndLog("recorded activity:");
PrintAndLog(" time :rssi: who bytes");
PrintAndLog("---------+----+----+-----------");
int i = 0;
int prev = -1;
for(;;) {
if(i >= 900) {
break;
}
bool isResponse;
int timestamp = *((uint32_t *)(got+i));
if(timestamp & 0x80000000) {
timestamp &= 0x7fffffff;
isResponse = 1;
} else {
isResponse = 0;
}
int metric = *((uint32_t *)(got+i+4));
int len = got[i+8];
if(len > 100) {
break;
}
if(i + len >= 900) {
break;
}
uint8_t *frame = (got+i+9);
char line[1000] = "";
int j;
for(j = 0; j < len; j++) {
sprintf(line+(j*3), "%02x ", frame[j]);
}
char *crc;
if(len > 2) {
uint8_t b1, b2;
ComputeCrc14443(CRC_14443_B, frame, len-2, &b1, &b2);
if(b1 != frame[len-2] || b2 != frame[len-1]) {
crc = "**FAIL CRC**";
} else {
crc = "";
}
} else {
crc = "(SHORT)";
}
char metricString[100];
if(isResponse) {
sprintf(metricString, "%3d", metric);
} else {
strcpy(metricString, " ");
}
PrintAndLog(" +%7d: %s: %s %s %s",
(prev < 0 ? 0 : timestamp - prev),
metricString,
(isResponse ? "TAG" : " "), line, crc);
prev = timestamp;
i += (len + 9);
}
return 0;
}
int CmdHF14BRead(const char *Cmd)
{
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443, {strtol(Cmd, NULL, 0), 0, 0}};
SendCommand(&c);
return 0;
}
int CmdHF14Sim(const char *Cmd)
{
UsbCommand c={CMD_SIMULATE_TAG_ISO_14443};
SendCommand(&c);
return 0;
}
int CmdHFSimlisten(const char *Cmd)
{
UsbCommand c = {CMD_SIMULATE_TAG_HF_LISTEN};
SendCommand(&c);
return 0;
}
int CmdHF14BSnoop(const char *Cmd)
{
UsbCommand c = {CMD_SNOOP_ISO_14443};
SendCommand(&c);
return 0;
}
/* New command to read the contents of a SRI512 tag
* SRI512 tags are ISO14443-B modulated memory tags,
* this command just dumps the contents of the memory
*/
int CmdSri512Read(const char *Cmd)
{
UsbCommand c = {CMD_READ_SRI512_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
SendCommand(&c);
return 0;
}
/* New command to read the contents of a SRIX4K tag
* SRIX4K tags are ISO14443-B modulated memory tags,
* this command just dumps the contents of the memory/
*/
int CmdSrix4kRead(const char *Cmd)
{
UsbCommand c = {CMD_READ_SRIX4K_TAG, {strtol(Cmd, NULL, 0), 0, 0}};
SendCommand(&c);
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"demod", CmdHF14BDemod, 1, "Demodulate ISO14443 Type B from tag"},
{"list", CmdHF14BList, 0, "List ISO 14443 history"},
{"read", CmdHF14BRead, 0, "Read HF tag (ISO 14443)"},
{"sim", CmdHF14Sim, 0, "Fake ISO 14443 tag"},
{"simlisten", CmdHFSimlisten, 0, "Get HF samples as fake tag"},
{"snoop", CmdHF14BSnoop, 0, "Eavesdrop ISO 14443"},
{"sri512read", CmdSri512Read, 0, "<int> -- Read contents of a SRI512 tag"},
{"srix4kread", CmdSrix4kRead, 0, "<int> -- Read contents of a SRIX4K tag"},
{NULL, NULL, 0, NULL}
};
int CmdHF14B(const char *Cmd)
{
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

15
client/cmdhf14b.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef CMDHF14B_H__
#define CMDHF14B_H__
int CmdHF14B(const char *Cmd);
int CmdHF14BDemod(const char *Cmd);
int CmdHF14BList(const char *Cmd);
int CmdHF14BRead(const char *Cmd);
int CmdHF14Sim(const char *Cmd);
int CmdHFSimlisten(const char *Cmd);
int CmdHF14BSnoop(const char *Cmd);
int CmdSri512Read(const char *Cmd);
int CmdSrix4kRead(const char *Cmd);
#endif

196
client/cmdhf15.c Normal file
View file

@ -0,0 +1,196 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "proxusb.h"
#include "data.h"
#include "graph.h"
#include "ui.h"
#include "cmdparser.h"
#include "cmdhf15.h"
static int CmdHelp(const char *Cmd);
static uint16_t Iso15693Crc(uint8_t *v, int n)
{
uint32_t reg;
int i, j;
reg = 0xffff;
for (i = 0; i < n; i++) {
reg = reg ^ ((uint32_t)v[i]);
for (j = 0; j < 8; j++) {
if (reg & 0x0001) {
reg = (reg >> 1) ^ 0x8408;
} else {
reg = (reg >> 1);
}
}
}
return (uint16_t)~reg;
}
int CmdHF15Demod(const char *Cmd)
{
// The sampling rate is 106.353 ksps/s, for T = 18.8 us
// SOF defined as
// 1) Unmodulated time of 56.64us
// 2) 24 pulses of 423.75khz
// 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz)
static const int FrameSOF[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-1, -1, -1, -1,
-1, -1, -1, -1,
1, 1, 1, 1,
1, 1, 1, 1
};
static const int Logic0[] = {
1, 1, 1, 1,
1, 1, 1, 1,
-1, -1, -1, -1,
-1, -1, -1, -1
};
static const int Logic1[] = {
-1, -1, -1, -1,
-1, -1, -1, -1,
1, 1, 1, 1,
1, 1, 1, 1
};
// EOF defined as
// 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us)
// 2) 24 pulses of 423.75khz
// 3) Unmodulated time of 56.64us
static const int FrameEOF[] = {
1, 1, 1, 1,
1, 1, 1, 1,
-1, -1, -1, -1,
-1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
int i, j;
int max = 0, maxPos;
int skip = 4;
if (GraphTraceLen < 1000) return 0;
// First, correlate for SOF
for (i = 0; i < 100; i++) {
int corr = 0;
for (j = 0; j < arraylen(FrameSOF); j += skip) {
corr += FrameSOF[j] * GraphBuffer[i + (j / skip)];
}
if (corr > max) {
max = corr;
maxPos = i;
}
}
PrintAndLog("SOF at %d, correlation %d", maxPos,
max / (arraylen(FrameSOF) / skip));
i = maxPos + arraylen(FrameSOF) / skip;
int k = 0;
uint8_t outBuf[20];
memset(outBuf, 0, sizeof(outBuf));
uint8_t mask = 0x01;
for (;;) {
int corr0 = 0, corr1 = 0, corrEOF = 0;
for (j = 0; j < arraylen(Logic0); j += skip) {
corr0 += Logic0[j] * GraphBuffer[i + (j / skip)];
}
for (j = 0; j < arraylen(Logic1); j += skip) {
corr1 += Logic1[j] * GraphBuffer[i + (j / skip)];
}
for (j = 0; j < arraylen(FrameEOF); j += skip) {
corrEOF += FrameEOF[j] * GraphBuffer[i + (j / skip)];
}
// Even things out by the length of the target waveform.
corr0 *= 4;
corr1 *= 4;
if (corrEOF > corr1 && corrEOF > corr0) {
PrintAndLog("EOF at %d", i);
break;
} else if (corr1 > corr0) {
i += arraylen(Logic1) / skip;
outBuf[k] |= mask;
} else {
i += arraylen(Logic0) / skip;
}
mask <<= 1;
if (mask == 0) {
k++;
mask = 0x01;
}
if ((i + (int)arraylen(FrameEOF)) >= GraphTraceLen) {
PrintAndLog("ran off end!");
break;
}
}
if (mask != 0x01) {
PrintAndLog("error, uneven octet! (discard extra bits!)");
PrintAndLog(" mask=%02x", mask);
}
PrintAndLog("%d octets", k);
for (i = 0; i < k; i++) {
PrintAndLog("# %2d: %02x ", i, outBuf[i]);
}
PrintAndLog("CRC=%04x", Iso15693Crc(outBuf, k - 2));
return 0;
}
int CmdHF15Read(const char *Cmd)
{
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693};
SendCommand(&c);
return 0;
}
int CmdHF15Reader(const char *Cmd)
{
UsbCommand c = {CMD_READER_ISO_15693, {strtol(Cmd, NULL, 0), 0, 0}};
SendCommand(&c);
return 0;
}
int CmdHF15Sim(const char *Cmd)
{
UsbCommand c = {CMD_SIMTAG_ISO_15693, {strtol(Cmd, NULL, 0), 0, 0}};
SendCommand(&c);
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"demod", CmdHF15Demod, 1, "Demodulate ISO15693 from tag"},
{"read", CmdHF15Read, 0, "Read HF tag (ISO 15693)"},
{"reader", CmdHF15Reader, 0, "Act like an ISO15693 reader"},
{"sim", CmdHF15Sim, 0, "Fake an ISO15693 tag"},
{NULL, NULL, 0, NULL}
};
int CmdHF15(const char *Cmd)
{
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

11
client/cmdhf15.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef CMDHF15_H__
#define CMDHF15_H__
int CmdHF15(const char *Cmd);
int CmdHF15Demod(const char *Cmd);
int CmdHF15Read(const char *Cmd);
int CmdHF15Reader(const char *Cmd);
int CmdHF15Sim(const char *Cmd);
#endif

31
client/cmdhflegic.c Normal file
View file

@ -0,0 +1,31 @@
#include "proxusb.h"
#include "cmdparser.h"
#include "cmdhflegic.h"
static int CmdHelp(const char *Cmd);
int CmdLegicRFRead(const char *Cmd)
{
UsbCommand c = {CMD_READER_LEGIC_RF};
SendCommand(&c);
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"reader", CmdLegicRFRead, 0, "Start the LEGIC RF reader"},
{NULL, NULL, 0, NULL}
};
int CmdHFLegic(const char *Cmd)
{
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

8
client/cmdhflegic.h Normal file
View file

@ -0,0 +1,8 @@
#ifndef CMDHFLEGIC_H__
#define CMDHFLEGIC_H__
int CmdHFLegic(const char *Cmd);
int CmdLegicRFRead(const char *Cmd);
#endif

144
client/cmdhw.c Normal file
View file

@ -0,0 +1,144 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include "ui.h"
#include "proxusb.h"
#include "cmdparser.h"
#include "cmdhw.h"
/* low-level hardware control */
static int CmdHelp(const char *Cmd);
int CmdDetectReader(const char *Cmd)
{
UsbCommand c={CMD_LISTEN_READER_FIELD};
// 'l' means LF - 125/134 kHz
if(*Cmd == 'l') {
c.arg[0] = 1;
} else if (*Cmd == 'h') {
c.arg[0] = 2;
} else if (*Cmd != '\0') {
PrintAndLog("use 'detectreader' or 'detectreader l' or 'detectreader h'");
return 0;
}
SendCommand(&c);
return 0;
}
// ## FPGA Control
int CmdFPGAOff(const char *Cmd)
{
UsbCommand c = {CMD_FPGA_MAJOR_MODE_OFF};
SendCommand(&c);
return 0;
}
int CmdLCD(const char *Cmd)
{
int i, j;
UsbCommand c={CMD_LCD};
sscanf(Cmd, "%x %d", &i, &j);
while (j--) {
c.arg[0] = i & 0x1ff;
SendCommand(&c);
}
return 0;
}
int CmdLCDReset(const char *Cmd)
{
UsbCommand c = {CMD_LCD_RESET, {strtol(Cmd, NULL, 0), 0, 0}};
SendCommand(&c);
return 0;
}
int CmdReadmem(const char *Cmd)
{
UsbCommand c = {CMD_READ_MEM, {strtol(Cmd, NULL, 0), 0, 0}};
SendCommand(&c);
return 0;
}
int CmdReset(const char *Cmd)
{
UsbCommand c = {CMD_HARDWARE_RESET};
SendCommand(&c);
return 0;
}
/*
* Sets the divisor for LF frequency clock: lets the user choose any LF frequency below
* 600kHz.
*/
int CmdSetDivisor(const char *Cmd)
{
UsbCommand c = {CMD_SET_LF_DIVISOR, {strtol(Cmd, NULL, 0), 0, 0}};
if (c.arg[0] < 0 || c.arg[0] > 255) {
PrintAndLog("divisor must be between 19 and 255");
} else {
SendCommand(&c);
PrintAndLog("Divisor set, expected freq=%dHz", 12000000 / (c.arg[0]+1));
}
return 0;
}
int CmdSetMux(const char *Cmd)
{
UsbCommand c={CMD_SET_ADC_MUX};
if (strcmp(Cmd, "lopkd") == 0) {
c.arg[0] = 0;
} else if (strcmp(Cmd, "loraw") == 0) {
c.arg[0] = 1;
} else if (strcmp(Cmd, "hipkd") == 0) {
c.arg[0] = 2;
} else if (strcmp(Cmd, "hiraw") == 0) {
c.arg[0] = 3;
}
SendCommand(&c);
return 0;
}
int CmdTune(const char *Cmd)
{
UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING};
SendCommand(&c);
return 0;
}
int CmdVersion(const char *Cmd)
{
UsbCommand c = {CMD_VERSION};
SendCommand(&c);
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"detectreader", CmdDetectReader,0, "['l'|'h'] -- Detect external reader field (option 'l' or 'h' to limit to LF or HF)"},
{"fpgaoff", CmdFPGAOff, 0, "Set FPGA off"},
{"lcd", CmdLCD, 0, "<HEX command> <count> -- Send command/data to LCD"},
{"lcdreset", CmdLCDReset, 0, "Hardware reset LCD"},
{"readmem", CmdReadmem, 0, "[address] -- Read memory at decimal address from flash"},
{"reset", CmdReset, 0, "Reset the Proxmark3"},
{"setlfdivisor", CmdSetDivisor, 0, "<19 - 255> -- Drive LF antenna at 12Mhz/(divisor+1)"},
{"setmux", CmdSetMux, 0, "<loraw|hiraw|lopkd|hipkd> -- Set the ADC mux to a specific value"},
{"tune", CmdTune, 0, "Measure antenna tuning"},
{"version", CmdVersion, 0, "Show version inforation about the connected Proxmark"},
{NULL, NULL, 0, NULL}
};
int CmdHW(const char *Cmd)
{
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

17
client/cmdhw.h Normal file
View file

@ -0,0 +1,17 @@
#ifndef CMDHW_H__
#define CMDHW_H__
int CmdHW(const char *Cmd);
int CmdDetectReader(const char *Cmd);
int CmdFPGAOff(const char *Cmd);
int CmdLCD(const char *Cmd);
int CmdLCDReset(const char *Cmd);
int CmdReadmem(const char *Cmd);
int CmdReset(const char *Cmd);
int CmdSetDivisor(const char *Cmd);
int CmdSetMux(const char *Cmd);
int CmdTune(const char *Cmd);
int CmdVersion(const char *Cmd);
#endif

453
client/cmdlf.c Normal file
View file

@ -0,0 +1,453 @@
#include <stdio.h>
#include <string.h>
#include "proxusb.h"
#include "data.h"
#include "graph.h"
#include "ui.h"
#include "cmdparser.h"
#include "cmddata.h"
#include "cmdlf.h"
#include "cmdlfhid.h"
#include "cmdlfti.h"
#include "cmdlfem4x.h"
static int CmdHelp(const char *Cmd);
/* send a command before reading */
int CmdLFCommandRead(const char *Cmd)
{
static char dummy[3];
dummy[0]= ' ';
UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K};
sscanf(Cmd, "%i %i %i %s %s", &c.arg[0], &c.arg[1], &c.arg[2], (char *) &c.d.asBytes,(char *) &dummy+1);
// in case they specified 'h'
strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy);
SendCommand(&c);
return 0;
}
int CmdFlexdemod(const char *Cmd)
{
int i;
for (i = 0; i < GraphTraceLen; ++i) {
if (GraphBuffer[i] < 0) {
GraphBuffer[i] = -1;
} else {
GraphBuffer[i] = 1;
}
}
#define LONG_WAIT 100
int start;
for (start = 0; start < GraphTraceLen - LONG_WAIT; start++) {
int first = GraphBuffer[start];
for (i = start; i < start + LONG_WAIT; i++) {
if (GraphBuffer[i] != first) {
break;
}
}
if (i == (start + LONG_WAIT)) {
break;
}
}
if (start == GraphTraceLen - LONG_WAIT) {
PrintAndLog("nothing to wait for");
return 0;
}
GraphBuffer[start] = 2;
GraphBuffer[start+1] = -2;
uint8_t bits[64];
int bit;
i = start;
for (bit = 0; bit < 64; bit++) {
int j;
int sum = 0;
for (j = 0; j < 16; j++) {
sum += GraphBuffer[i++];
}
if (sum > 0) {
bits[bit] = 1;
} else {
bits[bit] = 0;
}
PrintAndLog("bit %d sum %d", bit, sum);
}
for (bit = 0; bit < 64; bit++) {
int j;
int sum = 0;
for (j = 0; j < 16; j++) {
sum += GraphBuffer[i++];
}
if (sum > 0 && bits[bit] != 1) {
PrintAndLog("oops1 at %d", bit);
}
if (sum < 0 && bits[bit] != 0) {
PrintAndLog("oops2 at %d", bit);
}
}
GraphTraceLen = 32*64;
i = 0;
int phase = 0;
for (bit = 0; bit < 64; bit++) {
if (bits[bit] == 0) {
phase = 0;
} else {
phase = 1;
}
int j;
for (j = 0; j < 32; j++) {
GraphBuffer[i++] = phase;
phase = !phase;
}
}
RepaintGraphWindow();
return 0;
}
int CmdIndalaDemod(const char *Cmd)
{
// Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID
int state = -1;
int count = 0;
int i, j;
// worst case with GraphTraceLen=64000 is < 4096
// under normal conditions it's < 2048
uint8_t rawbits[4096];
int rawbit = 0;
int worst = 0, worstPos = 0;
PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32);
for (i = 0; i < GraphTraceLen-1; i += 2) {
count += 1;
if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) {
if (state == 0) {
for (j = 0; j < count - 8; j += 16) {
rawbits[rawbit++] = 0;
}
if ((abs(count - j)) > worst) {
worst = abs(count - j);
worstPos = i;
}
}
state = 1;
count = 0;
} else if ((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) {
if (state == 1) {
for (j = 0; j < count - 8; j += 16) {
rawbits[rawbit++] = 1;
}
if ((abs(count - j)) > worst) {
worst = abs(count - j);
worstPos = i;
}
}
state = 0;
count = 0;
}
}
PrintAndLog("Recovered %d raw bits", rawbit);
PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos);
// Finding the start of a UID
int uidlen, long_wait;
if (strcmp(Cmd, "224") == 0) {
uidlen = 224;
long_wait = 30;
} else {
uidlen = 64;
long_wait = 29;
}
int start;
int first = 0;
for (start = 0; start <= rawbit - uidlen; start++) {
first = rawbits[start];
for (i = start; i < start + long_wait; i++) {
if (rawbits[i] != first) {
break;
}
}
if (i == (start + long_wait)) {
break;
}
}
if (start == rawbit - uidlen + 1) {
PrintAndLog("nothing to wait for");
return 0;
}
// Inverting signal if needed
if (first == 1) {
for (i = start; i < rawbit; i++) {
rawbits[i] = !rawbits[i];
}
}
// Dumping UID
uint8_t bits[224];
char showbits[225];
showbits[uidlen]='\0';
int bit;
i = start;
int times = 0;
if (uidlen > rawbit) {
PrintAndLog("Warning: not enough raw bits to get a full UID");
for (bit = 0; bit < rawbit; bit++) {
bits[bit] = rawbits[i++];
// As we cannot know the parity, let's use "." and "/"
showbits[bit] = '.' + bits[bit];
}
showbits[bit+1]='\0';
PrintAndLog("Partial UID=%s", showbits);
return 0;
} else {
for (bit = 0; bit < uidlen; bit++) {
bits[bit] = rawbits[i++];
showbits[bit] = '0' + bits[bit];
}
times = 1;
}
PrintAndLog("UID=%s", showbits);
// Checking UID against next occurences
for (; i + uidlen <= rawbit;) {
int failed = 0;
for (bit = 0; bit < uidlen; bit++) {
if (bits[bit] != rawbits[i++]) {
failed = 1;
break;
}
}
if (failed == 1) {
break;
}
times += 1;
}
PrintAndLog("Occurences: %d (expected %d)", times, (rawbit - start) / uidlen);
// Remodulating for tag cloning
GraphTraceLen = 32*uidlen;
i = 0;
int phase = 0;
for (bit = 0; bit < uidlen; bit++) {
if (bits[bit] == 0) {
phase = 0;
} else {
phase = 1;
}
int j;
for (j = 0; j < 32; j++) {
GraphBuffer[i++] = phase;
phase = !phase;
}
}
RepaintGraphWindow();
return 0;
}
int CmdLFRead(const char *Cmd)
{
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K};
// 'h' means higher-low-frequency, 134 kHz
if(*Cmd == 'h') {
c.arg[0] = 1;
} else if (*Cmd == '\0') {
c.arg[0] = 0;
} else {
PrintAndLog("use 'read' or 'read h'");
return 0;
}
SendCommand(&c);
return 0;
}
static void ChkBitstream(const char *str)
{
int i;
/* convert to bitstream if necessary */
for (i = 0; i < (int)(GraphTraceLen / 2); i++)
{
if (GraphBuffer[i] > 1 || GraphBuffer[i] < 0)
{
CmdBitstream(str);
break;
}
}
}
int CmdLFSim(const char *Cmd)
{
int i;
static int gap;
sscanf(Cmd, "%i", &gap);
/* convert to bitstream if necessary */
ChkBitstream(Cmd);
PrintAndLog("Sending data, please wait...");
for (i = 0; i < GraphTraceLen; i += 48) {
UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}};
int j;
for (j = 0; j < 48; j++) {
c.d.asBytes[j] = GraphBuffer[i+j];
}
SendCommand(&c);
WaitForResponse(CMD_ACK);
}
PrintAndLog("Starting simulator...");
UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}};
SendCommand(&c);
return 0;
}
int CmdLFSimBidir(const char *Cmd)
{
/* Set ADC to twice the carrier for a slight supersampling */
UsbCommand c = {CMD_LF_SIMULATE_BIDIR, {47, 384, 0}};
SendCommand(&c);
return 0;
}
/* simulate an LF Manchester encoded tag with specified bitstream, clock rate and inter-id gap */
int CmdLFSimManchester(const char *Cmd)
{
static int clock, gap;
static char data[1024], gapstring[8];
/* get settings/bits */
sscanf(Cmd, "%i %s %i", &clock, &data[0], &gap);
/* clear our graph */
ClearGraph(0);
/* fill it with our bitstream */
for (int i = 0; i < strlen(data) ; ++i)
AppendGraph(0, clock, data[i]- '0');
/* modulate */
CmdManchesterMod("");
/* show what we've done */
RepaintGraphWindow();
/* simulate */
sprintf(&gapstring[0], "%i", gap);
CmdLFSim(gapstring);
return 0;
}
int CmdVchDemod(const char *Cmd)
{
// Is this the entire sync pattern, or does this also include some
// data bits that happen to be the same everywhere? That would be
// lovely to know.
static const int SyncPattern[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
};
// So first, we correlate for the sync pattern, and mark that.
int bestCorrel = 0, bestPos = 0;
int i;
// It does us no good to find the sync pattern, with fewer than
// 2048 samples after it...
for (i = 0; i < (GraphTraceLen-2048); i++) {
int sum = 0;
int j;
for (j = 0; j < arraylen(SyncPattern); j++) {
sum += GraphBuffer[i+j]*SyncPattern[j];
}
if (sum > bestCorrel) {
bestCorrel = sum;
bestPos = i;
}
}
PrintAndLog("best sync at %d [metric %d]", bestPos, bestCorrel);
char bits[257];
bits[256] = '\0';
int worst = INT_MAX;
int worstPos;
for (i = 0; i < 2048; i += 8) {
int sum = 0;
int j;
for (j = 0; j < 8; j++) {
sum += GraphBuffer[bestPos+i+j];
}
if (sum < 0) {
bits[i/8] = '.';
} else {
bits[i/8] = '1';
}
if(abs(sum) < worst) {
worst = abs(sum);
worstPos = i;
}
}
PrintAndLog("bits:");
PrintAndLog("%s", bits);
PrintAndLog("worst metric: %d at pos %d", worst, worstPos);
if (strcmp(Cmd, "clone")==0) {
GraphTraceLen = 0;
char *s;
for(s = bits; *s; s++) {
int j;
for(j = 0; j < 16; j++) {
GraphBuffer[GraphTraceLen++] = (*s == '1') ? 1 : 0;
}
}
RepaintGraphWindow();
}
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"cmdread", CmdLFCommandRead, 0, "<off period> <'0' period> <'1' period> <command> ['h'] -- Modulate LF reader field to send command before read (all periods in microseconds) (option 'h' for 134)"},
{"em4x", CmdLFEM4X, 1, "EM4X RFIDs"},
{"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"},
{"hid", CmdLFHID, 1, "HID RFIDs"},
{"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
{"read", CmdLFRead, 0, "['h'] -- Read 125/134 kHz LF ID-only tag (option 'h' for 134)"},
{"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"},
{"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
{"simman", CmdLFSimManchester, 0, "<Clock> <Bitstream> [GAP] Simulate arbitrary Manchester LF tag"},
{"ti", CmdLFTI, 1, "TI RFIDs"},
{"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"},
{NULL, NULL, 0, NULL}
};
int CmdLF(const char *Cmd)
{
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

15
client/cmdlf.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef CMDLF_H__
#define CMDLF_H__
int CmdLF(const char *Cmd);
int CmdLFCommandRead(const char *Cmd);
int CmdFlexdemod(const char *Cmd);
int CmdIndalaDemod(const char *Cmd);
int CmdLFRead(const char *Cmd);
int CmdLFSim(const char *Cmd);
int CmdLFSimBidir(const char *Cmd);
int CmdLFSimManchester(const char *Cmd);
int CmdVchDemod(const char *Cmd);
#endif

415
client/cmdlfem4x.c Normal file
View file

@ -0,0 +1,415 @@
#include <stdio.h>
#include "proxusb.h"
#include "ui.h"
#include "graph.h"
#include "cmdparser.h"
#include "cmddata.h"
#include "cmdlf.h"
#include "cmdlfem4x.h"
static int CmdHelp(const char *Cmd);
/* Read the ID of an EM410x tag.
* Format:
* 1111 1111 1 <-- standard non-repeatable header
* XXXX [row parity bit] <-- 10 rows of 5 bits for our 40 bit tag ID
* ....
* CCCC <-- each bit here is parity for the 10 bits above in corresponding column
* 0 <-- stop bit, end of tag
*/
int CmdEM410xRead(const char *Cmd)
{
int i, j, clock, header, rows, bit, hithigh, hitlow, first, bit2idx, high, low;
int parity[4];
char id[11];
int retested = 0;
int BitStream[MAX_GRAPH_TRACE_LEN];
high = low = 0;
/* Detect high and lows and clock */
for (i = 0; i < GraphTraceLen; i++)
{
if (GraphBuffer[i] > high)
high = GraphBuffer[i];
else if (GraphBuffer[i] < low)
low = GraphBuffer[i];
}
/* get clock */
clock = GetClock(Cmd, high, 0);
/* parity for our 4 columns */
parity[0] = parity[1] = parity[2] = parity[3] = 0;
header = rows = 0;
/* manchester demodulate */
bit = bit2idx = 0;
for (i = 0; i < (int)(GraphTraceLen / clock); i++)
{
hithigh = 0;
hitlow = 0;
first = 1;
/* Find out if we hit both high and low peaks */
for (j = 0; j < clock; j++)
{
if (GraphBuffer[(i * clock) + j] == high)
hithigh = 1;
else if (GraphBuffer[(i * clock) + j] == low)
hitlow = 1;
/* it doesn't count if it's the first part of our read
because it's really just trailing from the last sequence */
if (first && (hithigh || hitlow))
hithigh = hitlow = 0;
else
first = 0;
if (hithigh && hitlow)
break;
}
/* If we didn't hit both high and low peaks, we had a bit transition */
if (!hithigh || !hitlow)
bit ^= 1;
BitStream[bit2idx++] = bit;
}
retest:
/* We go till 5 before the graph ends because we'll get that far below */
for (i = 1; i < bit2idx - 5; i++)
{
/* Step 2: We have our header but need our tag ID */
if (header == 9 && rows < 10)
{
/* Confirm parity is correct */
if ((BitStream[i] ^ BitStream[i+1] ^ BitStream[i+2] ^ BitStream[i+3]) == BitStream[i+4])
{
/* Read another byte! */
sprintf(id+rows, "%x", (8 * BitStream[i]) + (4 * BitStream[i+1]) + (2 * BitStream[i+2]) + (1 * BitStream[i+3]));
rows++;
/* Keep parity info */
parity[0] ^= BitStream[i];
parity[1] ^= BitStream[i+1];
parity[2] ^= BitStream[i+2];
parity[3] ^= BitStream[i+3];
/* Move 4 bits ahead */
i += 4;
}
/* Damn, something wrong! reset */
else
{
PrintAndLog("Thought we had a valid tag but failed at word %d (i=%d)", rows + 1, i);
/* Start back rows * 5 + 9 header bits, -1 to not start at same place */
i -= 9 + (5 * rows) - 5;
rows = header = 0;
}
}
/* Step 3: Got our 40 bits! confirm column parity */
else if (rows == 10)
{
/* We need to make sure our 4 bits of parity are correct and we have a stop bit */
if (BitStream[i] == parity[0] && BitStream[i+1] == parity[1] &&
BitStream[i+2] == parity[2] && BitStream[i+3] == parity[3] &&
BitStream[i+4] == 0)
{
/* Sweet! */
PrintAndLog("EM410x Tag ID: %s", id);
/* Stop any loops */
return 1;
}
/* Crap! Incorrect parity or no stop bit, start all over */
else
{
rows = header = 0;
/* Go back 59 bits (9 header bits + 10 rows at 4+1 parity) */
i -= 59;
}
}
/* Step 1: get our header */
else if (header < 9)
{
/* Need 9 consecutive 1's */
if (BitStream[i] == 1)
header++;
/* We don't have a header, not enough consecutive 1 bits */
else
header = 0;
}
}
/* if we've already retested after flipping bits, return */
if (retested++)
return 0;
/* if this didn't work, try flipping bits */
for (i = 0; i < bit2idx; i++)
BitStream[i] ^= 1;
goto retest;
}
/* emulate an EM410X tag
* Format:
* 1111 1111 1 <-- standard non-repeatable header
* XXXX [row parity bit] <-- 10 rows of 5 bits for our 40 bit tag ID
* ....
* CCCC <-- each bit here is parity for the 10 bits above in corresponding column
* 0 <-- stop bit, end of tag
*/
int CmdEM410xSim(const char *Cmd)
{
int i, n, j, h, binary[4], parity[4];
/* clock is 64 in EM410x tags */
int clock = 64;
/* clear our graph */
ClearGraph(0);
/* write it out a few times */
for (h = 0; h < 4; h++)
{
/* write 9 start bits */
for (i = 0; i < 9; i++)
AppendGraph(0, clock, 1);
/* for each hex char */
parity[0] = parity[1] = parity[2] = parity[3] = 0;
for (i = 0; i < 10; i++)
{
/* read each hex char */
sscanf(&Cmd[i], "%1x", &n);
for (j = 3; j >= 0; j--, n/= 2)
binary[j] = n % 2;
/* append each bit */
AppendGraph(0, clock, binary[0]);
AppendGraph(0, clock, binary[1]);
AppendGraph(0, clock, binary[2]);
AppendGraph(0, clock, binary[3]);
/* append parity bit */
AppendGraph(0, clock, binary[0] ^ binary[1] ^ binary[2] ^ binary[3]);
/* keep track of column parity */
parity[0] ^= binary[0];
parity[1] ^= binary[1];
parity[2] ^= binary[2];
parity[3] ^= binary[3];
}
/* parity columns */
AppendGraph(0, clock, parity[0]);
AppendGraph(0, clock, parity[1]);
AppendGraph(0, clock, parity[2]);
AppendGraph(0, clock, parity[3]);
/* stop bit */
AppendGraph(0, clock, 0);
}
/* modulate that biatch */
CmdManchesterMod("");
/* booyah! */
RepaintGraphWindow();
CmdLFSim("");
return 0;
}
/* Function is equivalent of loread + losamples + em410xread
* looped until an EM410x tag is detected */
int CmdEM410xWatch(const char *Cmd)
{
char *zero = "";
char *twok = "2000";
int stop = 0;
do
{
CmdLFRead(zero);
CmdLFSamples(twok);
stop = CmdEM410xRead(zero);
} while (!stop);
return 0;
}
/* Read the transmitted data of an EM4x50 tag
* Format:
*
* XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
* XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
* XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
* XXXXXXXX [row parity bit (even)] <- 8 bits plus parity
* CCCCCCCC <- column parity bits
* 0 <- stop bit
* LW <- Listen Window
*
* This pattern repeats for every block of data being transmitted.
* Transmission starts with two Listen Windows (LW - a modulated
* pattern of 320 cycles each (32/32/128/64/64)).
*
* Note that this data may or may not be the UID. It is whatever data
* is stored in the blocks defined in the control word First and Last
* Word Read values. UID is stored in block 32.
*/
int CmdEM4x50Read(const char *Cmd)
{
int i, j, startblock, clock, skip, block, start, end, low, high;
bool complete= false;
int tmpbuff[MAX_GRAPH_TRACE_LEN / 64];
char tmp[6];
high= low= 0;
clock= 64;
/* first get high and low values */
for (i = 0; i < GraphTraceLen; i++)
{
if (GraphBuffer[i] > high)
high = GraphBuffer[i];
else if (GraphBuffer[i] < low)
low = GraphBuffer[i];
}
/* populate a buffer with pulse lengths */
i= 0;
j= 0;
while (i < GraphTraceLen)
{
// measure from low to low
while ((GraphBuffer[i] > low) && (i<GraphTraceLen))
++i;
start= i;
while ((GraphBuffer[i] < high) && (i<GraphTraceLen))
++i;
while ((GraphBuffer[i] > low) && (i<GraphTraceLen))
++i;
if (j>(MAX_GRAPH_TRACE_LEN/64)) {
break;
}
tmpbuff[j++]= i - start;
}
/* look for data start - should be 2 pairs of LW (pulses of 192,128) */
start= -1;
skip= 0;
for (i= 0; i < j - 4 ; ++i)
{
skip += tmpbuff[i];
if (tmpbuff[i] >= 190 && tmpbuff[i] <= 194)
if (tmpbuff[i+1] >= 126 && tmpbuff[i+1] <= 130)
if (tmpbuff[i+2] >= 190 && tmpbuff[i+2] <= 194)
if (tmpbuff[i+3] >= 126 && tmpbuff[i+3] <= 130)
{
start= i + 3;
break;
}
}
startblock= i + 3;
/* skip over the remainder of the LW */
skip += tmpbuff[i+1]+tmpbuff[i+2];
while (skip < MAX_GRAPH_TRACE_LEN && GraphBuffer[skip] > low)
++skip;
skip += 8;
/* now do it again to find the end */
end= start;
for (i += 3; i < j - 4 ; ++i)
{
end += tmpbuff[i];
if (tmpbuff[i] >= 190 && tmpbuff[i] <= 194)
if (tmpbuff[i+1] >= 126 && tmpbuff[i+1] <= 130)
if (tmpbuff[i+2] >= 190 && tmpbuff[i+2] <= 194)
if (tmpbuff[i+3] >= 126 && tmpbuff[i+3] <= 130)
{
complete= true;
break;
}
}
if (start >= 0)
PrintAndLog("Found data at sample: %i",skip);
else
{
PrintAndLog("No data found!");
PrintAndLog("Try again with more samples.");
return 0;
}
if (!complete)
{
PrintAndLog("*** Warning!");
PrintAndLog("Partial data - no end found!");
PrintAndLog("Try again with more samples.");
}
/* get rid of leading crap */
sprintf(tmp,"%i",skip);
CmdLtrim(tmp);
/* now work through remaining buffer printing out data blocks */
block= 0;
i= startblock;
while (block < 6)
{
PrintAndLog("Block %i:", block);
// mandemod routine needs to be split so we can call it for data
// just print for now for debugging
CmdManchesterDemod("i 64");
skip= 0;
/* look for LW before start of next block */
for ( ; i < j - 4 ; ++i)
{
skip += tmpbuff[i];
if (tmpbuff[i] >= 190 && tmpbuff[i] <= 194)
if (tmpbuff[i+1] >= 126 && tmpbuff[i+1] <= 130)
break;
}
while (GraphBuffer[skip] > low)
++skip;
skip += 8;
sprintf(tmp,"%i",skip);
CmdLtrim(tmp);
start += skip;
block++;
}
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"em410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag"},
{"em410xsim", CmdEM410xSim, 0, "<UID> -- Simulate EM410x tag"},
{"em410xwatch", CmdEM410xWatch, 0, "Watches for EM410x tags"},
{"em4x50read", CmdEM4x50Read, 1, "Extract data from EM4x50 tag"},
{NULL, NULL, 0, NULL}
};
int CmdLFEM4X(const char *Cmd)
{
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

11
client/cmdlfem4x.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef CMDLFEM4X_H__
#define CMDLFEM4X_H__
int CmdLFEM4X(const char *Cmd);
int CmdEM410xRead(const char *Cmd);
int CmdEM410xSim(const char *Cmd);
int CmdEM410xWatch(const char *Cmd);
int CmdEM4x50Read(const char *Cmd);
#endif

72
client/cmdlfhid.c Normal file
View file

@ -0,0 +1,72 @@
#include <stdio.h>
#include "proxusb.h"
#include "ui.h"
#include "graph.h"
#include "cmdparser.h"
#include "cmdlfhid.h"
static int CmdHelp(const char *Cmd);
int CmdHIDDemod(const char *Cmd)
{
if (GraphTraceLen < 4800) {
PrintAndLog("too short; need at least 4800 samples");
return 0;
}
GraphTraceLen = 4800;
for (int i = 0; i < GraphTraceLen; ++i) {
if (GraphBuffer[i] < 0) {
GraphBuffer[i] = 0;
} else {
GraphBuffer[i] = 1;
}
}
RepaintGraphWindow();
return 0;
}
int CmdHIDDemodFSK(const char *Cmd)
{
UsbCommand c={CMD_HID_DEMOD_FSK};
SendCommand(&c);
return 0;
}
int CmdHIDSim(const char *Cmd)
{
unsigned int hi = 0, lo = 0;
int n = 0, i = 0;
while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
hi = (hi << 4) | (lo >> 28);
lo = (lo << 4) | (n & 0xf);
}
PrintAndLog("Emulating tag with ID %x%16x", hi, lo);
UsbCommand c = {CMD_HID_SIM_TAG, {hi, lo, 0}};
SendCommand(&c);
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"demod", CmdHIDDemod, 1, "Demodulate HID Prox Card II (not optimal)"},
{"fskdemod", CmdHIDDemodFSK, 0, "Realtime HID FSK demodulator"},
{"sim", CmdHIDSim, 0, "<ID> -- HID tag simulator"},
{NULL, NULL, 0, NULL}
};
int CmdLFHID(const char *Cmd)
{
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

10
client/cmdlfhid.h Normal file
View file

@ -0,0 +1,10 @@
#ifndef CMDLFHID_H__
#define CMDLFHID_H__
int CmdLFHID(const char *Cmd);
int CmdHIDDemod(const char *Cmd);
int CmdHIDDemodFSK(const char *Cmd);
int CmdHIDSim(const char *Cmd);
#endif

293
client/cmdlfti.c Normal file
View file

@ -0,0 +1,293 @@
#include <stdio.h>
#include "crc16.h"
#include "proxusb.h"
#include "data.h"
#include "ui.h"
#include "graph.h"
#include "cmdparser.h"
#include "cmdlfti.h"
static int CmdHelp(const char *Cmd);
int CmdTIDemod(const char *Cmd)
{
/* MATLAB as follows:
f_s = 2000000; % sampling frequency
f_l = 123200; % low FSK tone
f_h = 134200; % high FSK tone
T_l = 119e-6; % low bit duration
T_h = 130e-6; % high bit duration
l = 2*pi*ones(1, floor(f_s*T_l))*(f_l/f_s);
h = 2*pi*ones(1, floor(f_s*T_h))*(f_h/f_s);
l = sign(sin(cumsum(l)));
h = sign(sin(cumsum(h)));
*/
// 2M*16/134.2k = 238
static const int LowTone[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, -1, -1
};
// 2M*16/123.2k = 260
static const int HighTone[] = {
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, -1,
1, 1, 1, 1, 1, 1, 1, 1
};
int lowLen = sizeof(LowTone)/sizeof(int);
int highLen = sizeof(HighTone)/sizeof(int);
int convLen = (highLen>lowLen)?highLen:lowLen;
uint16_t crc;
int i, j, TagType;
int lowSum = 0, highSum = 0;;
int lowTot = 0, highTot = 0;
for (i = 0; i < GraphTraceLen - convLen; i++) {
lowSum = 0;
highSum = 0;;
for (j = 0; j < lowLen; j++) {
lowSum += LowTone[j]*GraphBuffer[i+j];
}
for (j = 0; j < highLen; j++) {
highSum += HighTone[j]*GraphBuffer[i+j];
}
lowSum = abs((100*lowSum) / lowLen);
highSum = abs((100*highSum) / highLen);
lowSum = (lowSum<0)?-lowSum:lowSum;
highSum = (highSum<0)?-highSum:highSum;
GraphBuffer[i] = (highSum << 16) | lowSum;
}
for (i = 0; i < GraphTraceLen - convLen - 16; i++) {
lowTot = 0;
highTot = 0;
// 16 and 15 are f_s divided by f_l and f_h, rounded
for (j = 0; j < 16; j++) {
lowTot += (GraphBuffer[i+j] & 0xffff);
}
for (j = 0; j < 15; j++) {
highTot += (GraphBuffer[i+j] >> 16);
}
GraphBuffer[i] = lowTot - highTot;
}
GraphTraceLen -= (convLen + 16);
RepaintGraphWindow();
// TI tag data format is 16 prebits, 8 start bits, 64 data bits,
// 16 crc CCITT bits, 8 stop bits, 15 end bits
// the 16 prebits are always low
// the 8 start and stop bits of a tag must match
// the start/stop prebits of a ro tag are 01111110
// the start/stop prebits of a rw tag are 11111110
// the 15 end bits of a ro tag are all low
// the 15 end bits of a rw tag match bits 15-1 of the data bits
// Okay, so now we have unsliced soft decisions;
// find bit-sync, and then get some bits.
// look for 17 low bits followed by 6 highs (common pattern for ro and rw tags)
int max = 0, maxPos = 0;
for (i = 0; i < 6000; i++) {
int j;
int dec = 0;
// searching 17 consecutive lows
for (j = 0; j < 17*lowLen; j++) {
dec -= GraphBuffer[i+j];
}
// searching 7 consecutive highs
for (; j < 17*lowLen + 6*highLen; j++) {
dec += GraphBuffer[i+j];
}
if (dec > max) {
max = dec;
maxPos = i;
}
}
// place a marker in the buffer to visually aid location
// of the start of sync
GraphBuffer[maxPos] = 800;
GraphBuffer[maxPos+1] = -800;
// advance pointer to start of actual data stream (after 16 pre and 8 start bits)
maxPos += 17*lowLen;
maxPos += 6*highLen;
// place a marker in the buffer to visually aid location
// of the end of sync
GraphBuffer[maxPos] = 800;
GraphBuffer[maxPos+1] = -800;
PrintAndLog("actual data bits start at sample %d", maxPos);
PrintAndLog("length %d/%d", highLen, lowLen);
uint8_t bits[1+64+16+8+16];
bits[sizeof(bits)-1] = '\0';
uint32_t shift3 = 0x7e000000, shift2 = 0, shift1 = 0, shift0 = 0;
for (i = 0; i < arraylen(bits)-1; i++) {
int high = 0;
int low = 0;
int j;
for (j = 0; j < lowLen; j++) {
low -= GraphBuffer[maxPos+j];
}
for (j = 0; j < highLen; j++) {
high += GraphBuffer[maxPos+j];
}
if (high > low) {
bits[i] = '1';
maxPos += highLen;
// bitstream arrives lsb first so shift right
shift3 |= (1<<31);
} else {
bits[i] = '.';
maxPos += lowLen;
}
// 128 bit right shift register
shift0 = (shift0>>1) | (shift1 << 31);
shift1 = (shift1>>1) | (shift2 << 31);
shift2 = (shift2>>1) | (shift3 << 31);
shift3 >>= 1;
// place a marker in the buffer between bits to visually aid location
GraphBuffer[maxPos] = 800;
GraphBuffer[maxPos+1] = -800;
}
PrintAndLog("Info: raw tag bits = %s", bits);
TagType = (shift3>>8)&0xff;
if ( TagType != ((shift0>>16)&0xff) ) {
PrintAndLog("Error: start and stop bits do not match!");
return 0;
}
else if (TagType == 0x7e) {
PrintAndLog("Info: Readonly TI tag detected.");
return 0;
}
else if (TagType == 0xfe) {
PrintAndLog("Info: Rewriteable TI tag detected.");
// put 64 bit data into shift1 and shift0
shift0 = (shift0>>24) | (shift1 << 8);
shift1 = (shift1>>24) | (shift2 << 8);
// align 16 bit crc into lower half of shift2
shift2 = ((shift2>>24) | (shift3 << 8)) & 0x0ffff;
// align 16 bit "end bits" or "ident" into lower half of shift3
shift3 >>= 16;
// only 15 bits compare, last bit of ident is not valid
if ( (shift3^shift0)&0x7fff ) {
PrintAndLog("Error: Ident mismatch!");
}
// WARNING the order of the bytes in which we calc crc below needs checking
// i'm 99% sure the crc algorithm is correct, but it may need to eat the
// bytes in reverse or something
// calculate CRC
crc=0;
crc = update_crc16(crc, (shift0)&0xff);
crc = update_crc16(crc, (shift0>>8)&0xff);
crc = update_crc16(crc, (shift0>>16)&0xff);
crc = update_crc16(crc, (shift0>>24)&0xff);
crc = update_crc16(crc, (shift1)&0xff);
crc = update_crc16(crc, (shift1>>8)&0xff);
crc = update_crc16(crc, (shift1>>16)&0xff);
crc = update_crc16(crc, (shift1>>24)&0xff);
PrintAndLog("Info: Tag data = %08X%08X", shift1, shift0);
if (crc != (shift2&0xffff)) {
PrintAndLog("Error: CRC mismatch, calculated %04X, got ^04X", crc, shift2&0xffff);
} else {
PrintAndLog("Info: CRC %04X is good", crc);
}
}
else {
PrintAndLog("Unknown tag type.");
return 0;
}
return 0;
}
// read a TI tag and return its ID
int CmdTIRead(const char *Cmd)
{
UsbCommand c = {CMD_READ_TI_TYPE};
SendCommand(&c);
return 0;
}
// write new data to a r/w TI tag
int CmdTIWrite(const char *Cmd)
{
UsbCommand c = {CMD_WRITE_TI_TYPE};
int res = 0;
res = sscanf(Cmd, "0x%x 0x%x 0x%x ", &c.arg[0], &c.arg[1], &c.arg[2]);
if (res == 2) c.arg[2]=0;
if (res < 2)
PrintAndLog("Please specify the data as two hex strings, optionally the CRC as a third");
else
SendCommand(&c);
return 0;
}
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"demod", CmdTIDemod, 1, "Demodulate raw bits for TI-type LF tag"},
{"read", CmdTIRead, 0, "Read and decode a TI 134 kHz tag"},
{"write", CmdTIWrite, 0, "Write new data to a r/w TI 134 kHz tag"},
{NULL, NULL, 0, NULL}
};
int CmdLFTI(const char *Cmd)
{
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}

10
client/cmdlfti.h Normal file
View file

@ -0,0 +1,10 @@
#ifndef CMDLFTI_H__
#define CMDLFTI_H__
int CmdLFTI(const char *Cmd);
int CmdTIDemod(const char *Cmd);
int CmdTIRead(const char *Cmd);
int CmdTIWrite(const char *Cmd);
#endif

138
client/cmdmain.c Normal file
View file

@ -0,0 +1,138 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "cmdparser.h"
#include "data.h"
#include "usb_cmd.h"
#include "ui.h"
#include "cmdhf.h"
#include "cmddata.h"
#include "cmdhw.h"
#include "cmdlf.h"
#include "cmdmain.h"
unsigned int current_command = CMD_UNKNOWN;
unsigned int received_command = CMD_UNKNOWN;
static int CmdHelp(const char *Cmd);
static int CmdQuit(const char *Cmd);
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"data", CmdData, 1, "Plot window / data buffer manipulation"},
{"exit", CmdQuit, 1, "Exit program"},
{"hf", CmdHF, 1, "HF commands"},
{"hw", CmdHW, 1, "Hardware commands"},
{"lf", CmdLF, 1, "LF commands"},
{"quit", CmdQuit, 1, "Quit program"},
{NULL, NULL, 0, NULL}
};
int CmdHelp(const char *Cmd)
{
CmdsHelp(CommandTable);
return 0;
}
int CmdQuit(const char *Cmd)
{
exit(0);
return 0;
}
void WaitForResponse(uint32_t response_type)
{
while (received_command != response_type) {
#ifdef WIN32
UsbCommand c;
if (ReceiveCommandPoll(&c))
UsbCommandReceived(&c);
Sleep(0);
#else
usleep(10000); // XXX ugh
#endif
}
received_command = CMD_UNKNOWN;
}
//-----------------------------------------------------------------------------
// Entry point into our code: called whenever the user types a command and
// then presses Enter, which the full command line that they typed.
//-----------------------------------------------------------------------------
void CommandReceived(char *Cmd)
{
CmdsParse(CommandTable, Cmd);
}
//-----------------------------------------------------------------------------
// Entry point into our code: called whenever we received a packet over USB
// that we weren't necessarily expecting, for example a debug print.
//-----------------------------------------------------------------------------
void UsbCommandReceived(UsbCommand *UC)
{
// printf("%s(%x) current cmd = %x\n", __FUNCTION__, c->cmd, current_command);
/* If we recognize a response, return to avoid further processing */
switch(UC->cmd) {
case CMD_DEBUG_PRINT_STRING: {
char s[100];
if(UC->arg[0] > 70 || UC->arg[0] < 0) {
UC->arg[0] = 0;
}
memcpy(s, UC->d.asBytes, UC->arg[0]);
s[UC->arg[0]] = '\0';
PrintAndLog("#db# %s", s);
return;
}
case CMD_DEBUG_PRINT_INTEGERS:
PrintAndLog("#db# %08x, %08x, %08x\r\n", UC->arg[0], UC->arg[1], UC->arg[2]);
return;
case CMD_MEASURED_ANTENNA_TUNING: {
int peakv, peakf;
int vLf125, vLf134, vHf;
vLf125 = UC->arg[0] & 0xffff;
vLf134 = UC->arg[0] >> 16;
vHf = UC->arg[1] & 0xffff;;
peakf = UC->arg[2] & 0xffff;
peakv = UC->arg[2] >> 16;
PrintAndLog("");
PrintAndLog("");
PrintAndLog("# LF antenna: %5.2f V @ 125.00 kHz", vLf125/1000.0);
PrintAndLog("# LF antenna: %5.2f V @ 134.00 kHz", vLf134/1000.0);
PrintAndLog("# LF optimal: %5.2f V @%9.2f kHz", peakv/1000.0, 12000.0/(peakf+1));
PrintAndLog("# HF antenna: %5.2f V @ 13.56 MHz", vHf/1000.0);
if (peakv<2000)
PrintAndLog("# Your LF antenna is unusable.");
else if (peakv<10000)
PrintAndLog("# Your LF antenna is marginal.");
if (vHf<2000)
PrintAndLog("# Your HF antenna is unusable.");
else if (vHf<5000)
PrintAndLog("# Your HF antenna is marginal.");
return;
}
default:
break;
}
/* Maybe it's a response: */
switch(current_command) {
case CMD_DOWNLOAD_RAW_ADC_SAMPLES_125K:
if (UC->cmd != CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K) goto unexpected_response;
int i;
for(i=0; i<48; i++) sample_buf[i] = UC->d.asBytes[i];
received_command = UC->cmd;
return;
case CMD_DOWNLOADED_SIM_SAMPLES_125K:
if (UC->cmd != CMD_ACK) goto unexpected_response;
// got ACK
received_command = UC->cmd;
return;
default:
unexpected_response:
PrintAndLog("unrecognized command %08x\n", UC->cmd);
break;
}
}

10
client/cmdmain.h Normal file
View file

@ -0,0 +1,10 @@
#ifndef CMDMAIN_H__
#define CMDMAIN_H__
#include "usb_cmd.h"
void UsbCommandReceived(UsbCommand *UC);
void CommandReceived(char *Cmd);
void WaitForResponse(uint32_t response_type);
#endif

32
client/cmdparser.c Normal file
View file

@ -0,0 +1,32 @@
#include <stdio.h>
#include <string.h>
#include "ui.h"
#include "cmdparser.h"
void CmdsHelp(const command_t Commands[])
{
if (Commands[0].Name == NULL)
return;
int i = 0;
while (Commands[i].Name)
{
if (!offline || Commands[i].Offline)
PrintAndLog("%-16s %s", Commands[i].Name, Commands[i].Help);
++i;
}
}
void CmdsParse(const command_t Commands[], const char *Cmd)
{
char cmd_name[32];
int len = 0;
memset(cmd_name, 0, 32);
sscanf(Cmd, "%31s%n", cmd_name, &len);
int i = 0;
while (Commands[i].Name && strcmp(Commands[i].Name, cmd_name))
++i;
if (Commands[i].Name)
Commands[i].Parse(Cmd + len);
else
PrintAndLog("Command not found");
}

19
client/cmdparser.h Normal file
View file

@ -0,0 +1,19 @@
#ifndef CMDPARSER_H__
#define CMDPARSER_H__
typedef struct command_s
{
const char * Name;
int (*Parse)(const char *Cmd);
int Offline;
const char * Help;
} command_t;
// command_t array are expected to be NULL terminated
// Print help for each command in the command array
void CmdsHelp(const command_t Commands[]);
// Parse a command line
void CmdsParse(const command_t Commands[], const char *Cmd);
#endif

File diff suppressed because it is too large Load diff

25
client/data.c Normal file
View file

@ -0,0 +1,25 @@
#include <string.h>
#include <stdint.h>
#include "data.h"
#include "ui.h"
#include "proxusb.h"
#include "cmdmain.h"
uint8_t sample_buf[SAMPLE_BUFFER_SIZE];
void GetFromBigBuf(uint8_t *dest, int bytes)
{
int n = bytes/4;
if (n % 48 != 0) {
PrintAndLog("bad len in GetFromBigBuf");
return;
}
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);
memcpy(dest+(i*4), sample_buf, 48);
}
}

13
client/data.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef DATA_H__
#define DATA_H__
#include <stdint.h>
#define SAMPLE_BUFFER_SIZE 64
extern uint8_t sample_buf[SAMPLE_BUFFER_SIZE];
#define arraylen(x) (sizeof(x)/sizeof((x)[0]))
void GetFromBigBuf(uint8_t *dest, int bytes);
#endif

View file

@ -1,26 +1,14 @@
#ifdef WIN32 #ifdef WIN32
#include <windows.h> #include <windows.h>
#include <setupapi.h> #include <setupapi.h>
#include <ctype.h>
#define bzero(b,len) (memset((b), '\0', (len)), (void) 0) #define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
BOOL UsbConnect(void); BOOL UsbConnect(void);
#else #else
#include <usb.h> #include <proxusb.h>
#endif #endif
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <strings.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "prox.h" #include <stdio.h>
#ifndef WIN32 #include <string.h>
#include "proxmark3.h"
#endif
#include "flash.h" #include "flash.h"
#include "elf.h" #include "elf.h"
@ -30,269 +18,268 @@ static bool AllWritten;
#define PHYSICAL_FLASH_START 0x100000 #define PHYSICAL_FLASH_START 0x100000
#define PHYSICAL_FLASH_END 0x200000 #define PHYSICAL_FLASH_END 0x200000
void WaitForAck(void) { void WaitForAck(void)
UsbCommand ack; {
ReceiveCommand(&ack); UsbCommand ack;
if(ack.cmd != CMD_ACK) { ReceiveCommand(&ack);
printf("bad ACK\n"); if (ack.cmd != CMD_ACK) {
exit(-1); printf("bad ACK\n");
} exit(-1);
}
} }
struct partition partitions[] = { struct partition partitions[] = {
{0x100000, 0x102000, 1, "bootrom"}, {0x100000, 0x102000, 1, "bootrom"},
{0x102000, 0x110000, 0, "fpga"}, {0x102000, 0x110000, 0, "fpga"},
{0x110000, 0x140000, 0, "os"}, {0x110000, 0x140000, 0, "os"},
{0, 0, 0, NULL}, {0, 0, 0, NULL},
}; };
void WriteBlock(unsigned int block_start, unsigned int len, unsigned char *buf) void WriteBlock(unsigned int block_start, unsigned int len, unsigned char *buf)
{ {
unsigned char temp_buf[256]; unsigned char temp_buf[256];
if (block_start & 0xFF) { if (block_start & 0xFF) {
printf("moving stuff forward by %d bytes\n", block_start & 0xFF); printf("moving stuff forward by %d bytes\n", block_start & 0xFF);
memset(temp_buf, 0xFF, block_start & 0xFF); memset(temp_buf, 0xFF, block_start & 0xFF);
memcpy(temp_buf + (block_start & 0xFF), buf, len - (block_start & 0xFF)); memcpy(temp_buf + (block_start & 0xFF), buf, len - (block_start & 0xFF));
block_start &= ~0xFF; block_start &= ~0xFF;
} else { } else {
memcpy(temp_buf, buf, len); memcpy(temp_buf, buf, len);
} }
UsbCommand c = {CMD_SETUP_WRITE};
int i; UsbCommand c = {CMD_SETUP_WRITE};
for(i = 0; i < 240; i += 48) {
memcpy(c.d.asBytes, temp_buf+i, 48);
c.arg[0] = (i/4);
SendCommand(&c);
WaitForAck();
}
c.cmd = CMD_FINISH_WRITE; for (int i = 0; i < 240; i += 48) {
c.arg[0] = block_start; memcpy(c.d.asBytes, temp_buf+i, 48);
c.arg[0] = (i/4);
SendCommand(&c);
WaitForAck();
}
// printf("writing block %08x\r", c.arg[0]); c.cmd = CMD_FINISH_WRITE;
memcpy(c.d.asBytes, temp_buf+240, 16); c.arg[0] = block_start;
SendCommand(&c);
WaitForAck();
AllWritten = true; // printf("writing block %08x\r", c.arg[0]);
memcpy(c.d.asBytes, temp_buf+240, 16);
SendCommand(&c);
WaitForAck();
AllWritten = true;
} }
void LoadFlashFromFile(const char *file, int start_addr, int end_addr) void LoadFlashFromFile(const char *file, int start_addr, int end_addr)
{ {
FILE *f = fopen(file, "rb"); FILE *f = fopen(file, "rb");
if(!f) { if (!f) {
printf("couldn't open file\n"); printf("couldn't open file\n");
exit(-1); exit(-1);
} }
char buf[4]; char buf[4];
fread(buf, 1, 4, f); fread(buf, 1, 4, f);
if (memcmp(buf, "\x7F" "ELF", 4) == 0) { if (memcmp(buf, "\x7F" "ELF", 4) == 0) {
int i; fseek(f, 0, SEEK_SET);
fseek(f, 0, SEEK_SET); Elf32_Ehdr header;
Elf32_Ehdr header; fread(&header, 1, sizeof(header), f);
fread(&header, 1, sizeof(header), f); int count = header.e_phnum;
int count = header.e_phnum; printf("count=%d phoff=%x\n", count, header.e_phoff);
printf("count=%d phoff=%x\n", count, header.e_phoff); Elf32_Phdr phdr;
Elf32_Phdr phdr;
for (i=0; i<header.e_phnum; i++) {
fseek(f, header.e_phoff + i * sizeof(Elf32_Phdr), SEEK_SET);
fread(&phdr, 1, sizeof(phdr), f);
printf("type=%d offset=%x paddr=%x vaddr=%x filesize=%x memsize=%x flags=%x align=%x\n",
phdr.p_type, phdr.p_offset, phdr.p_paddr, phdr.p_vaddr, phdr.p_filesz, phdr.p_memsz, phdr.p_flags, phdr.p_align);
if (phdr.p_type == PT_LOAD && phdr.p_filesz > 0 && phdr.p_paddr >= PHYSICAL_FLASH_START
&& (phdr.p_paddr + phdr.p_filesz) < PHYSICAL_FLASH_END) {
printf("flashing offset=%x paddr=%x size=%x\n", phdr.p_offset, phdr.p_paddr, phdr.p_filesz);
if (phdr.p_offset == 0) {
printf("skipping forward 0x2000 because of strange linker thing\n");
phdr.p_offset += 0x2000;
phdr.p_paddr += 0x2000;
phdr.p_filesz -= 0x2000;
phdr.p_memsz -= 0x2000;
}
fseek(f, phdr.p_offset, SEEK_SET); for (int i = 0; i < header.e_phnum; ++i) {
ExpectedAddr = phdr.p_paddr; fseek(f, header.e_phoff + i * sizeof(Elf32_Phdr), SEEK_SET);
while (ExpectedAddr < (phdr.p_paddr + phdr.p_filesz)) { fread(&phdr, 1, sizeof(phdr), f);
unsigned int bytes_to_read = phdr.p_paddr + phdr.p_filesz - ExpectedAddr; printf("type=%d offset=%x paddr=%x vaddr=%x filesize=%x memsize=%x flags=%x align=%x\n",
if (bytes_to_read > 256) phdr.p_type, phdr.p_offset, phdr.p_paddr, phdr.p_vaddr, phdr.p_filesz, phdr.p_memsz, phdr.p_flags, phdr.p_align);
bytes_to_read=256; if (phdr.p_type == PT_LOAD && phdr.p_filesz > 0 && phdr.p_paddr >= PHYSICAL_FLASH_START
else && (phdr.p_paddr + phdr.p_filesz) < PHYSICAL_FLASH_END) {
memset(QueuedToSend, 0xFF, 256); printf("flashing offset=%x paddr=%x size=%x\n", phdr.p_offset, phdr.p_paddr, phdr.p_filesz);
fread(QueuedToSend, 1, bytes_to_read, f); if (phdr.p_offset == 0) {
printf("WriteBlock(%x, %d, %02x %02x %02x %02x %02x %02x %02x %02x ... %02x %02x %02x %02x %02x %02x %02x %02x)\n", ExpectedAddr, bytes_to_read, printf("skipping forward 0x2000 because of strange linker thing\n");
QueuedToSend[0], QueuedToSend[1], QueuedToSend[2], QueuedToSend[3], phdr.p_offset += 0x2000;
QueuedToSend[4], QueuedToSend[5], QueuedToSend[6], QueuedToSend[7], phdr.p_paddr += 0x2000;
QueuedToSend[248], QueuedToSend[249], QueuedToSend[250], QueuedToSend[251], phdr.p_filesz -= 0x2000;
QueuedToSend[252], QueuedToSend[253], QueuedToSend[254], QueuedToSend[255]); phdr.p_memsz -= 0x2000;
WriteBlock(ExpectedAddr, 256, QueuedToSend);
ExpectedAddr += bytes_to_read;
}
}
} }
fclose(f); fseek(f, phdr.p_offset, SEEK_SET);
printf("\ndone.\n"); ExpectedAddr = phdr.p_paddr;
return; while (ExpectedAddr < (phdr.p_paddr + phdr.p_filesz)) {
} else printf("Bad file format\n"); unsigned int bytes_to_read = phdr.p_paddr + phdr.p_filesz - ExpectedAddr;
if (bytes_to_read > 256)
bytes_to_read=256;
else
memset(QueuedToSend, 0xFF, 256);
fread(QueuedToSend, 1, bytes_to_read, f);
printf("WriteBlock(%x, %d, %02x %02x %02x %02x %02x %02x %02x %02x ... %02x %02x %02x %02x %02x %02x %02x %02x)\n", ExpectedAddr, bytes_to_read,
QueuedToSend[0], QueuedToSend[1], QueuedToSend[2], QueuedToSend[3],
QueuedToSend[4], QueuedToSend[5], QueuedToSend[6], QueuedToSend[7],
QueuedToSend[248], QueuedToSend[249], QueuedToSend[250], QueuedToSend[251],
QueuedToSend[252], QueuedToSend[253], QueuedToSend[254], QueuedToSend[255]);
WriteBlock(ExpectedAddr, 256, QueuedToSend);
ExpectedAddr += bytes_to_read;
}
}
}
fclose(f);
printf("\ndone.\n");
return;
} else printf("Bad file format\n");
} }
int PrepareFlash(struct partition *p, const char *filename, unsigned int state) int PrepareFlash(struct partition *p, const char *filename, unsigned int state)
{ {
if(state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) { if (state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) {
UsbCommand c = {CMD_START_FLASH, {p->start, p->end, 0}}; UsbCommand c = {CMD_START_FLASH, {p->start, p->end, 0}};
/* Only send magic when flashing bootrom */
if(p->precious)
c.arg[2] = START_FLASH_MAGIC;
else
c.arg[2] = 0;
SendCommand(&c); /* Only send magic when flashing bootrom */
WaitForAck(); if (p->precious)
} else { c.arg[2] = START_FLASH_MAGIC;
fprintf(stderr, "Warning: Your bootloader does not understand the new START_FLASH command\n"); else
fprintf(stderr, " It is recommended that you update your bootloader\n\n"); c.arg[2] = 0;
exit(0);
} SendCommand(&c);
WaitForAck();
LoadFlashFromFile(filename, p->start, p->end); } else {
return 1; fprintf(stderr, "Warning: Your bootloader does not understand the new START_FLASH command\n");
fprintf(stderr, " It is recommended that you update your bootloader\n\n");
exit(0);
}
LoadFlashFromFile(filename, p->start, p->end);
return 1;
} }
unsigned int GetProxmarkState(void) unsigned int GetProxmarkState(void)
{ {
unsigned int state = 0; unsigned int state = 0;
UsbCommand c; UsbCommand c;
c.cmd = CMD_DEVICE_INFO; c.cmd = CMD_DEVICE_INFO;
SendCommand(&c); SendCommand(&c);
UsbCommand resp; UsbCommand resp;
ReceiveCommand(&resp); ReceiveCommand(&resp);
/* Three cases: /* Three cases:
* 1. The old bootrom code will ignore CMD_DEVICE_INFO, but respond with an ACK * 1. The old bootrom code will ignore CMD_DEVICE_INFO, but respond with an ACK
* 2. The old os code will respond with CMD_DEBUG_PRINT_STRING and "unknown command" * 2. The old os code will respond with CMD_DEBUG_PRINT_STRING and "unknown command"
* 3. The new bootrom and os codes will respond with CMD_DEVICE_INFO and flags * 3. The new bootrom and os codes will respond with CMD_DEVICE_INFO and flags
*/ */
switch(resp.cmd) { switch (resp.cmd) {
case CMD_ACK: case CMD_ACK:
state = DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM; state = DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM;
break; break;
case CMD_DEBUG_PRINT_STRING: case CMD_DEBUG_PRINT_STRING:
state = DEVICE_INFO_FLAG_CURRENT_MODE_OS; state = DEVICE_INFO_FLAG_CURRENT_MODE_OS;
break; break;
case CMD_DEVICE_INFO: case CMD_DEVICE_INFO:
state = resp.arg[0]; state = resp.arg[0];
break; break;
default: default:
fprintf(stderr, "Couldn't get proxmark state, bad response type: 0x%04X\n", resp.cmd); fprintf(stderr, "Couldn't get proxmark state, bad response type: 0x%04X\n", resp.cmd);
exit(-1); exit(-1);
break; break;
} }
return state; return state;
} }
unsigned int EnterFlashState(void) unsigned int EnterFlashState(void)
{ {
unsigned int state = GetProxmarkState(); unsigned int state = GetProxmarkState();
if(state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM) { if (state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM) {
/* Already in flash state, we're done. */ /* Already in flash state, we're done. */
return state; return state;
} }
if(state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) { if (state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) {
fprintf(stderr,"Entering flash-mode...\n"); fprintf(stderr,"Entering flash-mode...\n");
UsbCommand c; UsbCommand c;
bzero(&c, sizeof(c)); bzero(&c, sizeof(c));
if( (state & DEVICE_INFO_FLAG_BOOTROM_PRESENT) && (state & DEVICE_INFO_FLAG_OSIMAGE_PRESENT) ) { if ((state & DEVICE_INFO_FLAG_BOOTROM_PRESENT) && (state & DEVICE_INFO_FLAG_OSIMAGE_PRESENT)) {
/* New style handover: Send CMD_START_FLASH, which will reset the board and /* New style handover: Send CMD_START_FLASH, which will reset the board and
* enter the bootrom on the next boot. * enter the bootrom on the next boot.
*/ */
c.cmd = CMD_START_FLASH; c.cmd = CMD_START_FLASH;
SendCommand(&c); SendCommand(&c);
fprintf(stderr,"(You don't have to do anything. Press and release the button only if you want to abort)\n"); fprintf(stderr,"(You don't have to do anything. Press and release the button only if you want to abort)\n");
fprintf(stderr,"Waiting for Proxmark to reappear on USB... "); fprintf(stderr,"Waiting for Proxmark to reappear on USB... ");
} else { } else {
/* Old style handover: Ask the user to press the button, then reset the board */ /* Old style handover: Ask the user to press the button, then reset the board */
c.cmd = CMD_HARDWARE_RESET; c.cmd = CMD_HARDWARE_RESET;
SendCommand(&c); SendCommand(&c);
fprintf(stderr,"(Press and hold down button NOW if your bootloader requires it)\n"); fprintf(stderr,"(Press and hold down button NOW if your bootloader requires it)\n");
fprintf(stderr,"Waiting for Proxmark to reappear on USB... "); fprintf(stderr,"Waiting for Proxmark to reappear on USB... ");
} }
#ifdef WIN32 #ifdef WIN32
Sleep(1000); Sleep(1000);
while(!UsbConnect()) { Sleep(1000); } while (!UsbConnect()) { Sleep(1000); }
#else #else
CloseProxmark(); CloseProxmark();
sleep(1); sleep(1);
while(!(devh=OpenProxmark(0))) { sleep(1); } while (!OpenProxmark(0)) { sleep(1); }
#endif #endif
fprintf(stderr,"Found.\n"); fprintf(stderr,"Found.\n");
return GetProxmarkState(); return GetProxmarkState();
} }
return 0; return 0;
} }
/* On first call, have *offset = -1, *length = 0; */ /* On first call, have *offset = -1, *length = 0; */
int find_next_area(const char *str, int *offset, int *length) int find_next_area(const char *str, int *offset, int *length)
{ {
if(*str == '\0') return 0; if (*str == '\0') return 0;
if((*offset >= 0) && str[*offset + *length] == '\0') return 0; if ((*offset >= 0) && str[*offset + *length] == '\0') return 0;
*offset += 1 + *length; *offset += 1 + *length;
char *next_comma = strchr(str + *offset, ','); char *next_comma = strchr(str + *offset, ',');
if(next_comma == NULL) { if (next_comma == NULL) {
*length = strlen(str) - *offset; *length = strlen(str) - *offset;
} else { } else {
*length = next_comma-(str+*offset); *length = next_comma-(str+*offset);
} }
return 1; return 1;
} }
void do_flash(char **argv) { void do_flash(char **argv)
unsigned int state = EnterFlashState(); {
unsigned int state = EnterFlashState();
if (!(state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM)) { if (!(state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM)) {
fprintf(stderr, "Proxmark would not enter flash state, abort\n"); fprintf(stderr, "Proxmark would not enter flash state, abort\n");
exit(-1); exit(-1);
} }
int offset=-1, length=0; int offset=-1, length=0;
int current_area = 0; int current_area = 0;
while(find_next_area(argv[1], &offset, &length)) { while (find_next_area(argv[1], &offset, &length)) {
int i; struct partition *p = NULL;
struct partition *p = NULL; for (int i = 0; i<sizeof(partitions)/sizeof(partitions[0]); ++i) {
for (i=0; i<sizeof(partitions)/sizeof(partitions[0]); i++) { if (strncmp(partitions[i].name, argv[1] + offset, length) == 0) {
if (strncmp(partitions[i].name, argv[1] + offset, length) == 0) { /* Check if the name matches the bootrom partition, and if so, require "bootrom" to
/* Check if the name matches the bootrom partition, and if so, require "bootrom" to * be written in full. The other names may be abbreviated.
* be written in full. The other names may be abbreviated. */
*/ if(!partitions[i].precious || (strlen(partitions[i].name) == length))
if(!partitions[i].precious || (strlen(partitions[i].name) == length)) p = &partitions[i];
p = &partitions[i]; break;
break; }
} }
}
if(p == NULL) { if (p == NULL) {
fprintf(stderr, "Warning: area name '"); fprintf(stderr, "Warning: area name '");
fwrite(argv[1]+offset, length, 1, stderr); fwrite(argv[1]+offset, length, 1, stderr);
fprintf(stderr, "' unknown, ignored\n"); fprintf(stderr, "' unknown, ignored\n");
} else { } else {
fprintf(stderr, "Flashing %s from %s\n", p->name, argv[2+current_area]); fprintf(stderr, "Flashing %s from %s\n", p->name, argv[2+current_area]);
PrepareFlash(p, argv[2+current_area], state); PrepareFlash(p, argv[2+current_area], state);
} }
current_area++; current_area++;
} }
} }

View file

@ -2,10 +2,10 @@
#define __FLASH_H__ #define __FLASH_H__
struct partition { struct partition {
int start; int start;
int end; int end;
int precious; int precious;
const char *name; const char *name;
}; };
void FlushPrevious(int translate); void FlushPrevious(int translate);

View file

@ -1,16 +1,5 @@
#include <usb.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include "proxusb.h"
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <strings.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>
#include "prox.h"
#include "proxmark3.h"
#include "flash.h" #include "flash.h"
unsigned int current_command = CMD_UNKNOWN; unsigned int current_command = CMD_UNKNOWN;
@ -19,49 +8,49 @@ extern struct partition partitions[];
static void usage(char **argv) static void usage(char **argv)
{ {
int i; fprintf(stderr, "Usage: %s areas image [image [image]]\n", argv[0]);
fprintf(stderr, "Usage: %s areas image [image [image]]\n", argv[0]); fprintf(stderr, " areas is a comma-separated list of areas to flash, with no spaces\n");
fprintf(stderr, " areas is a comma-separated list of areas to flash, with no spaces\n"); fprintf(stderr, " Known areas are:");
fprintf(stderr, " Known areas are:");
for(i=0; partitions[i].name != NULL; i++) { for (int i = 0; partitions[i].name != NULL; ++i) {
fprintf(stderr, " %s", partitions[i].name); fprintf(stderr, " %s", partitions[i].name);
} }
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fprintf(stderr, " image is the path to the corresponding image\n\n"); fprintf(stderr, " image is the path to the corresponding image\n\n");
fprintf(stderr, "Example: %s os,fpga path/to/osimage.elf path/to/fpgaimage.elf\n", argv[0]); fprintf(stderr, "Example: %s os,fpga path/to/osimage.elf path/to/fpgaimage.elf\n", argv[0]);
} }
int main(int argc, char **argv) { int main(int argc, char **argv)
if(argc < 2) { {
usage(argv); if (argc < 2) {
exit(-1); usage(argv);
} exit(-1);
}
/* Count area arguments */
int areas = 0, offset=-1, length=0;
while(find_next_area(argv[1], &offset, &length)) areas++;
if(areas != argc - 2) {
usage(argv);
exit(-1);
}
usb_init();
fprintf(stderr,"Waiting for Proxmark to appear on USB... "); /* Count area arguments */
while(!(devh=OpenProxmark(0))) { sleep(1); } int areas = 0, offset=-1, length=0;
fprintf(stderr,"Found.\n"); while (find_next_area(argv[1], &offset, &length)) areas++;
do_flash(argv);
UsbCommand c = {CMD_HARDWARE_RESET};
SendCommand(&c);
CloseProxmark(); if (areas != argc - 2) {
usage(argv);
exit(-1);
}
fprintf(stderr,"Have a nice day!\n"); usb_init();
return 0; fprintf(stderr,"Waiting for Proxmark to appear on USB... ");
while (!OpenProxmark(0)) { sleep(1); }
fprintf(stderr,"Found.\n");
do_flash(argv);
UsbCommand c = {CMD_HARDWARE_RESET};
SendCommand(&c);
CloseProxmark();
fprintf(stderr,"Have a nice day!\n");
return 0;
} }

85
client/graph.c Normal file
View file

@ -0,0 +1,85 @@
#include <stdio.h>
#include <string.h>
#include "ui.h"
#include "graph.h"
int GraphBuffer[MAX_GRAPH_TRACE_LEN];
int GraphTraceLen;
/* write a bit to the graph */
void AppendGraph(int redraw, int clock, int bit)
{
int i;
for (i = 0; i < (int)(clock / 2); ++i)
GraphBuffer[GraphTraceLen++] = bit ^ 1;
for (i = (int)(clock / 2); i < clock; ++i)
GraphBuffer[GraphTraceLen++] = bit;
if (redraw)
RepaintGraphWindow();
}
/* clear out our graph window */
int ClearGraph(int redraw)
{
int gtl = GraphTraceLen;
GraphTraceLen = 0;
if (redraw)
RepaintGraphWindow();
return gtl;
}
/*
* Detect clock rate
*/
int DetectClock(int peak)
{
int i;
int clock = 0xFFFF;
int lastpeak = 0;
/* Detect peak if we don't have one */
if (!peak)
for (i = 0; i < GraphTraceLen; ++i)
if (GraphBuffer[i] > peak)
peak = GraphBuffer[i];
for (i = 1; i < GraphTraceLen; ++i)
{
/* If this is the beginning of a peak */
if (GraphBuffer[i - 1] != GraphBuffer[i] && GraphBuffer[i] == peak)
{
/* Find lowest difference between peaks */
if (lastpeak && i - lastpeak < clock)
clock = i - lastpeak;
lastpeak = i;
}
}
return clock;
}
/* Get or auto-detect clock rate */
int GetClock(const char *str, int peak, int verbose)
{
int clock;
sscanf(str, "%i", &clock);
if (!strcmp(str, ""))
clock = 0;
/* Auto-detect clock */
if (!clock)
{
clock = DetectClock(peak);
/* Only print this message if we're not looping something */
if (!verbose)
PrintAndLog("Auto-detected clock rate: %d", clock);
}
return clock;
}

13
client/graph.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef GRAPH_H__
#define GRAPH_H__
void AppendGraph(int redraw, int clock, int bit);
int ClearGraph(int redraw);
int DetectClock(int peak);
int GetClock(const char *str, int peak, int verbose);
#define MAX_GRAPH_TRACE_LEN (1024*128)
extern int GraphBuffer[MAX_GRAPH_TRACE_LEN];
extern int GraphTraceLen;
#endif

View file

@ -1,57 +0,0 @@
#include <stdarg.h>
#include <stdio.h>
#include <time.h>
#include "proxgui.h"
#include "prox.h"
int GraphBuffer[MAX_GRAPH_TRACE_LEN];
int GraphTraceLen;
double CursorScaleFactor;
int PlotGridX, PlotGridY;
int CommandFinished;
int offline;
static char *logfilename = "proxmark3.log";
void PrintToScrollback(char *fmt, ...) {
va_list argptr, argptr2;
static FILE *logfile = NULL;
static int logging=1;
if (logging && !logfile) {
logfile=fopen(logfilename, "a");
if (!logfile) {
fprintf(stderr, "Can't open logfile, logging disabled!\n");
logging=0;
}
}
va_start(argptr, fmt);
va_copy(argptr2, argptr);
vprintf(fmt, argptr);
va_end(argptr);
printf("\n");
if (logging && logfile) {
#if 0
char zeit[25];
time_t jetzt_t;
struct tm *jetzt;
jetzt_t = time(NULL);
jetzt = localtime(&jetzt_t);
strftime(zeit, 25, "%b %e %T", jetzt);
fprintf(logfile,"%s ", zeit);
#endif
vfprintf(logfile, fmt, argptr2);
fprintf(logfile,"\n");
fflush(logfile);
}
va_end(argptr2);
}
void setlogfilename(char *fn)
{
logfilename = fn;
}

View file

@ -1,118 +0,0 @@
#ifndef __PROX_H
#define __PROX_H
#ifdef _MSC_VER
typedef DWORD uint32_t;
typedef BYTE uint8_t;
typedef WORD uint16_t;
#define bool BOOL
#else
#include <stdint.h>
#include <stdbool.h>
#endif
#include "../include/usb_cmd.h"
// prox.cpp
void ReceiveCommand(UsbCommand *c);
bool ReceiveCommandPoll(UsbCommand *c);
void SendCommand(UsbCommand *c);
void WaitForAck(void);
void wait_for_response(uint32_t command_type);
// gui.cpp
void ShowGui(void);
void HideGraphWindow(void);
void ShowGraphWindow(void);
void RepaintGraphWindow(void);
void PrintToScrollback(char *fmt, ...);
#define MAX_GRAPH_TRACE_LEN (1024*128)
extern int GraphBuffer[MAX_GRAPH_TRACE_LEN];
extern int GraphTraceLen;
extern double CursorScaleFactor;
extern int PlotGridX, PlotGridY;
extern int CommandFinished;
extern int offline;
// command.cpp
static void CmdBuffClear(char *str);
static void GetFromBigBuf(uint8_t *dest, int bytes);
static void CmdReset(char *str);
static void CmdQuit(char *str);
static void CmdEM410xread(char *str);
static void CmdEM410xwatch(char *str);
static void ChkBitstream(char *str);
int GetClock(char *str, int peak);
static void CmdHIDdemodFSK(char *str);
static void Cmdmanchestermod(char *str);
static void CmdTune(char *str);
static void CmdHiTune(char *str);
static void CmdHi15read(char *str);
static void CmdHi14read(char *str);
static void CmdSri512read(char *str);
static void CmdHi14areader(char *str);
static void CmdHi15reader(char *str);
static void CmdHi15tag(char *str);
static void CmdHi14read_sim(char *str);
static void CmdHi14readt(char *str);
static void CmdHisimlisten(char *str);
static void CmdReadmem(char *str);
static void CmdHi14sim(char *str);
static void CmdHi14asim(char *str);
static void CmdHi14snoop(char *str);
static void CmdHi14asnoop(char *str);
static void CmdFPGAOff(char *str);
int CmdClearGraph(int redraw);
static void CmdAppendGraph(int redraw, int clock, int bit);
static void CmdEM410xsim(char *str);
static void CmdLosim(char *str);
static void CmdLoCommandRead(char *str);
static void CmdLoread(char *str);
static void CmdLosamples(char *str);
static void CmdBitsamples(char *str);
static void CmdHisamples(char *str);
static int CmdHisamplest(char *str, int nrlow);
static void CmdHexsamples(char *str);
static void CmdHisampless(char *str);
static uint16_t Iso15693Crc(uint8_t *v, int n);
static void CmdHi14bdemod(char *str);
static void CmdHi14list(char *str);
static void CmdHi14alist(char *str);
static void CmdHi15demod(char *str);
static void CmdTiread(char *str);
static void CmdTibits(char *str);
static void CmdTidemod(char *cmdline);
static void CmdNorm(char *str);
static void CmdDec(char *str);
static void CmdHpf(char *str);
static void CmdZerocrossings(char *str);
static void CmdLtrim(char *str);
static void CmdAutoCorr(char *str);
static void CmdVchdemod(char *str);
static void CmdIndalademod(char *str);
static void CmdFlexdemod(char *str);
static void Cmdaskdemod(char *str);
static void Cmddetectclockrate(char *str);
int detectclock(int peak);
static void Cmdbitstream(char *str);
static void Cmdmanchesterdemod(char *str);
static void CmdHiddemod(char *str);
static void CmdPlot(char *str);
static void CmdHide(char *str);
static void CmdScale(char *str);
static void CmdSave(char *str);
static void CmdLoad(char *str);
static void CmdHIDsimTAG(char *str);
static void CmdLcdReset(char *str);
static void CmdLcd(char *str);
static void CmdTest(char *str);
static void CmdSetDivisor(char *str);
static void CmdSweepLF(char *str);
void CommandReceived(char *cmd);
void UsbCommandReceived(UsbCommand *c);
// cmdline.cpp
void ShowCommandline(void);
void ExecCmd(char *cmd);
//void PrintToScrollback(char *fmt, ...);
#endif

View file

@ -5,54 +5,54 @@ static ProxGuiQT *gui = NULL;
extern "C" void ShowGraphWindow(void) extern "C" void ShowGraphWindow(void)
{ {
if (!gui) if (!gui)
return; return;
gui->ShowGraphWindow(); gui->ShowGraphWindow();
} }
extern "C" void HideGraphWindow(void) extern "C" void HideGraphWindow(void)
{ {
if (!gui) if (!gui)
return; return;
gui->HideGraphWindow(); gui->HideGraphWindow();
} }
extern "C" void RepaintGraphWindow(void) extern "C" void RepaintGraphWindow(void)
{ {
if (!gui) if (!gui)
return; return;
gui->RepaintGraphWindow(); gui->RepaintGraphWindow();
} }
extern "C" void MainGraphics(void) extern "C" void MainGraphics(void)
{ {
if (!gui) if (!gui)
return; return;
gui->MainLoop(); gui->MainLoop();
} }
extern "C" void InitGraphics(int argc, char **argv) extern "C" void InitGraphics(int argc, char **argv)
{ {
#ifdef Q_WS_X11 #ifdef Q_WS_X11
bool useGUI = getenv("DISPLAY") != 0; bool useGUI = getenv("DISPLAY") != 0;
#else #else
bool useGUI = true; bool useGUI = true;
#endif #endif
if (!useGUI) if (!useGUI)
return; return;
gui = new ProxGuiQT(argc, argv); gui = new ProxGuiQT(argc, argv);
} }
extern "C" void ExitGraphics(void) extern "C" void ExitGraphics(void)
{ {
if (!gui) if (!gui)
return; return;
delete gui; delete gui;
gui = NULL; gui = NULL;
} }

View file

@ -1,106 +1,100 @@
#include <usb.h>
#include <stdio.h> #include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <pthread.h>
#include <readline/readline.h> #include <readline/readline.h>
#include <readline/history.h> #include <readline/history.h>
#include <pthread.h> #include "proxusb.h"
#include "prox.h"
#include "proxmark3.h" #include "proxmark3.h"
#include "proxgui.h" #include "proxgui.h"
#include "cmdmain.h"
struct usb_receiver_arg { struct usb_receiver_arg
int run; {
int run;
}; };
struct main_loop_arg { struct main_loop_arg
int usb_present; {
int usb_present;
}; };
static void *usb_receiver(void *targ) { static void *usb_receiver(void *targ)
struct usb_receiver_arg *arg = (struct usb_receiver_arg*)targ; {
UsbCommand cmdbuf; struct usb_receiver_arg *arg = (struct usb_receiver_arg*)targ;
UsbCommand cmdbuf;
while(arg->run) { while (arg->run) {
if (ReceiveCommandPoll(&cmdbuf)) { if (ReceiveCommandPoll(&cmdbuf)) {
int i; for (int i = 0; i < strlen(PROXPROMPT); i++)
putchar(0x08);
UsbCommandReceived(&cmdbuf);
printf(PROXPROMPT);
fflush(NULL);
}
}
for (i=0; i<strlen(PROXPROMPT); i++) pthread_exit(NULL);
putchar(0x08);
UsbCommandReceived(&cmdbuf);
printf(PROXPROMPT);
fflush(NULL);
}
}
pthread_exit(NULL);
} }
static void *main_loop(void *targ) static void *main_loop(void *targ)
{ {
struct main_loop_arg *arg = (struct main_loop_arg*)targ; struct main_loop_arg *arg = (struct main_loop_arg*)targ;
struct usb_receiver_arg rarg; struct usb_receiver_arg rarg;
char *cmd = NULL; char *cmd = NULL;
pthread_t reader_thread; pthread_t reader_thread;
if (arg->usb_present == 1) { if (arg->usb_present == 1) {
rarg.run=1; rarg.run=1;
pthread_create(&reader_thread, NULL, &usb_receiver, &rarg); pthread_create(&reader_thread, NULL, &usb_receiver, &rarg);
} }
while(1) { while(1) {
cmd = readline(PROXPROMPT);
if (cmd) {
if (cmd[0] != 0x00) {
CommandReceived(cmd);
add_history(cmd);
}
free(cmd);
} else {
printf("\n");
break;
}
}
cmd = readline(PROXPROMPT); if (arg->usb_present == 1) {
if (cmd) { rarg.run = 0;
if (cmd[0] != 0x00) { pthread_join(reader_thread, NULL);
CommandReceived(cmd); }
add_history(cmd);
}
free(cmd);
} else {
printf("\n");
break;
}
}
if (arg->usb_present == 1) {
rarg.run = 0;
pthread_join(reader_thread, NULL);
}
ExitGraphics(); ExitGraphics();
pthread_exit(NULL); pthread_exit(NULL);
} }
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
struct main_loop_arg marg; struct main_loop_arg marg;
pthread_t main_loop_t; pthread_t main_loop_t;
usb_init(); usb_init();
if (!(devh = OpenProxmark(1))) { if (!OpenProxmark(1)) {
fprintf(stderr,"PROXMARK3: NOT FOUND!\n"); fprintf(stderr,"PROXMARK3: NOT FOUND!\n");
marg.usb_present = 0; marg.usb_present = 0;
offline = 1; offline = 1;
} else { } else {
marg.usb_present = 1; marg.usb_present = 1;
offline = 0; offline = 0;
} }
pthread_create(&main_loop_t, NULL, &main_loop, &marg); pthread_create(&main_loop_t, NULL, &main_loop, &marg);
InitGraphics(argc, argv); InitGraphics(argc, argv);
MainGraphics(); MainGraphics();
pthread_join(main_loop_t, NULL); pthread_join(main_loop_t, NULL);
if (marg.usb_present == 1) { if (marg.usb_present == 1) {
CloseProxmark(); CloseProxmark();
} }
return 0; return 0;
} }

View file

@ -1,14 +1,6 @@
#ifndef PROXMARK3_H__
#define PROXMARK3_H__
#define PROXPROMPT "proxmark3> " #define PROXPROMPT "proxmark3> "
#define FLASH_ADDR_OS 0x10000 #endif
#define FLASH_ADDR_FPGA 0x2000
extern usb_dev_handle *devh;
extern unsigned char return_on_error;
extern unsigned char error_occured;
int ReceiveCommandP(UsbCommand *c);
usb_dev_handle* OpenProxmark(int);
void CloseProxmark(void);
void setlogfilename(char *fn);

169
client/proxusb.c Normal file
View file

@ -0,0 +1,169 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <usb.h>
#include <strings.h>
#include <errno.h>
#include "proxusb.h"
#include "proxmark3.h"
#include "usb_cmd.h"
usb_dev_handle *devh = NULL;
static unsigned int claimed_iface = 0;
unsigned char return_on_error = 0;
unsigned char error_occured = 0;
extern unsigned int current_command;
void SendCommand(UsbCommand *c)
{
int ret;
#if 0
printf("Sending %d bytes\n", sizeof(UsbCommand));
#endif
current_command = c->cmd;
ret = usb_bulk_write(devh, 0x01, (char*)c, sizeof(UsbCommand), 1000);
if (ret<0) {
error_occured = 1;
if (return_on_error)
return;
fprintf(stderr, "write failed: %s!\nTrying to reopen device...\n",
usb_strerror());
if (devh) {
usb_close(devh);
devh = NULL;
}
while(!(devh=OpenProxmark(0))) { sleep(1); }
printf(PROXPROMPT);
fflush(NULL);
return;
}
}
bool ReceiveCommandPoll(UsbCommand *c)
{
int ret;
bzero(c, sizeof(UsbCommand));
ret = usb_bulk_read(devh, 0x82, (char*)c, sizeof(UsbCommand), 500);
if (ret<0) {
if (ret != -ETIMEDOUT) {
error_occured = 1;
if (return_on_error)
return false;
fprintf(stderr, "read failed: %s(%d)!\nTrying to reopen device...\n",
usb_strerror(), ret);
if (devh) {
usb_close(devh);
devh = NULL;
}
while(!(devh=OpenProxmark(0))) { sleep(1); }
printf(PROXPROMPT);
fflush(NULL);
return false;
}
} else {
if (ret && (ret < sizeof(UsbCommand))) {
fprintf(stderr, "Read only %d instead of requested %d bytes!\n",
ret, (int)sizeof(UsbCommand));
}
}
return ret > 0;
}
void ReceiveCommand(UsbCommand *c)
{
// printf("%s()\n", __FUNCTION__);
int retval = 0;
do {
retval = ReceiveCommandPoll(c);
if (retval != 1) printf("ReceiveCommandPoll returned %d\n", retval);
} while(retval<0);
// printf("recv %x\n", c->cmd);
}
usb_dev_handle* findProxmark(int verbose, unsigned int *iface)
{
struct usb_bus *busses, *bus;
usb_dev_handle *handle = NULL;
usb_find_busses();
usb_find_devices();
busses = usb_get_busses();
for (bus = busses; bus; bus = bus->next) {
struct usb_device *dev;
for (dev = bus->devices; dev; dev = dev->next) {
struct usb_device_descriptor *desc = &(dev->descriptor);
if ((desc->idProduct == 0x4b8f) && (desc->idVendor == 0x9ac4)) {
handle = usb_open(dev);
if (!handle) {
if (verbose)
fprintf(stderr, "open failed: %s!\n", usb_strerror());
return NULL;
}
*iface = dev->config[0].interface[0].altsetting[0].bInterfaceNumber;
return handle;
}
}
}
return NULL;
}
usb_dev_handle* OpenProxmark(int verbose)
{
int ret;
usb_dev_handle *handle = NULL;
unsigned int iface;
#ifndef __APPLE__
handle = findProxmark(verbose, &iface);
if (!handle)
return NULL;
/* Whatever... */
usb_reset(handle);
#endif
handle = findProxmark(verbose, &iface);
if (!handle)
return NULL;
#ifndef __APPLE__
/* detach kernel driver first */
ret = usb_detach_kernel_driver_np(handle, iface);
/* don't complain if no driver attached */
if (ret<0 && ret != -61 && verbose)
fprintf(stderr, "detach kernel driver failed: (%d) %s!\n", ret, usb_strerror());
#endif
ret = usb_claim_interface(handle, iface);
if (ret < 0) {
if (verbose)
fprintf(stderr, "claim failed: %s!\n", usb_strerror());
return NULL;
}
claimed_iface = iface;
devh = handle;
return handle;
}
void CloseProxmark(void)
{
usb_release_interface(devh, claimed_iface);
usb_close(devh);
}

27
client/proxusb.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef PROXUSB_H__
#define PROXUSB_H__
#ifdef _MSC_VER
typedef DWORD uint32_t;
typedef BYTE uint8_t;
typedef WORD uint16_t;
#define bool BOOL
#else
#include <stdint.h>
#include <stdbool.h>
#endif
#include <usb.h>
#include "usb_cmd.h"
extern unsigned char return_on_error;
extern unsigned char error_occured;
void SendCommand(UsbCommand *c);
bool ReceiveCommandPoll(UsbCommand *c);
void ReceiveCommand(UsbCommand *c);
usb_dev_handle* FindProxmark(int verbose, unsigned int *iface);
usb_dev_handle* OpenProxmark(int verbose);
usb_dev_handle* OpenProxmark(int verbose);
void CloseProxmark(void);
#endif

View file

@ -1,48 +1,36 @@
#include <usb.h> #include "ui.h"
#include <stdio.h> #include "proxusb.h"
#include <unistd.h> #include "cmdmain.h"
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <errno.h>
#include "prox.h"
#include "proxmark3.h"
#define HANDLE_ERROR if (error_occured) { \ #define HANDLE_ERROR if (error_occured) { \
error_occured = 0;\ error_occured = 0;\
break;\ break;\
} }
int main() int main()
{ {
usb_init(); usb_init();
setlogfilename("snooper.log"); SetLogFilename("snooper.log");
return_on_error = 1; return_on_error = 1;
while(1) { while(1) {
while(!(devh=OpenProxmark(0))) { sleep(1); } while (!OpenProxmark(0)) { sleep(1); }
while (1) {
UsbCommand cmdbuf;
CommandReceived("hi14asnoop");
HANDLE_ERROR;
ReceiveCommand(&cmdbuf);
HANDLE_ERROR;
for (int i = 0; i < 5; ++i) {
ReceiveCommandPoll(&cmdbuf);
}
HANDLE_ERROR;
CommandReceived("hi14alist");
HANDLE_ERROR;
}
}
while(1) { CloseProxmark();
UsbCommand cmdbuf; return 0;
int i;
CommandReceived("hi14asnoop");
HANDLE_ERROR
ReceiveCommand(&cmdbuf);
HANDLE_ERROR
for (i=0; i<5; i++) {
ReceiveCommandPoll(&cmdbuf);
}
HANDLE_ERROR
CommandReceived("hi14alist");
HANDLE_ERROR
}
}
CloseProxmark();
return 0;
} }

View file

@ -1,9 +0,0 @@
#define BYTE unsigned char
#define WORD unsigned short
#define DWORD unsigned int
#define TRUE 1
#define FALSE 0
#define BOOL int
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)>(b))?(b):(a))

54
client/ui.c Normal file
View file

@ -0,0 +1,54 @@
#include <stdarg.h>
#include <stdio.h>
#include <time.h>
#include "ui.h"
double CursorScaleFactor;
int PlotGridX, PlotGridY;
int offline;
static char *logfilename = "proxmark3.log";
void PrintAndLog(char *fmt, ...)
{
va_list argptr, argptr2;
static FILE *logfile = NULL;
static int logging=1;
if (logging && !logfile) {
logfile=fopen(logfilename, "a");
if (!logfile) {
fprintf(stderr, "Can't open logfile, logging disabled!\n");
logging=0;
}
}
va_start(argptr, fmt);
va_copy(argptr2, argptr);
vprintf(fmt, argptr);
va_end(argptr);
printf("\n");
if (logging && logfile) {
#if 0
char zeit[25];
time_t jetzt_t;
struct tm *jetzt;
jetzt_t = time(NULL);
jetzt = localtime(&jetzt_t);
strftime(zeit, 25, "%b %e %T", jetzt);
fprintf(logfile,"%s ", zeit);
#endif
vfprintf(logfile, fmt, argptr2);
fprintf(logfile,"\n");
fflush(logfile);
}
va_end(argptr2);
}
void SetLogFilename(char *fn)
{
logfilename = fn;
}

15
client/ui.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef UI_H__
#define UI_H__
void ShowGui(void);
void HideGraphWindow(void);
void ShowGraphWindow(void);
void RepaintGraphWindow(void);
void PrintAndLog(char *fmt, ...);
void SetLogFilename(char *fn);
extern double CursorScaleFactor;
extern int PlotGridX, PlotGridY;
extern int offline;
#endif

View file

@ -1,163 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <usb.h>
#include <strings.h>
#include <errno.h>
#include "prox.h"
#include "proxmark3.h"
#include "../include/usb_cmd.h"
usb_dev_handle *devh = NULL;
static unsigned int claimed_iface = 0;
unsigned char return_on_error = 0;
unsigned char error_occured = 0;
extern unsigned int current_command;
void SendCommand(UsbCommand *c) {
int ret;
#if 0
printf("Sending %d bytes\n", sizeof(UsbCommand));
#endif
current_command = c->cmd;
ret = usb_bulk_write(devh, 0x01, (char*)c, sizeof(UsbCommand), 1000);
if (ret<0) {
error_occured = 1;
if (return_on_error)
return;
fprintf(stderr, "write failed: %s!\nTrying to reopen device...\n",
usb_strerror());
if (devh) {
usb_close(devh);
devh = NULL;
}
while(!(devh=OpenProxmark(0))) { sleep(1); }
printf(PROXPROMPT);
fflush(NULL);
return;
}
}
bool ReceiveCommandPoll(UsbCommand *c) {
int ret;
bzero(c, sizeof(UsbCommand));
ret = usb_bulk_read(devh, 0x82, (char*)c, sizeof(UsbCommand), 500);
if (ret<0) {
if (ret != -ETIMEDOUT) {
error_occured = 1;
if (return_on_error)
return false;
fprintf(stderr, "read failed: %s(%d)!\nTrying to reopen device...\n",
usb_strerror(), ret);
if (devh) {
usb_close(devh);
devh = NULL;
}
while(!(devh=OpenProxmark(0))) { sleep(1); }
printf(PROXPROMPT);
fflush(NULL);
return false;
}
} else {
if (ret && (ret < sizeof(UsbCommand))) {
fprintf(stderr, "Read only %d instead of requested %d bytes!\n",
ret, (int)sizeof(UsbCommand));
}
}
return ret > 0;
}
void ReceiveCommand(UsbCommand *c) {
// printf("%s()\n", __FUNCTION__);
int retval = 0;
do {
retval = ReceiveCommandPoll(c);
if (retval != 1) printf("ReceiveCommandPoll returned %d\n", retval);
} while(retval<0);
// printf("recv %x\n", c->cmd);
}
usb_dev_handle* findProxmark(int verbose, unsigned int *iface) {
struct usb_bus *busses, *bus;
usb_dev_handle *handle = NULL;
usb_find_busses();
usb_find_devices();
busses = usb_get_busses();
for (bus = busses; bus; bus = bus->next) {
struct usb_device *dev;
for (dev = bus->devices; dev; dev = dev->next) {
struct usb_device_descriptor *desc = &(dev->descriptor);
if ((desc->idProduct == 0x4b8f) && (desc->idVendor == 0x9ac4)) {
handle = usb_open(dev);
if (!handle) {
if (verbose)
fprintf(stderr, "open failed: %s!\n", usb_strerror());
return NULL;
}
*iface = dev->config[0].interface[0].altsetting[0].bInterfaceNumber;
return handle;
}
}
}
return NULL;
}
usb_dev_handle* OpenProxmark(int verbose) {
int ret;
usb_dev_handle *handle = NULL;
unsigned int iface;
#ifndef __APPLE__
handle = findProxmark(verbose, &iface);
if (!handle)
return NULL;
/* Whatever... */
usb_reset(handle);
#endif
handle = findProxmark(verbose, &iface);
if (!handle)
return NULL;
#ifndef __APPLE__
/* detach kernel driver first */
ret = usb_detach_kernel_driver_np(handle, iface);
/* don't complain if no driver attached */
if (ret<0 && ret != -61 && verbose)
fprintf(stderr, "detach kernel driver failed: (%d) %s!\n", ret, usb_strerror());
#endif
ret = usb_claim_interface(handle, iface);
if (ret<0) {
if (verbose)
fprintf(stderr, "claim failed: %s!\n", usb_strerror());
return NULL;
}
claimed_iface = iface;
devh = handle;
return handle;
}
void CloseProxmark(void) {
usb_release_interface(devh, claimed_iface);
usb_close(devh);
}

View file

@ -17,7 +17,7 @@ OBJCOPY = $(CROSS)objcopy
OBJDIR = obj OBJDIR = obj
INCLUDE = -I../include INCLUDE = -I../include -I../common
# Windows' echo echos its input verbatim, on Posix there is some # Windows' echo echos its input verbatim, on Posix there is some
# amount of shell command line parsing going on. echo "" on # amount of shell command line parsing going on. echo "" on
@ -57,7 +57,7 @@ INCLUDES = ../include/proxmark3.h ../include/at91sam7s512.h ../include/config_gp
CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -std=gnu99 $(APP_CFLAGS) CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -std=gnu99 $(APP_CFLAGS)
THUMBOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(THUMBSRC)) THUMBOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(THUMBSRC))
ARMOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(ARMSRC)) ARMOBJ = $(ARMSRC:%.c=$(OBJDIR)/%.o)
ASMOBJ = $(patsubst %.s,$(OBJDIR)/%.o,$(ASMSRC)) ASMOBJ = $(patsubst %.s,$(OBJDIR)/%.o,$(ASMSRC))
VERSIONOBJ = $(OBJDIR)/version.o VERSIONOBJ = $(OBJDIR)/version.o

View file

@ -1,7 +1,10 @@
unsigned short update_crc16( unsigned short crc, unsigned char c ) { #include "crc16.h"
unsigned short i, v, tcrc = 0;
v = (crc ^ c) & 0xff; unsigned short update_crc16( unsigned short crc, unsigned char c )
{
unsigned short i, v, tcrc = 0;
v = (crc ^ c) & 0xff;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
tcrc = ( (tcrc ^ v) & 1 ) ? ( tcrc >> 1 ) ^ 0x8408 : tcrc >> 1; tcrc = ( (tcrc ^ v) & 1 ) ? ( tcrc >> 1 ) ^ 0x8408 : tcrc >> 1;
v >>= 1; v >>= 1;

6
common/crc16.h Normal file
View file

@ -0,0 +1,6 @@
#ifndef CRC16_H__
#define CRC16_H__
unsigned short update_crc16(unsigned short crc, unsigned char c);
#endif

View file

@ -1,35 +0,0 @@
//-----------------------------------------------------------------------------
// Routines to compute the CRCs (two different flavours, just for confusion)
// required for ISO 14443, swiped directly from the spec.
//-----------------------------------------------------------------------------
#define CRC_14443_A 0x6363 /* ITU-V.41 */
#define CRC_14443_B 0xFFFF /* ISO/IEC 13239 (formerly ISO/IEC 3309) */
static unsigned short UpdateCrc14443(unsigned char ch, unsigned short *lpwCrc)
{
ch = (ch ^ (unsigned char) ((*lpwCrc) & 0x00FF));
ch = (ch ^ (ch << 4));
*lpwCrc = (*lpwCrc >> 8) ^ ((unsigned short) ch << 8) ^
((unsigned short) ch << 3) ^ ((unsigned short) ch >> 4);
return (*lpwCrc);
}
static void ComputeCrc14443(int CrcType, unsigned char *Data, int Length,
unsigned char *TransmitFirst, unsigned char *TransmitSecond)
{
unsigned char chBlock;
unsigned short wCrc=CrcType;
do {
chBlock = *Data++;
UpdateCrc14443(chBlock, &wCrc);
} while (--Length);
if (CrcType == CRC_14443_B)
wCrc = ~wCrc; /* ISO/IEC 13239 (formerly ISO/IEC 3309) */
*TransmitFirst = (unsigned char) (wCrc & 0xFF);
*TransmitSecond = (unsigned char) ((wCrc >> 8) & 0xFF);
return;
}

31
common/iso14443crc.c Normal file
View file

@ -0,0 +1,31 @@
#include "iso14443crc.h"
static unsigned short UpdateCrc14443(unsigned char ch, unsigned short *lpwCrc)
{
ch = (ch ^ (unsigned char) ((*lpwCrc) & 0x00FF));
ch = (ch ^ (ch << 4));
*lpwCrc = (*lpwCrc >> 8) ^ ((unsigned short) ch << 8) ^
((unsigned short) ch << 3) ^ ((unsigned short) ch >> 4);
return (*lpwCrc);
}
void ComputeCrc14443(int CrcType,
unsigned char *Data, int Length,
unsigned char *TransmitFirst,
unsigned char *TransmitSecond)
{
unsigned char chBlock;
unsigned short wCrc=CrcType;
do {
chBlock = *Data++;
UpdateCrc14443(chBlock, &wCrc);
} while (--Length);
if (CrcType == CRC_14443_B)
wCrc = ~wCrc; /* ISO/IEC 13239 (formerly ISO/IEC 3309) */
*TransmitFirst = (unsigned char) (wCrc & 0xFF);
*TransmitSecond = (unsigned char) ((wCrc >> 8) & 0xFF);
return;
}

16
common/iso14443crc.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef ISO14443CRC_H__
#define ISO14443CRC_H__
//-----------------------------------------------------------------------------
// Routines to compute the CRCs (two different flavours, just for confusion)
// required for ISO 14443, swiped directly from the spec.
//-----------------------------------------------------------------------------
#define CRC_14443_A 0x6363 /* ITU-V.41 */
#define CRC_14443_B 0xFFFF /* ISO/IEC 13239 (formerly ISO/IEC 3309) */
void ComputeCrc14443(int CrcType,
unsigned char *Data, int Length,
unsigned char *TransmitFirst,
unsigned char *TransmitSecond);
#endif

View file

@ -66,7 +66,6 @@ typedef struct {
// For the 13.56 MHz tags // For the 13.56 MHz tags
#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 0x0300 #define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 0x0300
#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443 0x0301 #define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443 0x0301
#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_14443_SIM 0x0302
#define CMD_READ_SRI512_TAG 0x0303 #define CMD_READ_SRI512_TAG 0x0303
#define CMD_READ_SRIX4K_TAG 0x0304 #define CMD_READ_SRIX4K_TAG 0x0304
#define CMD_READER_ISO_15693 0x0310 #define CMD_READER_ISO_15693 0x0310