mirror of
https://github.com/Proxmark/proxmark3.git
synced 2024-09-21 07:16:24 +08:00
small improvements, added new command hf mf sniff
(there will be cool sniffer). But now... here is optimized hf 14a snoop. As I see it works the same as th old version.
This commit is contained in:
parent
ac14bee321
commit
b62a5a8444
|
@ -16,7 +16,7 @@ APP_CFLAGS = -O2 -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DW
|
|||
#SRC_LCD = fonts.c LCD.c
|
||||
SRC_LF = lfops.c hitag2.c
|
||||
SRC_ISO15693 = iso15693.c iso15693tools.c
|
||||
SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c
|
||||
SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c mifaresniff.c
|
||||
SRC_ISO14443b = iso14443.c
|
||||
SRC_CRAPTO1 = crapto1.c crypto1.c
|
||||
|
||||
|
|
|
@ -761,6 +761,11 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
|||
case CMD_MIFARE_EML_CGETBLOCK:
|
||||
MifareCGetBlock(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
|
||||
break;
|
||||
|
||||
// mifare sniffer
|
||||
case CMD_MIFARE_SNIFFER:
|
||||
SniffMifare();
|
||||
break;
|
||||
#endif
|
||||
|
||||
#ifdef WITH_ICLASS
|
||||
|
|
|
@ -135,6 +135,7 @@ uint32_t GetParity(const uint8_t * pbtCmd, int iLen);
|
|||
void iso14a_set_trigger(int enable);
|
||||
void iso14a_clear_tracelen(void);
|
||||
void iso14a_set_tracing(int enable);
|
||||
void RAMFUNC SniffMifare(void);
|
||||
|
||||
// mifarecmd.h
|
||||
void ReaderMifare(uint32_t parameter);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Merlok - June 2011
|
||||
// Merlok - June 2011, 2012
|
||||
// Gerhard de Koning Gans - May 2008
|
||||
// Hagen Fritsch - June 2010
|
||||
//
|
||||
|
@ -129,32 +129,7 @@ int LogTrace(const uint8_t * btBytes, int iLen, int iSamples, uint32_t dwParity,
|
|||
// The software UART that receives commands from the reader, and its state
|
||||
// variables.
|
||||
//-----------------------------------------------------------------------------
|
||||
static struct {
|
||||
enum {
|
||||
STATE_UNSYNCD,
|
||||
STATE_START_OF_COMMUNICATION,
|
||||
STATE_MILLER_X,
|
||||
STATE_MILLER_Y,
|
||||
STATE_MILLER_Z,
|
||||
STATE_ERROR_WAIT
|
||||
} state;
|
||||
uint16_t shiftReg;
|
||||
int bitCnt;
|
||||
int byteCnt;
|
||||
int byteCntMax;
|
||||
int posCnt;
|
||||
int syncBit;
|
||||
int parityBits;
|
||||
int samples;
|
||||
int highCnt;
|
||||
int bitBuffer;
|
||||
enum {
|
||||
DROP_NONE,
|
||||
DROP_FIRST_HALF,
|
||||
DROP_SECOND_HALF
|
||||
} drop;
|
||||
uint8_t *output;
|
||||
} Uart;
|
||||
static tUart Uart;
|
||||
|
||||
static RAMFUNC int MillerDecoding(int bit)
|
||||
{
|
||||
|
@ -393,32 +368,7 @@ static RAMFUNC int MillerDecoding(int bit)
|
|||
//=============================================================================
|
||||
// ISO 14443 Type A - Manchester
|
||||
//=============================================================================
|
||||
|
||||
static struct {
|
||||
enum {
|
||||
DEMOD_UNSYNCD,
|
||||
DEMOD_START_OF_COMMUNICATION,
|
||||
DEMOD_MANCHESTER_D,
|
||||
DEMOD_MANCHESTER_E,
|
||||
DEMOD_MANCHESTER_F,
|
||||
DEMOD_ERROR_WAIT
|
||||
} state;
|
||||
int bitCount;
|
||||
int posCount;
|
||||
int syncBit;
|
||||
int parityBits;
|
||||
uint16_t shiftReg;
|
||||
int buffer;
|
||||
int buff;
|
||||
int samples;
|
||||
int len;
|
||||
enum {
|
||||
SUB_NONE,
|
||||
SUB_FIRST_HALF,
|
||||
SUB_SECOND_HALF
|
||||
} sub;
|
||||
uint8_t *output;
|
||||
} Demod;
|
||||
static tDemod Demod;
|
||||
|
||||
static RAMFUNC int ManchesterDecoding(int v)
|
||||
{
|
||||
|
@ -2402,9 +2352,7 @@ lbWORK: if (len == 0) break;
|
|||
cardSTATE = MFEMUL_WORK;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
|
@ -2416,3 +2364,132 @@ lbWORK: if (len == 0) break;
|
|||
|
||||
if (MF_DBGLEVEL >= 1) Dbprintf("Emulator stopped. Tracing: %d trace length: %d ", tracing, traceLen);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// MIFARE sniffer.
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
void RAMFUNC SniffMifare(void) {
|
||||
LEDsoff();
|
||||
// init trace buffer
|
||||
traceLen = 0;
|
||||
memset(trace, 0x44, TRACE_SIZE);
|
||||
|
||||
// We won't start recording the frames that we acquire until we trigger;
|
||||
// a good trigger condition to get started is probably when we see a
|
||||
// response from the tag.
|
||||
int triggered = FALSE; // FALSE to wait first for card
|
||||
|
||||
// The command (reader -> tag) that we're receiving.
|
||||
// The length of a received command will in most cases be no more than 18 bytes.
|
||||
// So 32 should be enough!
|
||||
uint8_t *receivedCmd = (((uint8_t *)BigBuf) + RECV_CMD_OFFSET);
|
||||
// The response (tag -> reader) that we're receiving.
|
||||
uint8_t *receivedResponse = (((uint8_t *)BigBuf) + RECV_RES_OFFSET);
|
||||
|
||||
// As we receive stuff, we copy it from receivedCmd or receivedResponse
|
||||
// into trace, along with its length and other annotations.
|
||||
//uint8_t *trace = (uint8_t *)BigBuf;
|
||||
|
||||
// The DMA buffer, used to stream samples from the FPGA
|
||||
int8_t *dmaBuf = ((int8_t *)BigBuf) + DMA_BUFFER_OFFSET;
|
||||
int lastRxCounter;
|
||||
int8_t *upTo;
|
||||
int smpl;
|
||||
int maxBehindBy = 0;
|
||||
|
||||
// Set up the demodulator for tag -> reader responses.
|
||||
Demod.output = receivedResponse;
|
||||
Demod.len = 0;
|
||||
Demod.state = DEMOD_UNSYNCD;
|
||||
|
||||
// Set up the demodulator for the reader -> tag commands
|
||||
memset(&Uart, 0, sizeof(Uart));
|
||||
Uart.output = receivedCmd;
|
||||
Uart.byteCntMax = 32; // was 100 (greg)//////////////////
|
||||
Uart.state = STATE_UNSYNCD;
|
||||
|
||||
// Setup for the DMA.
|
||||
FpgaSetupSsc();
|
||||
upTo = dmaBuf;
|
||||
lastRxCounter = DMA_BUFFER_SIZE;
|
||||
FpgaSetupSscDma((uint8_t *)dmaBuf, DMA_BUFFER_SIZE);
|
||||
|
||||
// And put the FPGA in the appropriate mode
|
||||
// Signal field is off with the appropriate LED
|
||||
LED_D_OFF();
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_ISO14443A | FPGA_HF_ISO14443A_SNIFFER);
|
||||
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
|
||||
|
||||
// Count of samples received so far, so that we can include timing
|
||||
// information in the trace buffer.
|
||||
rsamples = 0;
|
||||
// And now we loop, receiving samples.
|
||||
while(true) {
|
||||
LED_A_ON();
|
||||
WDT_HIT();
|
||||
int behindBy = (lastRxCounter - AT91C_BASE_PDC_SSC->PDC_RCR) &
|
||||
(DMA_BUFFER_SIZE-1);
|
||||
if(behindBy > maxBehindBy) {
|
||||
maxBehindBy = behindBy;
|
||||
if(behindBy > 400) {
|
||||
Dbprintf("blew circular buffer! behindBy=0x%x", behindBy);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
if(behindBy < 1) continue;
|
||||
|
||||
LED_A_OFF();
|
||||
|
||||
smpl = upTo[0];
|
||||
upTo++;
|
||||
lastRxCounter -= 1;
|
||||
if(upTo - dmaBuf > DMA_BUFFER_SIZE) {
|
||||
upTo -= DMA_BUFFER_SIZE;
|
||||
lastRxCounter += DMA_BUFFER_SIZE;
|
||||
AT91C_BASE_PDC_SSC->PDC_RNPR = (uint32_t) upTo;
|
||||
AT91C_BASE_PDC_SSC->PDC_RNCR = DMA_BUFFER_SIZE;
|
||||
}
|
||||
|
||||
rsamples += 4;
|
||||
if(MillerDecoding((smpl & 0xF0) >> 4)) {
|
||||
LED_C_ON();
|
||||
if(triggered) {
|
||||
if (!LogTrace(receivedCmd, Uart.byteCnt, -1 * Uart.samples, Uart.parityBits, TRUE)) break;
|
||||
}
|
||||
/* And ready to receive another command. */
|
||||
Uart.state = STATE_UNSYNCD;
|
||||
/* And also reset the demod code, which might have been */
|
||||
/* false-triggered by the commands from the reader. */
|
||||
Demod.state = DEMOD_UNSYNCD;
|
||||
LED_B_OFF();
|
||||
}
|
||||
|
||||
if(ManchesterDecoding(smpl & 0x0F)) {
|
||||
LED_B_ON();
|
||||
|
||||
if (!LogTrace(receivedResponse, Demod.len, -1 * Demod.samples, Demod.parityBits, FALSE)) break;
|
||||
|
||||
triggered = TRUE;
|
||||
|
||||
// And ready to receive another response.
|
||||
memset(&Demod, 0, sizeof(Demod));
|
||||
Demod.output = receivedResponse;
|
||||
Demod.state = DEMOD_UNSYNCD;
|
||||
LED_C_OFF();
|
||||
}
|
||||
|
||||
if(BUTTON_PRESS()) {
|
||||
DbpString("button cancelled");
|
||||
goto done;
|
||||
}
|
||||
} // main cycle
|
||||
|
||||
DbpString("COMMAND FINISHED");
|
||||
|
||||
done:
|
||||
AT91C_BASE_PDC_SSC->PDC_PTCR = AT91C_PDC_RXTDIS;
|
||||
Dbprintf("maxBehindBy=%x, Uart.state=%x, Uart.byteCnt=%x", maxBehindBy, Uart.state, Uart.byteCnt);
|
||||
Dbprintf("Uart.byteCntMax=%x, traceLen=%x, Uart.output[0]=%x", Uart.byteCntMax, traceLen, (int)Uart.output[0]);
|
||||
LEDsoff();
|
||||
}
|
|
@ -23,6 +23,60 @@
|
|||
|
||||
typedef struct nestedVector { uint32_t nt, ks1; } nestedVector;
|
||||
|
||||
typedef struct {
|
||||
enum {
|
||||
DEMOD_UNSYNCD,
|
||||
DEMOD_START_OF_COMMUNICATION,
|
||||
DEMOD_MANCHESTER_D,
|
||||
DEMOD_MANCHESTER_E,
|
||||
DEMOD_MANCHESTER_F,
|
||||
DEMOD_ERROR_WAIT
|
||||
} state;
|
||||
int bitCount;
|
||||
int posCount;
|
||||
int syncBit;
|
||||
int parityBits;
|
||||
uint16_t shiftReg;
|
||||
int buffer;
|
||||
int buff;
|
||||
int samples;
|
||||
int len;
|
||||
enum {
|
||||
SUB_NONE,
|
||||
SUB_FIRST_HALF,
|
||||
SUB_SECOND_HALF
|
||||
} sub;
|
||||
uint8_t *output;
|
||||
} tDemod;
|
||||
|
||||
typedef struct {
|
||||
enum {
|
||||
STATE_UNSYNCD,
|
||||
STATE_START_OF_COMMUNICATION,
|
||||
STATE_MILLER_X,
|
||||
STATE_MILLER_Y,
|
||||
STATE_MILLER_Z,
|
||||
STATE_ERROR_WAIT
|
||||
} state;
|
||||
uint16_t shiftReg;
|
||||
int bitCnt;
|
||||
int byteCnt;
|
||||
int byteCntMax;
|
||||
int posCnt;
|
||||
int syncBit;
|
||||
int parityBits;
|
||||
int samples;
|
||||
int highCnt;
|
||||
int bitBuffer;
|
||||
enum {
|
||||
DROP_NONE,
|
||||
DROP_FIRST_HALF,
|
||||
DROP_SECOND_HALF
|
||||
} drop;
|
||||
uint8_t *output;
|
||||
} tUart;
|
||||
|
||||
|
||||
extern byte_t oddparity (const byte_t bt);
|
||||
extern uint32_t GetParity(const uint8_t * pbtCmd, int iLen);
|
||||
extern void AppendCrc14443a(uint8_t* data, int len);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Merlok - June 2011
|
||||
// Merlok - June 2011, 2012
|
||||
// Gerhard de Koning Gans - May 2008
|
||||
// Hagen Fritsch - June 2010
|
||||
//
|
||||
|
|
15
armsrc/mifaresniff.c
Normal file
15
armsrc/mifaresniff.c
Normal file
|
@ -0,0 +1,15 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Merlok - 2012
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Routines to support mifare classic sniffer.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "mifaresniff.h"
|
||||
#include "apps.h"
|
||||
|
||||
|
||||
|
26
armsrc/mifaresniff.h
Normal file
26
armsrc/mifaresniff.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Merlok - June 2012
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
// the license.
|
||||
//-----------------------------------------------------------------------------
|
||||
// Routines to support mifare classic sniffer.
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef __MIFARESNIFF_H
|
||||
#define __MIFARESNIFF_H
|
||||
|
||||
#include "proxmark3.h"
|
||||
#include "apps.h"
|
||||
#include "util.h"
|
||||
#include "string.h"
|
||||
|
||||
#include "iso14443crc.h"
|
||||
#include "iso14443a.h"
|
||||
#include "crapto1.h"
|
||||
#include "mifareutil.h"
|
||||
#include "common.h"
|
||||
|
||||
|
||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Merlok, May 2011
|
||||
// Merlok, May 2011, 2012
|
||||
// Many authors, whom made it possible
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Copyright (C) 2011 Merlok
|
||||
// Copyright (C) 2011,2012 Merlok
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
|
@ -1542,6 +1542,20 @@ int CmdHF14AMfCSave(const char *Cmd) {
|
|||
}
|
||||
}
|
||||
|
||||
int CmdHF14AMfSniff(const char *Cmd){
|
||||
|
||||
if (param_getchar(Cmd, 0) == 'h') {
|
||||
PrintAndLog("Usage: hf mf sniff ");
|
||||
PrintAndLog(" sample: hf mf sniff ");
|
||||
return 0;
|
||||
}
|
||||
|
||||
UsbCommand c = {CMD_MIFARE_SNIFFER, {0, 0, 0}};
|
||||
SendCommand(&c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] =
|
||||
{
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
|
@ -1554,6 +1568,7 @@ static command_t CommandTable[] =
|
|||
{"chk", CmdHF14AMfChk, 0, "Test block keys"},
|
||||
{"mifare", CmdHF14AMifare, 0, "Read parity error messages. param - <used card nonce>"},
|
||||
{"nested", CmdHF14AMfNested, 0, "Test nested authentication"},
|
||||
{"sniff", CmdHF14AMfSniff, 0, "Sniff card-reader communication"},
|
||||
{"sim", CmdHF14AMf1kSim, 0, "Simulate MIFARE card"},
|
||||
{"eclr", CmdHF14AMfEClear, 0, "Clear simulator memory block"},
|
||||
{"eget", CmdHF14AMfEGet, 0, "Get simulator memory block"},
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// Merlok, 2011
|
||||
// Merlok, 2011, 2012
|
||||
// people from mifare@nethemba.com, 2010
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
|
|
|
@ -127,6 +127,8 @@ typedef struct {
|
|||
#define CMD_MIFARE_WRITEBL 0x0622
|
||||
#define CMD_MIFARE_CHKKEYS 0x0623
|
||||
|
||||
#define CMD_MIFARE_SNIFFER 0x0630
|
||||
|
||||
#define CMD_UNKNOWN 0xFFFF
|
||||
|
||||
// CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions:
|
||||
|
|
Loading…
Reference in a new issue