mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-07-15 01:33:00 -07:00
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:
parent
6982ac2612
commit
7fe9b0b742
59 changed files with 4306 additions and 3968 deletions
|
@ -24,6 +24,8 @@ THUMBSRC = start.c \
|
|||
# These are to be compiled in ARM mode
|
||||
ARMSRC = fpgaloader.c \
|
||||
legicrf.c \
|
||||
iso14443crc.c \
|
||||
crc16.c \
|
||||
$(SRC_ISO14443a) \
|
||||
$(SRC_ISO14443b) \
|
||||
crc.c
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
#include <proxmark3.h>
|
||||
#include "apps.h"
|
||||
#include "../common/iso14443_crc.c"
|
||||
#include "iso14443crc.h"
|
||||
|
||||
|
||||
//static void GetSamplesFor14443(BOOL weTx, int n);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
#include <proxmark3.h>
|
||||
#include "apps.h"
|
||||
#include "../common/iso14443_crc.c"
|
||||
#include "iso14443crc.h"
|
||||
|
||||
static BYTE *trace = (BYTE *) BigBuf;
|
||||
static int traceLen = 0;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include <proxmark3.h>
|
||||
#include "apps.h"
|
||||
#include "hitag2.h"
|
||||
#include "../common/crc16.c"
|
||||
#include "crc16.h"
|
||||
|
||||
void AcquireRawAdcSamples125k(BOOL at134khz)
|
||||
{
|
||||
|
|
|
@ -1,15 +1,38 @@
|
|||
WINCC=c:\mingw\bin\gcc
|
||||
|
||||
#COMMON_FLAGS = -m32
|
||||
|
||||
VPATH = ../common
|
||||
|
||||
LDLIBS = -L/opt/local/lib -L/usr/local/lib -lusb -lreadline -lpthread
|
||||
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
|
||||
CXXFLAGS = $(shell pkg-config --cflags QtCore QtGui 2>/dev/null) -Wall
|
||||
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 uname),Darwin)
|
||||
|
@ -29,7 +52,7 @@ endif
|
|||
|
||||
RM = rm -f
|
||||
BINS = proxmark3 snooper cli flasher
|
||||
CLEAN = cli flasher proxmark3 snooper *.o *.moc.cpp
|
||||
CLEAN = cli flasher proxmark3 snooper *.o $(CMDOBJS) *.moc.cpp
|
||||
else
|
||||
RM = del
|
||||
BINS = prox.exe
|
||||
|
@ -41,19 +64,17 @@ all: $(BINS)
|
|||
all-static: LDLIBS:=-static $(LDLIBS)
|
||||
all-static: snooper cli flasher
|
||||
|
||||
prox.exe: prox.c wingui.c command.c flash.c
|
||||
$(WINCC) $(CFLAGS) $(DEFINES) -o prox.exe prox.c wingui.c command.c flash.c $(WINLIBS)
|
||||
prox.exe: prox.c wingui.c $(CMDSRCS) flash.c
|
||||
$(WINCC) $(CFLAGS) $(DEFINES) -o prox.exe prox.c wingui.c $(CMDSRCS) flash.c $(WINLIBS)
|
||||
|
||||
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 usb.o
|
||||
flasher: flash.o flasher.o proxusb.o
|
||||
|
||||
proxguiqt.moc.cpp: proxguiqt.h
|
||||
$(MOC) -o$@ $^
|
||||
|
|
85
client/cli.c
85
client/cli.c
|
@ -1,60 +1,49 @@
|
|||
#include <usb.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "prox.h"
|
||||
#include "proxmark3.h"
|
||||
#include "ui.h"
|
||||
#include "proxusb.h"
|
||||
#include "cmdmain.h"
|
||||
|
||||
#define HANDLE_ERROR if (error_occured) { \
|
||||
error_occured = 0;\
|
||||
break;\
|
||||
error_occured = 0;\
|
||||
break;\
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if(argc != 3 && argc != 4)
|
||||
{
|
||||
printf("\n\tusage: cli <command 1> <command 2> [logfile (default cli.log)]\n");
|
||||
printf("\n");
|
||||
printf("\texample: cli hi14asnoop hi14alist h14a.log\n");
|
||||
printf("\n");
|
||||
return -1;
|
||||
}
|
||||
if (argc != 3 && argc != 4)
|
||||
{
|
||||
printf("\n\tusage: cli <command 1> <command 2> [logfile (default cli.log)]\n");
|
||||
printf("\n");
|
||||
printf("\texample: cli hi14asnoop hi14alist h14a.log\n");
|
||||
printf("\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
usb_init();
|
||||
if (argc == 4)
|
||||
setlogfilename(argv[3]);
|
||||
else
|
||||
setlogfilename("cli.log");
|
||||
usb_init();
|
||||
if (argc == 4)
|
||||
SetLogFilename(argv[3]);
|
||||
else
|
||||
SetLogFilename("cli.log");
|
||||
|
||||
return_on_error = 1;
|
||||
return_on_error = 1;
|
||||
|
||||
while(1) {
|
||||
while(!(devh=OpenProxmark(0))) { sleep(1); }
|
||||
while (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) {
|
||||
UsbCommand cmdbuf;
|
||||
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;
|
||||
CloseProxmark();
|
||||
return 0;
|
||||
}
|
||||
|
|
910
client/cmddata.c
Normal file
910
client/cmddata.c
Normal 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
32
client/cmddata.h
Normal 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
41
client/cmdhf.c
Normal 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
8
client/cmdhf.h
Normal 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
200
client/cmdhf14a.c
Normal 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
12
client/cmdhf14a.h
Normal 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
283
client/cmdhf14b.c
Normal 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
15
client/cmdhf14b.h
Normal 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
196
client/cmdhf15.c
Normal 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
11
client/cmdhf15.h
Normal 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
31
client/cmdhflegic.c
Normal 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
8
client/cmdhflegic.h
Normal 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
144
client/cmdhw.c
Normal 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
17
client/cmdhw.h
Normal 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
453
client/cmdlf.c
Normal 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
15
client/cmdlf.h
Normal 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
415
client/cmdlfem4x.c
Normal 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
11
client/cmdlfem4x.h
Normal 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
72
client/cmdlfhid.c
Normal 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
10
client/cmdlfhid.h
Normal 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
293
client/cmdlfti.c
Normal 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
10
client/cmdlfti.h
Normal 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
138
client/cmdmain.c
Normal 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
10
client/cmdmain.h
Normal 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
32
client/cmdparser.c
Normal 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
19
client/cmdparser.h
Normal 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
|
3084
client/command.c
3084
client/command.c
File diff suppressed because it is too large
Load diff
25
client/data.c
Normal file
25
client/data.c
Normal 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
13
client/data.h
Normal 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
|
451
client/flash.c
451
client/flash.c
|
@ -1,26 +1,14 @@
|
|||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
#include <ctype.h>
|
||||
#define bzero(b,len) (memset((b), '\0', (len)), (void) 0)
|
||||
BOOL UsbConnect(void);
|
||||
#else
|
||||
#include <usb.h>
|
||||
#include <proxusb.h>
|
||||
#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"
|
||||
#ifndef WIN32
|
||||
#include "proxmark3.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "flash.h"
|
||||
#include "elf.h"
|
||||
|
||||
|
@ -30,269 +18,268 @@ static bool AllWritten;
|
|||
#define PHYSICAL_FLASH_START 0x100000
|
||||
#define PHYSICAL_FLASH_END 0x200000
|
||||
|
||||
void WaitForAck(void) {
|
||||
UsbCommand ack;
|
||||
ReceiveCommand(&ack);
|
||||
if(ack.cmd != CMD_ACK) {
|
||||
printf("bad ACK\n");
|
||||
exit(-1);
|
||||
}
|
||||
void WaitForAck(void)
|
||||
{
|
||||
UsbCommand ack;
|
||||
ReceiveCommand(&ack);
|
||||
if (ack.cmd != CMD_ACK) {
|
||||
printf("bad ACK\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
struct partition partitions[] = {
|
||||
{0x100000, 0x102000, 1, "bootrom"},
|
||||
{0x102000, 0x110000, 0, "fpga"},
|
||||
{0x110000, 0x140000, 0, "os"},
|
||||
{0, 0, 0, NULL},
|
||||
{0x100000, 0x102000, 1, "bootrom"},
|
||||
{0x102000, 0x110000, 0, "fpga"},
|
||||
{0x110000, 0x140000, 0, "os"},
|
||||
{0, 0, 0, NULL},
|
||||
};
|
||||
|
||||
void WriteBlock(unsigned int block_start, unsigned int len, unsigned char *buf)
|
||||
{
|
||||
unsigned char temp_buf[256];
|
||||
if (block_start & 0xFF) {
|
||||
printf("moving stuff forward by %d bytes\n", block_start & 0xFF);
|
||||
memset(temp_buf, 0xFF, block_start & 0xFF);
|
||||
memcpy(temp_buf + (block_start & 0xFF), buf, len - (block_start & 0xFF));
|
||||
block_start &= ~0xFF;
|
||||
} else {
|
||||
memcpy(temp_buf, buf, len);
|
||||
}
|
||||
|
||||
UsbCommand c = {CMD_SETUP_WRITE};
|
||||
unsigned char temp_buf[256];
|
||||
if (block_start & 0xFF) {
|
||||
printf("moving stuff forward by %d bytes\n", block_start & 0xFF);
|
||||
memset(temp_buf, 0xFF, block_start & 0xFF);
|
||||
memcpy(temp_buf + (block_start & 0xFF), buf, len - (block_start & 0xFF));
|
||||
block_start &= ~0xFF;
|
||||
} else {
|
||||
memcpy(temp_buf, buf, len);
|
||||
}
|
||||
|
||||
int i;
|
||||
for(i = 0; i < 240; i += 48) {
|
||||
memcpy(c.d.asBytes, temp_buf+i, 48);
|
||||
c.arg[0] = (i/4);
|
||||
SendCommand(&c);
|
||||
WaitForAck();
|
||||
}
|
||||
UsbCommand c = {CMD_SETUP_WRITE};
|
||||
|
||||
c.cmd = CMD_FINISH_WRITE;
|
||||
c.arg[0] = block_start;
|
||||
for (int i = 0; i < 240; i += 48) {
|
||||
memcpy(c.d.asBytes, temp_buf+i, 48);
|
||||
c.arg[0] = (i/4);
|
||||
SendCommand(&c);
|
||||
WaitForAck();
|
||||
}
|
||||
|
||||
// printf("writing block %08x\r", c.arg[0]);
|
||||
memcpy(c.d.asBytes, temp_buf+240, 16);
|
||||
SendCommand(&c);
|
||||
WaitForAck();
|
||||
c.cmd = CMD_FINISH_WRITE;
|
||||
c.arg[0] = block_start;
|
||||
|
||||
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)
|
||||
{
|
||||
FILE *f = fopen(file, "rb");
|
||||
if(!f) {
|
||||
printf("couldn't open file\n");
|
||||
exit(-1);
|
||||
}
|
||||
FILE *f = fopen(file, "rb");
|
||||
if (!f) {
|
||||
printf("couldn't open file\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
char buf[4];
|
||||
fread(buf, 1, 4, f);
|
||||
if (memcmp(buf, "\x7F" "ELF", 4) == 0) {
|
||||
int i;
|
||||
fseek(f, 0, SEEK_SET);
|
||||
Elf32_Ehdr header;
|
||||
fread(&header, 1, sizeof(header), f);
|
||||
int count = header.e_phnum;
|
||||
printf("count=%d phoff=%x\n", count, header.e_phoff);
|
||||
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;
|
||||
}
|
||||
char buf[4];
|
||||
fread(buf, 1, 4, f);
|
||||
if (memcmp(buf, "\x7F" "ELF", 4) == 0) {
|
||||
fseek(f, 0, SEEK_SET);
|
||||
Elf32_Ehdr header;
|
||||
fread(&header, 1, sizeof(header), f);
|
||||
int count = header.e_phnum;
|
||||
printf("count=%d phoff=%x\n", count, header.e_phoff);
|
||||
Elf32_Phdr phdr;
|
||||
|
||||
fseek(f, phdr.p_offset, SEEK_SET);
|
||||
ExpectedAddr = phdr.p_paddr;
|
||||
while (ExpectedAddr < (phdr.p_paddr + phdr.p_filesz)) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
for (int 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;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
printf("\ndone.\n");
|
||||
return;
|
||||
} else printf("Bad file format\n");
|
||||
fseek(f, phdr.p_offset, SEEK_SET);
|
||||
ExpectedAddr = phdr.p_paddr;
|
||||
while (ExpectedAddr < (phdr.p_paddr + phdr.p_filesz)) {
|
||||
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)
|
||||
{
|
||||
if(state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) {
|
||||
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;
|
||||
if (state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) {
|
||||
UsbCommand c = {CMD_START_FLASH, {p->start, p->end, 0}};
|
||||
|
||||
SendCommand(&c);
|
||||
WaitForAck();
|
||||
} else {
|
||||
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;
|
||||
/* Only send magic when flashing bootrom */
|
||||
if (p->precious)
|
||||
c.arg[2] = START_FLASH_MAGIC;
|
||||
else
|
||||
c.arg[2] = 0;
|
||||
|
||||
SendCommand(&c);
|
||||
WaitForAck();
|
||||
} else {
|
||||
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 state = 0;
|
||||
|
||||
UsbCommand c;
|
||||
c.cmd = CMD_DEVICE_INFO;
|
||||
SendCommand(&c);
|
||||
|
||||
UsbCommand resp;
|
||||
ReceiveCommand(&resp);
|
||||
/* Three cases:
|
||||
* 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"
|
||||
* 3. The new bootrom and os codes will respond with CMD_DEVICE_INFO and flags
|
||||
*/
|
||||
|
||||
switch(resp.cmd) {
|
||||
case CMD_ACK:
|
||||
state = DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM;
|
||||
break;
|
||||
case CMD_DEBUG_PRINT_STRING:
|
||||
state = DEVICE_INFO_FLAG_CURRENT_MODE_OS;
|
||||
break;
|
||||
case CMD_DEVICE_INFO:
|
||||
state = resp.arg[0];
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Couldn't get proxmark state, bad response type: 0x%04X\n", resp.cmd);
|
||||
exit(-1);
|
||||
break;
|
||||
}
|
||||
|
||||
return state;
|
||||
unsigned int state = 0;
|
||||
|
||||
UsbCommand c;
|
||||
c.cmd = CMD_DEVICE_INFO;
|
||||
SendCommand(&c);
|
||||
|
||||
UsbCommand resp;
|
||||
ReceiveCommand(&resp);
|
||||
/* Three cases:
|
||||
* 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"
|
||||
* 3. The new bootrom and os codes will respond with CMD_DEVICE_INFO and flags
|
||||
*/
|
||||
|
||||
switch (resp.cmd) {
|
||||
case CMD_ACK:
|
||||
state = DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM;
|
||||
break;
|
||||
case CMD_DEBUG_PRINT_STRING:
|
||||
state = DEVICE_INFO_FLAG_CURRENT_MODE_OS;
|
||||
break;
|
||||
case CMD_DEVICE_INFO:
|
||||
state = resp.arg[0];
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Couldn't get proxmark state, bad response type: 0x%04X\n", resp.cmd);
|
||||
exit(-1);
|
||||
break;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
unsigned int EnterFlashState(void)
|
||||
{
|
||||
unsigned int state = GetProxmarkState();
|
||||
|
||||
if(state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM) {
|
||||
/* Already in flash state, we're done. */
|
||||
return state;
|
||||
}
|
||||
|
||||
if(state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) {
|
||||
fprintf(stderr,"Entering flash-mode...\n");
|
||||
UsbCommand c;
|
||||
bzero(&c, sizeof(c));
|
||||
|
||||
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
|
||||
* enter the bootrom on the next boot.
|
||||
*/
|
||||
c.cmd = CMD_START_FLASH;
|
||||
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,"Waiting for Proxmark to reappear on USB... ");
|
||||
} else {
|
||||
/* Old style handover: Ask the user to press the button, then reset the board */
|
||||
c.cmd = CMD_HARDWARE_RESET;
|
||||
SendCommand(&c);
|
||||
fprintf(stderr,"(Press and hold down button NOW if your bootloader requires it)\n");
|
||||
fprintf(stderr,"Waiting for Proxmark to reappear on USB... ");
|
||||
}
|
||||
unsigned int state = GetProxmarkState();
|
||||
|
||||
if (state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM) {
|
||||
/* Already in flash state, we're done. */
|
||||
return state;
|
||||
}
|
||||
|
||||
if (state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) {
|
||||
fprintf(stderr,"Entering flash-mode...\n");
|
||||
UsbCommand c;
|
||||
bzero(&c, sizeof(c));
|
||||
|
||||
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
|
||||
* enter the bootrom on the next boot.
|
||||
*/
|
||||
c.cmd = CMD_START_FLASH;
|
||||
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,"Waiting for Proxmark to reappear on USB... ");
|
||||
} else {
|
||||
/* Old style handover: Ask the user to press the button, then reset the board */
|
||||
c.cmd = CMD_HARDWARE_RESET;
|
||||
SendCommand(&c);
|
||||
fprintf(stderr,"(Press and hold down button NOW if your bootloader requires it)\n");
|
||||
fprintf(stderr,"Waiting for Proxmark to reappear on USB... ");
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
Sleep(1000);
|
||||
while(!UsbConnect()) { Sleep(1000); }
|
||||
Sleep(1000);
|
||||
while (!UsbConnect()) { Sleep(1000); }
|
||||
#else
|
||||
CloseProxmark();
|
||||
sleep(1);
|
||||
CloseProxmark();
|
||||
sleep(1);
|
||||
|
||||
while(!(devh=OpenProxmark(0))) { sleep(1); }
|
||||
while (!OpenProxmark(0)) { sleep(1); }
|
||||
#endif
|
||||
fprintf(stderr,"Found.\n");
|
||||
fprintf(stderr,"Found.\n");
|
||||
|
||||
return GetProxmarkState();
|
||||
}
|
||||
|
||||
return 0;
|
||||
return GetProxmarkState();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* On first call, have *offset = -1, *length = 0; */
|
||||
int find_next_area(const char *str, int *offset, int *length)
|
||||
{
|
||||
if(*str == '\0') return 0;
|
||||
if((*offset >= 0) && str[*offset + *length] == '\0') return 0;
|
||||
*offset += 1 + *length;
|
||||
|
||||
char *next_comma = strchr(str + *offset, ',');
|
||||
if(next_comma == NULL) {
|
||||
*length = strlen(str) - *offset;
|
||||
} else {
|
||||
*length = next_comma-(str+*offset);
|
||||
}
|
||||
return 1;
|
||||
if (*str == '\0') return 0;
|
||||
if ((*offset >= 0) && str[*offset + *length] == '\0') return 0;
|
||||
*offset += 1 + *length;
|
||||
|
||||
char *next_comma = strchr(str + *offset, ',');
|
||||
if (next_comma == NULL) {
|
||||
*length = strlen(str) - *offset;
|
||||
} else {
|
||||
*length = next_comma-(str+*offset);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void do_flash(char **argv) {
|
||||
unsigned int state = EnterFlashState();
|
||||
void do_flash(char **argv)
|
||||
{
|
||||
unsigned int state = EnterFlashState();
|
||||
|
||||
if (!(state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM)) {
|
||||
fprintf(stderr, "Proxmark would not enter flash state, abort\n");
|
||||
exit(-1);
|
||||
}
|
||||
if (!(state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM)) {
|
||||
fprintf(stderr, "Proxmark would not enter flash state, abort\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
int offset=-1, length=0;
|
||||
int current_area = 0;
|
||||
while(find_next_area(argv[1], &offset, &length)) {
|
||||
int i;
|
||||
struct partition *p = NULL;
|
||||
for (i=0; i<sizeof(partitions)/sizeof(partitions[0]); i++) {
|
||||
if (strncmp(partitions[i].name, argv[1] + offset, length) == 0) {
|
||||
/* Check if the name matches the bootrom partition, and if so, require "bootrom" to
|
||||
* be written in full. The other names may be abbreviated.
|
||||
*/
|
||||
if(!partitions[i].precious || (strlen(partitions[i].name) == length))
|
||||
p = &partitions[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
int offset=-1, length=0;
|
||||
int current_area = 0;
|
||||
while (find_next_area(argv[1], &offset, &length)) {
|
||||
struct partition *p = NULL;
|
||||
for (int i = 0; i<sizeof(partitions)/sizeof(partitions[0]); ++i) {
|
||||
if (strncmp(partitions[i].name, argv[1] + offset, length) == 0) {
|
||||
/* Check if the name matches the bootrom partition, and if so, require "bootrom" to
|
||||
* be written in full. The other names may be abbreviated.
|
||||
*/
|
||||
if(!partitions[i].precious || (strlen(partitions[i].name) == length))
|
||||
p = &partitions[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(p == NULL) {
|
||||
fprintf(stderr, "Warning: area name '");
|
||||
fwrite(argv[1]+offset, length, 1, stderr);
|
||||
fprintf(stderr, "' unknown, ignored\n");
|
||||
} else {
|
||||
fprintf(stderr, "Flashing %s from %s\n", p->name, argv[2+current_area]);
|
||||
PrepareFlash(p, argv[2+current_area], state);
|
||||
}
|
||||
current_area++;
|
||||
}
|
||||
if (p == NULL) {
|
||||
fprintf(stderr, "Warning: area name '");
|
||||
fwrite(argv[1]+offset, length, 1, stderr);
|
||||
fprintf(stderr, "' unknown, ignored\n");
|
||||
} else {
|
||||
fprintf(stderr, "Flashing %s from %s\n", p->name, argv[2+current_area]);
|
||||
PrepareFlash(p, argv[2+current_area], state);
|
||||
}
|
||||
current_area++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,10 @@
|
|||
#define __FLASH_H__
|
||||
|
||||
struct partition {
|
||||
int start;
|
||||
int end;
|
||||
int precious;
|
||||
const char *name;
|
||||
int start;
|
||||
int end;
|
||||
int precious;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
void FlushPrevious(int translate);
|
||||
|
|
|
@ -1,16 +1,5 @@
|
|||
#include <usb.h>
|
||||
#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 "proxmark3.h"
|
||||
#include "proxusb.h"
|
||||
#include "flash.h"
|
||||
|
||||
unsigned int current_command = CMD_UNKNOWN;
|
||||
|
@ -19,49 +8,49 @@ extern struct partition partitions[];
|
|||
|
||||
static void usage(char **argv)
|
||||
{
|
||||
int i;
|
||||
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, " Known areas are:");
|
||||
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, " Known areas are:");
|
||||
|
||||
for(i=0; partitions[i].name != NULL; i++) {
|
||||
fprintf(stderr, " %s", partitions[i].name);
|
||||
}
|
||||
for (int i = 0; partitions[i].name != NULL; ++i) {
|
||||
fprintf(stderr, " %s", partitions[i].name);
|
||||
}
|
||||
|
||||
fprintf(stderr, "\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, "\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]);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if(argc < 2) {
|
||||
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();
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 2) {
|
||||
usage(argv);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
fprintf(stderr,"Waiting for Proxmark to appear on USB... ");
|
||||
while(!(devh=OpenProxmark(0))) { sleep(1); }
|
||||
fprintf(stderr,"Found.\n");
|
||||
|
||||
do_flash(argv);
|
||||
|
||||
UsbCommand c = {CMD_HARDWARE_RESET};
|
||||
SendCommand(&c);
|
||||
/* Count area arguments */
|
||||
int areas = 0, offset=-1, length=0;
|
||||
while (find_next_area(argv[1], &offset, &length)) areas++;
|
||||
|
||||
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
85
client/graph.c
Normal 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
13
client/graph.h
Normal 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
|
57
client/gui.c
57
client/gui.c
|
@ -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;
|
||||
}
|
118
client/prox.h
118
client/prox.h
|
@ -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
|
|
@ -5,54 +5,54 @@ static ProxGuiQT *gui = NULL;
|
|||
|
||||
extern "C" void ShowGraphWindow(void)
|
||||
{
|
||||
if (!gui)
|
||||
return;
|
||||
|
||||
gui->ShowGraphWindow();
|
||||
if (!gui)
|
||||
return;
|
||||
|
||||
gui->ShowGraphWindow();
|
||||
}
|
||||
|
||||
extern "C" void HideGraphWindow(void)
|
||||
{
|
||||
if (!gui)
|
||||
return;
|
||||
|
||||
gui->HideGraphWindow();
|
||||
if (!gui)
|
||||
return;
|
||||
|
||||
gui->HideGraphWindow();
|
||||
}
|
||||
|
||||
extern "C" void RepaintGraphWindow(void)
|
||||
{
|
||||
if (!gui)
|
||||
return;
|
||||
if (!gui)
|
||||
return;
|
||||
|
||||
gui->RepaintGraphWindow();
|
||||
gui->RepaintGraphWindow();
|
||||
}
|
||||
|
||||
extern "C" void MainGraphics(void)
|
||||
{
|
||||
if (!gui)
|
||||
return;
|
||||
if (!gui)
|
||||
return;
|
||||
|
||||
gui->MainLoop();
|
||||
gui->MainLoop();
|
||||
}
|
||||
|
||||
extern "C" void InitGraphics(int argc, char **argv)
|
||||
{
|
||||
#ifdef Q_WS_X11
|
||||
bool useGUI = getenv("DISPLAY") != 0;
|
||||
bool useGUI = getenv("DISPLAY") != 0;
|
||||
#else
|
||||
bool useGUI = true;
|
||||
bool useGUI = true;
|
||||
#endif
|
||||
if (!useGUI)
|
||||
return;
|
||||
if (!useGUI)
|
||||
return;
|
||||
|
||||
gui = new ProxGuiQT(argc, argv);
|
||||
gui = new ProxGuiQT(argc, argv);
|
||||
}
|
||||
|
||||
extern "C" void ExitGraphics(void)
|
||||
{
|
||||
if (!gui)
|
||||
return;
|
||||
|
||||
delete gui;
|
||||
gui = NULL;
|
||||
if (!gui)
|
||||
return;
|
||||
|
||||
delete gui;
|
||||
gui = NULL;
|
||||
}
|
||||
|
|
|
@ -1,106 +1,100 @@
|
|||
#include <usb.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <readline/readline.h>
|
||||
#include <readline/history.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "prox.h"
|
||||
#include "proxusb.h"
|
||||
#include "proxmark3.h"
|
||||
#include "proxgui.h"
|
||||
#include "cmdmain.h"
|
||||
|
||||
struct usb_receiver_arg {
|
||||
int run;
|
||||
struct usb_receiver_arg
|
||||
{
|
||||
int run;
|
||||
};
|
||||
|
||||
struct main_loop_arg {
|
||||
int usb_present;
|
||||
struct main_loop_arg
|
||||
{
|
||||
int usb_present;
|
||||
};
|
||||
|
||||
static void *usb_receiver(void *targ) {
|
||||
struct usb_receiver_arg *arg = (struct usb_receiver_arg*)targ;
|
||||
UsbCommand cmdbuf;
|
||||
static void *usb_receiver(void *targ)
|
||||
{
|
||||
struct usb_receiver_arg *arg = (struct usb_receiver_arg*)targ;
|
||||
UsbCommand cmdbuf;
|
||||
|
||||
while(arg->run) {
|
||||
if (ReceiveCommandPoll(&cmdbuf)) {
|
||||
int i;
|
||||
while (arg->run) {
|
||||
if (ReceiveCommandPoll(&cmdbuf)) {
|
||||
for (int i = 0; i < strlen(PROXPROMPT); i++)
|
||||
putchar(0x08);
|
||||
UsbCommandReceived(&cmdbuf);
|
||||
printf(PROXPROMPT);
|
||||
fflush(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<strlen(PROXPROMPT); i++)
|
||||
putchar(0x08);
|
||||
|
||||
UsbCommandReceived(&cmdbuf);
|
||||
printf(PROXPROMPT);
|
||||
fflush(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
pthread_exit(NULL);
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
static void *main_loop(void *targ)
|
||||
{
|
||||
struct main_loop_arg *arg = (struct main_loop_arg*)targ;
|
||||
struct usb_receiver_arg rarg;
|
||||
char *cmd = NULL;
|
||||
pthread_t reader_thread;
|
||||
struct main_loop_arg *arg = (struct main_loop_arg*)targ;
|
||||
struct usb_receiver_arg rarg;
|
||||
char *cmd = NULL;
|
||||
pthread_t reader_thread;
|
||||
|
||||
if (arg->usb_present == 1) {
|
||||
rarg.run=1;
|
||||
pthread_create(&reader_thread, NULL, &usb_receiver, &rarg);
|
||||
}
|
||||
if (arg->usb_present == 1) {
|
||||
rarg.run=1;
|
||||
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 (cmd) {
|
||||
if (cmd[0] != 0x00) {
|
||||
CommandReceived(cmd);
|
||||
add_history(cmd);
|
||||
}
|
||||
free(cmd);
|
||||
} else {
|
||||
printf("\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (arg->usb_present == 1) {
|
||||
rarg.run = 0;
|
||||
pthread_join(reader_thread, NULL);
|
||||
}
|
||||
if (arg->usb_present == 1) {
|
||||
rarg.run = 0;
|
||||
pthread_join(reader_thread, NULL);
|
||||
}
|
||||
|
||||
ExitGraphics();
|
||||
pthread_exit(NULL);
|
||||
ExitGraphics();
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct main_loop_arg marg;
|
||||
pthread_t main_loop_t;
|
||||
usb_init();
|
||||
struct main_loop_arg marg;
|
||||
pthread_t main_loop_t;
|
||||
usb_init();
|
||||
|
||||
if (!(devh = OpenProxmark(1))) {
|
||||
fprintf(stderr,"PROXMARK3: NOT FOUND!\n");
|
||||
marg.usb_present = 0;
|
||||
offline = 1;
|
||||
} else {
|
||||
marg.usb_present = 1;
|
||||
offline = 0;
|
||||
}
|
||||
if (!OpenProxmark(1)) {
|
||||
fprintf(stderr,"PROXMARK3: NOT FOUND!\n");
|
||||
marg.usb_present = 0;
|
||||
offline = 1;
|
||||
} else {
|
||||
marg.usb_present = 1;
|
||||
offline = 0;
|
||||
}
|
||||
|
||||
pthread_create(&main_loop_t, NULL, &main_loop, &marg);
|
||||
InitGraphics(argc, argv);
|
||||
pthread_create(&main_loop_t, NULL, &main_loop, &marg);
|
||||
InitGraphics(argc, argv);
|
||||
|
||||
MainGraphics();
|
||||
MainGraphics();
|
||||
|
||||
pthread_join(main_loop_t, NULL);
|
||||
pthread_join(main_loop_t, NULL);
|
||||
|
||||
if (marg.usb_present == 1) {
|
||||
CloseProxmark();
|
||||
}
|
||||
return 0;
|
||||
if (marg.usb_present == 1) {
|
||||
CloseProxmark();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
#ifndef PROXMARK3_H__
|
||||
#define PROXMARK3_H__
|
||||
|
||||
#define PROXPROMPT "proxmark3> "
|
||||
|
||||
#define FLASH_ADDR_OS 0x10000
|
||||
#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);
|
||||
#endif
|
169
client/proxusb.c
Normal file
169
client/proxusb.c
Normal 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
27
client/proxusb.h
Normal 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
|
|
@ -1,48 +1,36 @@
|
|||
#include <usb.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "prox.h"
|
||||
#include "proxmark3.h"
|
||||
#include "ui.h"
|
||||
#include "proxusb.h"
|
||||
#include "cmdmain.h"
|
||||
|
||||
#define HANDLE_ERROR if (error_occured) { \
|
||||
error_occured = 0;\
|
||||
break;\
|
||||
error_occured = 0;\
|
||||
break;\
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
usb_init();
|
||||
setlogfilename("snooper.log");
|
||||
usb_init();
|
||||
SetLogFilename("snooper.log");
|
||||
|
||||
return_on_error = 1;
|
||||
return_on_error = 1;
|
||||
|
||||
while(1) {
|
||||
while(!(devh=OpenProxmark(0))) { sleep(1); }
|
||||
while(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) {
|
||||
UsbCommand cmdbuf;
|
||||
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;
|
||||
CloseProxmark();
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -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
54
client/ui.c
Normal 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
15
client/ui.h
Normal 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
|
163
client/usb.c
163
client/usb.c
|
@ -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);
|
||||
}
|
|
@ -17,7 +17,7 @@ OBJCOPY = $(CROSS)objcopy
|
|||
|
||||
OBJDIR = obj
|
||||
|
||||
INCLUDE = -I../include
|
||||
INCLUDE = -I../include -I../common
|
||||
|
||||
# Windows' echo echos its input verbatim, on Posix there is some
|
||||
# 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)
|
||||
|
||||
THUMBOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(THUMBSRC))
|
||||
ARMOBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(ARMSRC))
|
||||
ARMOBJ = $(ARMSRC:%.c=$(OBJDIR)/%.o)
|
||||
ASMOBJ = $(patsubst %.s,$(OBJDIR)/%.o,$(ASMSRC))
|
||||
VERSIONOBJ = $(OBJDIR)/version.o
|
||||
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
unsigned short update_crc16( unsigned short crc, unsigned char c ) {
|
||||
unsigned short i, v, tcrc = 0;
|
||||
#include "crc16.h"
|
||||
|
||||
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++) {
|
||||
tcrc = ( (tcrc ^ v) & 1 ) ? ( tcrc >> 1 ) ^ 0x8408 : tcrc >> 1;
|
||||
v >>= 1;
|
||||
|
|
6
common/crc16.h
Normal file
6
common/crc16.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef CRC16_H__
|
||||
#define CRC16_H__
|
||||
|
||||
unsigned short update_crc16(unsigned short crc, unsigned char c);
|
||||
|
||||
#endif
|
|
@ -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
31
common/iso14443crc.c
Normal 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
16
common/iso14443crc.h
Normal 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
|
|
@ -66,7 +66,6 @@ typedef struct {
|
|||
// For the 13.56 MHz tags
|
||||
#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_SIM 0x0302
|
||||
#define CMD_READ_SRI512_TAG 0x0303
|
||||
#define CMD_READ_SRIX4K_TAG 0x0304
|
||||
#define CMD_READER_ISO_15693 0x0310
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue