monster merge...

all those changes marshmellow did..  and more...
This commit is contained in:
iceman1001 2017-07-30 09:17:48 +02:00
commit f28da2da6e
107 changed files with 5087 additions and 3777 deletions

View file

@ -930,7 +930,7 @@ void UsbPacketReceived(uint8_t *packet, int len)
setSamplingConfig((sample_config *) c->d.asBytes);
break;
case CMD_ACQUIRE_RAW_ADC_SAMPLES_125K:
cmd_send(CMD_ACK, SampleLF(c->arg[0]),0,0,0,0);
cmd_send(CMD_ACK,SampleLF(c->arg[0], c->arg[1]),0,0,0,0);
break;
case CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K:
ModThenAcquireRawAdcSamples125k(c->arg[0], c->arg[1], c->arg[2], c->d.asBytes);
@ -1085,7 +1085,15 @@ void UsbPacketReceived(uint8_t *packet, int len)
LegicRfInfo();
break;
case CMD_LEGIC_ESET:
LegicEMemSet(c->arg[0], c->arg[1], c->d.asBytes);
//-----------------------------------------------------------------------------
// Note: we call FpgaDownloadAndGo(FPGA_BITSTREAM_HF) here although FPGA is not
// involved in dealing with emulator memory. But if it is called later, it might
// destroy the Emulator Memory.
//-----------------------------------------------------------------------------
// arg0 = offset
// arg1 = num of bytes
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
emlSet(c->d.asBytes, c->arg[0], c->arg[1]);
break;
#endif
@ -1499,9 +1507,9 @@ void __attribute__((noreturn)) AppMain(void)
for(;;) {
if ( usb_poll_validate_length() ) {
rx_len = usb_read(rx, sizeof(UsbCommand));
if (rx_len) {
if (rx_len)
UsbPacketReceived(rx, rx_len);
}
}
WDT_HIT();

View file

@ -31,6 +31,7 @@ extern "C" {
#include "iso14443b.h"
#include "emvcard.h"
extern const uint8_t OddByteParity[256];
extern int rsamples; // = 0;
extern int tracing; // = TRUE;
extern uint8_t trigger;

View file

@ -77,7 +77,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t periods, uint3
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
// now do the read
DoAcquisition_config(false);
DoAcquisition_config(false, 0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
}
@ -459,7 +459,6 @@ void SimulateTagLowFrequency(int period, int gap, int ledcontrol)
OUT:
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
LED_D_OFF();
DbpString("Simulation stopped");
return;
}
@ -784,6 +783,7 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
size_t size = 0;
uint32_t hi2=0, hi=0, lo=0;
int idx=0;
int dummyIdx = 0;
// Configure to go in 125Khz listen mode
LFSetupFPGAForADC(95, true);
@ -795,10 +795,10 @@ void CmdHIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
WDT_HIT();
if (ledcontrol) LED_A_ON();
DoAcquisition_default(0, true);
DoAcquisition_default(-1,true);
// FSK demodulator
size = 50*128*2; //big enough to catch 2 sequences of largest format
idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo);
idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo, &dummyIdx);
if (idx>0 && lo>0 && (size==96 || size==192)){
// go over previously decoded manchester data and decode into usable tag ID
@ -880,7 +880,7 @@ void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
{
uint8_t *dest = BigBuf_get_addr();
size_t size;
int idx=0;
int idx=0, dummyIdx=0;
//clear read buffer
BigBuf_Clear_keep_EM();
// Configure to go in 125Khz listen mode
@ -894,87 +894,74 @@ void CmdAWIDdemodFSK(int findone, int *high, int *low, int ledcontrol)
DoAcquisition_default(-1,true);
// FSK demodulator
size = 50*128*2; //big enough to catch 2 sequences of largest format
idx = AWIDdemodFSK(dest, &size);
idx = detectAWID(dest, &size, &dummyIdx);
if (idx<=0 || size!=96) continue;
// Index map
// 0 10 20 30 40 50 60
// | | | | | | |
// 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96
// -----------------------------------------------------------------------------
// 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1
// premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96
// |---26 bit---| |-----117----||-------------142-------------|
// b = format bit len, o = odd parity of last 3 bits
// f = facility code, c = card number
// w = wiegand parity
// (26 bit format shown)
// Index map
// 0 10 20 30 40 50 60
// | | | | | | |
// 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96
// -----------------------------------------------------------------------------
// 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1
// premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96
// |---26 bit---| |-----117----||-------------142-------------|
// b = format bit len, o = odd parity of last 3 bits
// f = facility code, c = card number
// w = wiegand parity
// (26 bit format shown)
//get raw ID before removing parities
uint32_t rawLo = bytebits_to_byte(dest+idx+64,32);
uint32_t rawHi = bytebits_to_byte(dest+idx+32,32);
uint32_t rawHi2 = bytebits_to_byte(dest+idx,32);
//get raw ID before removing parities
uint32_t rawLo = bytebits_to_byte(dest+idx+64,32);
uint32_t rawHi = bytebits_to_byte(dest+idx+32,32);
uint32_t rawHi2 = bytebits_to_byte(dest+idx,32);
size = removeParity(dest, idx+8, 4, 1, 88);
size = removeParity(dest, idx+8, 4, 1, 88);
if (size != 66) continue;
// ok valid card found!
// Index map
// 0 10 20 30 40 50 60
// | | | | | | |
// 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456
// -----------------------------------------------------------------------------
// 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000
// bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// |26 bit| |-117--| |-----142------|
//
// 00110010 0 0000011111010000000000000001000100101000100001111 0 00000000
// bbbbbbbb w ffffffffffffffffccccccccccccccccccccccccccccccccc w xxxxxxxx
// |50 bit| |----4000------||-----------2248975-------------|
//
// b = format bit len, o = odd parity of last 3 bits
// f = facility code, c = card number
// w = wiegand parity
// Index map
// 0 10 20 30 40 50 60
// | | | | | | |
// 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456
// -----------------------------------------------------------------------------
// 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000
// bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// |26 bit| |-117--| |-----142------|
// b = format bit len, o = odd parity of last 3 bits
// f = facility code, c = card number
// w = wiegand parity
// (26 bit format shown)
uint32_t fc = 0;
uint32_t cardnum = 0;
uint32_t code1 = 0;
uint32_t code2 = 0;
uint8_t fmtLen = bytebits_to_byte(dest,8);
switch(fmtLen) {
case 26:
fc = bytebits_to_byte(dest + 9, 8);
cardnum = bytebits_to_byte(dest + 17, 16);
code1 = bytebits_to_byte(dest + 8,fmtLen);
Dbprintf("AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo);
break;
case 50:
fc = bytebits_to_byte(dest + 9, 16);
cardnum = bytebits_to_byte(dest + 25, 32);
code1 = bytebits_to_byte(dest + 8, (fmtLen-32) );
code2 = bytebits_to_byte(dest + 8 + (fmtLen-32), 32);
Dbprintf("AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, code2, rawHi2, rawHi, rawLo);
break;
default:
if (fmtLen > 32 ) {
cardnum = bytebits_to_byte(dest+8+(fmtLen-17), 16);
code1 = bytebits_to_byte(dest+8,fmtLen-32);
code2 = bytebits_to_byte(dest+8+(fmtLen-32),32);
Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%u) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo);
} else {
cardnum = bytebits_to_byte(dest+8+(fmtLen-17), 16);
code1 = bytebits_to_byte(dest+8,fmtLen);
Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%u) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo);
}
break;
uint32_t fc = 0;
uint32_t cardnum = 0;
uint32_t code1 = 0;
uint32_t code2 = 0;
uint8_t fmtLen = bytebits_to_byte(dest,8);
if (fmtLen==26){
fc = bytebits_to_byte(dest+9, 8);
cardnum = bytebits_to_byte(dest+17, 16);
code1 = bytebits_to_byte(dest+8,fmtLen);
Dbprintf("AWID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo);
} else {
cardnum = bytebits_to_byte(dest+8+(fmtLen-17), 16);
if (fmtLen>32){
code1 = bytebits_to_byte(dest+8,fmtLen-32);
code2 = bytebits_to_byte(dest+8+(fmtLen-32),32);
Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo);
} else{
code1 = bytebits_to_byte(dest+8,fmtLen);
Dbprintf("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo);
}
if (findone)
break;
}
if (findone){
if (ledcontrol) LED_A_OFF();
break;
}
// reset
idx = 0;
WDT_HIT();
}
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
DbpString("Stopped");
if (ledcontrol) LED_A_OFF();
}
@ -1044,14 +1031,15 @@ void CmdEM410xdemod(int findone, int *high, int *low, int ledcontrol)
void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
{
uint8_t *dest = BigBuf_get_addr();
int idx=0;
int dummyIdx = 0;
int idx = 0;
uint32_t code=0, code2=0;
uint8_t version=0;
uint8_t facilitycode=0;
uint16_t number=0;
uint8_t crc = 0;
uint16_t calccrc = 0;
size_t size = BigBuf_max_traceLen();
//clear read buffer
BigBuf_Clear_keep_EM();
@ -1064,7 +1052,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
DoAcquisition_default(-1,true);
//fskdemod and get start index
WDT_HIT();
idx = IOdemodFSK(dest, BigBuf_max_traceLen());
idx = detectIOProx(dest, &size, &dummyIdx);
if (idx<0) continue;
//valid tag found
@ -1210,7 +1198,7 @@ void T55xxResetRead(void) {
TurnReadLFOn(READ_GAP);
// Acquisition
doT55x7Acquisition(BigBuf_max_traceLen());
DoPartialAcquisition(0, true, BigBuf_max_traceLen());
// Turn the field off
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
@ -1223,6 +1211,7 @@ void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg)
LED_A_ON();
bool PwdMode = arg & 0x1;
uint8_t Page = (arg & 0x2)>>1;
bool testMode = arg & 0x4;
uint32_t i = 0;
// Set up FPGA, 125kHz
@ -1234,9 +1223,11 @@ void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg)
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
WaitUS(START_GAP);
// Opcode 10
T55xxWriteBit(1);
T55xxWriteBit(Page); //Page 0
if (testMode) Dbprintf("TestMODE");
// Std Opcode 10
T55xxWriteBit(testMode ? 0 : 1);
T55xxWriteBit(testMode ? 1 : Page); //Page 0
if (PwdMode){
// Send Pwd
for (i = 0x80000000; i != 0; i >>= 1)
@ -1255,12 +1246,32 @@ void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg)
// Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550,
// so wait a little more)
TurnReadLFOn(20 * 1000);
// "there is a clock delay before programming"
// - programming takes ~5.6ms for t5577 ~18ms for E5550 or t5567
// so we should wait 1 clock + 5.6ms then read response?
// but we need to know we are dealing with t5577 vs t5567 vs e5550 (or q5) marshmellow...
if (testMode) {
//TESTMODE TIMING TESTS:
// <566us does nothing
// 566-568 switches between wiping to 0s and doing nothing
// 5184 wipes and allows 1 block to be programmed.
// indefinite power on wipes and then programs all blocks with bitshifted data sent.
TurnReadLFOn(5184);
} else {
TurnReadLFOn(20 * 1000);
//could attempt to do a read to confirm write took
// as the tag should repeat back the new block
// until it is reset, but to confirm it we would
// need to know the current block 0 config mode
//could attempt to do a read to confirm write took
// as the tag should repeat back the new block
// until it is reset, but to confirm it we would
// need to know the current block 0 config mode for
// modulation clock an other details to demod the response...
// response should be (for t55x7) a 0 bit then (ST if on)
// block data written in on repeat until reset.
//DoPartialAcquisition(20, true, 12000);
}
// turn field off
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@ -1279,7 +1290,7 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
bool PwdMode = arg0 & 0x1;
uint8_t Page = (arg0 & 0x2) >> 1;
uint32_t i = 0;
bool RegReadMode = (Block == 0xFF);
bool RegReadMode = (Block == 0xFF);//regular read mode
//clear buffer now so it does not interfere with timing later
BigBuf_Clear_keep_EM();
@ -1319,7 +1330,8 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
TurnReadLFOn(210*8);
// Acquisition
doT55x7Acquisition(7679);
// Now do the acquisition
DoPartialAcquisition(0, true, 12000);
// Turn the field off
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
@ -1398,7 +1410,7 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) {
data[0] = T55x7_BITRATE_RF_50 | T55x7_MODULATION_FSK2a | last_block << T55x7_MAXBLOCK_SHIFT;
//TODO add selection of chip for Q5 or T55x7
// data[0] = (((50-2)>>1)<<T5555_BITRATE_SHIFT) | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | last_block << T5555_MAXBLOCK_SHIFT;
// data[0] = T5555_SET_BITRATE(50) | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | last_block << T5555_MAXBLOCK_SHIFT;
LED_D_ON();
WriteT55xx(data, 0, last_block+1);
@ -1408,8 +1420,7 @@ void CopyHIDtoT55x7(uint32_t hi2, uint32_t hi, uint32_t lo, uint8_t longFMT) {
void CopyIOtoT55x7(uint32_t hi, uint32_t lo) {
uint32_t data[] = {T55x7_BITRATE_RF_64 | T55x7_MODULATION_FSK2a | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo};
//TODO add selection of chip for Q5 or T55x7
//t5555 (Q5) BITRATE = (RF-2)/2 (iceman)
// data[0] = ( ((64-2)>>1) << T5555_BITRATE_SHIFT) | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | 2 << T5555_MAXBLOCK_SHIFT;
// data[0] = T5555_SET_BITRATE(64) | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | 2 << T5555_MAXBLOCK_SHIFT;
LED_D_ON();
// Program the data blocks for supplied ID
@ -1424,7 +1435,7 @@ void CopyIndala64toT55x7(uint32_t hi, uint32_t lo) {
// and the Config for Indala 64 format (RF/32;PSK1 with RF/2;Maxblock=2)
uint32_t data[] = { T55x7_BITRATE_RF_32 | T55x7_MODULATION_PSK1 | (2 << T55x7_MAXBLOCK_SHIFT), hi, lo};
//TODO add selection of chip for Q5 or T55x7
// data[0] = (((32-2)>>1)<<T5555_BITRATE_SHIFT) | T5555_MODULATION_PSK1 | 2 << T5555_MAXBLOCK_SHIFT;
// data[0] = T5555_SET_BITRATE(32 | T5555_MODULATION_PSK1 | 2 << T5555_MAXBLOCK_SHIFT;
WriteT55xx(data, 0, 3);
//Alternative config for Indala (Extended mode;RF/32;PSK1 with RF/2;Maxblock=2;Inverse data)
@ -1446,8 +1457,7 @@ void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t
// clone viking tag to T55xx
void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5) {
uint32_t data[] = {T55x7_BITRATE_RF_32 | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT), block1, block2};
//t5555 (Q5) BITRATE = (RF-2)/2 (iceman)
if (Q5) data[0] = (((32-2)>>1) << T5555_BITRATE_SHIFT) | T5555_MODULATION_MANCHESTER | 2 << T5555_MAXBLOCK_SHIFT;
if (Q5) data[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_MANCHESTER | 2 << T5555_MAXBLOCK_SHIFT;
// Program the data blocks for supplied ID and the block 0 config
WriteT55xx(data, 0, 3);
LED_D_OFF();
@ -1531,8 +1541,7 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) {
}
data[0] = clock | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT);
} else { //t5555 (Q5)
// t5555 (Q5) BITRATE = (RF-2)/2 (iceman)
data[0] = ( ((clock-2) >> 1) << T5555_BITRATE_SHIFT) | T5555_MODULATION_MANCHESTER | (2 << T5555_MAXBLOCK_SHIFT);
data[0] = T5555_SET_BITRATE(clock) | T5555_MODULATION_MANCHESTER | (2 << T5555_MAXBLOCK_SHIFT);
}
WriteT55xx(data, 0, 3);
@ -1818,7 +1827,7 @@ void Cotag(uint32_t arg0) {
switch(rawsignal) {
case 0: doCotagAcquisition(50000); break;
case 1: doCotagAcquisitionManchester(); break;
case 2: DoAcquisition_config(true); break;
case 2: DoAcquisition_config(true, 0); break;
}
// Turn the field off

View file

@ -209,33 +209,33 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
uint32_t DoAcquisition_default(int trigger_threshold, bool silent) {
return DoAcquisition(1, 8, 0,trigger_threshold, silent, 0);
}
uint32_t DoAcquisition_config( bool silent) {
uint32_t DoAcquisition_config( bool silent, int sample_size) {
return DoAcquisition(config.decimation
,config.bits_per_sample
,config.averaging
,config.trigger_threshold
,silent
,0);
,sample_size);
}
uint32_t DoPartialAcquisition(int trigger_threshold, bool silent, int sample_size) {
return DoAcquisition(1, 8, 0, trigger_threshold, silent, sample_size);
}
uint32_t ReadLF(bool activeField, bool silent) {
uint32_t ReadLF(bool activeField, bool silent, int sample_size) {
if (!silent)
printConfig();
LFSetupFPGAForADC(config.divisor, activeField);
return DoAcquisition_config(silent);
return DoAcquisition_config(silent, sample_size);
}
/**
* Initializes the FPGA for reader-mode (field on), and acquires the samples.
* @return number of bits sampled
**/
uint32_t SampleLF(bool printCfg) {
uint32_t SampleLF(bool printCfg, int sample_size) {
BigBuf_Clear_ext(false);
uint32_t ret = ReadLF(true, printCfg);
uint32_t ret = ReadLF(true, printCfg, sample_size);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
return ret;
}
@ -245,7 +245,7 @@ uint32_t SampleLF(bool printCfg) {
**/
uint32_t SnoopLF() {
BigBuf_Clear_ext(false);
uint32_t ret = ReadLF(false, true);
uint32_t ret = ReadLF(false, true, 0);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
return ret;
}

View file

@ -27,13 +27,12 @@ void doT55x7Acquisition(size_t sample_size);
* Initializes the FPGA for reader-mode (field on), and acquires the samples.
* @return number of bits sampled
**/
uint32_t SampleLF(bool silent);
uint32_t SampleLF(bool silent, int sample_size);
/**
* Initializes the FPGA for snoop-mode (field off), and acquires the samples.
* @return number of bits sampled
**/
uint32_t SnoopLF();
// adds sample size to default options
@ -55,7 +54,7 @@ uint32_t DoAcquisition_default(int trigger_threshold, bool silent);
* @return number of bits sampled
*/
uint32_t DoAcquisition_config( bool silent);
uint32_t DoAcquisition_config(bool silent, int sample_size);
/**
* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream

View file

@ -82,8 +82,8 @@ CORESRCS = uart_posix.c \
uart_win32.c \
util.c \
util_posix.c \
scandir.c \
sleep.c
scandir.c
CMDSRCS = crapto1/crapto1.c \
crapto1/crypto1.c \
@ -133,11 +133,13 @@ CMDSRCS = crapto1/crapto1.c \
cmdlfhid.c \
cmdlfhitag.c \
cmdlfio.c \
cmdlfindala.c \
cmdlfjablotron.c \
cmdlfnexwatch.c \
cmdlfnedap.c \
cmdlfnoralsy.c \
cmdlfpac.c \
cmdlfparadox.c \
cmdlfpcf7931.c \
cmdlfpresco.c \
cmdlfpyramid.c \
@ -181,7 +183,7 @@ ifeq ($(MULTIARCHSRCS), )
endif
ZLIBSRCS = deflate.c adler32.c trees.c zutil.c inflate.c inffast.c inftrees.c
ZLIBFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED
ZLIBFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED
#-DDEBUG -Dverbose=1
QTGUISRCS = proxgui.cpp proxguiqt.cpp proxguiqt.moc.cpp guidummy.cpp

View file

@ -7,7 +7,7 @@
//-----------------------------------------------------------------------------
#include <stdio.h>
#include "sleep.h"
#include "util_posix.h"
#include "ui.h"
//#include "proxusb.h"
#include "cmdmain.h"

View file

@ -7,23 +7,7 @@
//-----------------------------------------------------------------------------
// CRC Calculations from the software reveng commands
//-----------------------------------------------------------------------------
#include <stdlib.h>
#ifdef _WIN32
# include <io.h>
# include <fcntl.h>
# ifndef STDIN_FILENO
# define STDIN_FILENO 0
# endif /* STDIN_FILENO */
#endif /* _WIN32 */
#include <stdio.h>
#include <string.h>
#include "cmdmain.h"
#include "cmdcrc.h"
#include "reveng/reveng.h"
#include "ui.h"
#include "util.h"
#define MAX_ARGS 20

View file

@ -11,9 +11,28 @@
#ifndef CMDCRC_H__
#define CMDCRC_H__
int CmdCrc(const char *Cmd);
#ifdef _WIN32
# include <io.h>
# include <fcntl.h>
# ifndef STDIN_FILENO
# define STDIN_FILENO 0
# endif /* STDIN_FILENO */
#endif /* _WIN32 */
int CmdrevengSearch(const char *Cmd);
int GetModels(char *Models[], int *count, uint8_t *width);
int RunModel(char *inModel, char *inHexStr, bool reverse, char endian, char *result);
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "cmdmain.h"
#include "reveng/reveng.h"
#include "ui.h"
#include "util.h"
extern int CmdCrc(const char *Cmd);
extern int CmdrevengSearch(const char *Cmd);
extern int GetModels(char *Models[], int *count, uint8_t *width);
extern int RunModel(char *inModel, char *inHexStr, bool reverse, char endian, char *result);
#endif

File diff suppressed because it is too large Load diff

View file

@ -31,15 +31,17 @@
#include "crc.h" // for pyramid checksum maxim
#include "crc16.h" // for FDXB demod checksum
#include "loclass/cipherutils.h" // for decimating samples in getsamples
#include "cmdlfem4x.h" // askem410xdecode
command_t * CmdDataCommands();
int CmdData(const char *Cmd);
void printDemodBuff(void);
void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx);
int CmdAskEM410xDemod(const char *Cmd);
int CmdVikingDemod(const char *Cmd);
int CmdG_Prox_II_Demod(const char *Cmd);
bool getDemodBuf(uint8_t *buff, size_t *size);
void save_restoreDB(uint8_t saveOpt);// option '1' to save DemodBuffer any other to restore
int CmdPrintDemodBuff(const char *Cmd);
int Cmdaskrawdemod(const char *Cmd);
int Cmdaskmandemod(const char *Cmd);
int AutoCorrelate(const int *in, int *out, size_t len, int window, bool SaveGrph, bool verbose);
@ -50,12 +52,6 @@ int CmdBitsamples(const char *Cmd);
int CmdBuffClear(const char *Cmd);
int CmdDec(const char *Cmd);
int CmdDetectClockRate(const char *Cmd);
int CmdFDXBdemodBI(const char *Cmd);
int CmdFSKdemodAWID(const char *Cmd);
int CmdFSKdemodHID(const char *Cmd);
int CmdFSKdemodIO(const char *Cmd);
int CmdFSKdemodParadox(const char *Cmd);
int CmdFSKdemodPyramid(const char *Cmd);
int CmdFSKrawdemod(const char *Cmd);
int CmdPSK1rawDemod(const char *Cmd);
int CmdPSK2rawDemod(const char *Cmd);
@ -80,19 +76,14 @@ int CmdSave(const char *Cmd);
int CmdScale(const char *Cmd);
int CmdDirectionalThreshold(const char *Cmd);
int CmdZerocrossings(const char *Cmd);
int CmdIndalaDecode(const char *Cmd);
int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo );
int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose);
int ASKbiphaseDemod(const char *Cmd, bool verbose);
int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType);
int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, bool *stCheck);
int FSKrawDemod(const char *Cmd, bool verbose);
int PSKDemod(const char *Cmd, bool verbose);
int NRZrawDemod(const char *Cmd, bool verbose);
void printEM410x(uint32_t hi, uint64_t id);
int getSamples(const char *Cmd, bool silent);
void setGrid_Clock(uint8_t clock);
int getSamples(int n, bool silent);
void setClockGrid(int clk, int offset);
int directionalThreshold(const int* in, int *out, size_t len, int8_t up, int8_t down);
extern int AskEdgeDetect(const int *in, int *out, int len, int threshold);

View file

@ -7,26 +7,7 @@
//-----------------------------------------------------------------------------
// High frequency commands
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include "proxmark3.h"
#include "graph.h"
#include "ui.h"
#include "cmdparser.h"
#include "cmdhf.h"
#include "cmdhf14a.h"
#include "cmdhf14b.h"
#include "cmdhf15.h"
#include "cmdhfepa.h"
#include "cmdhflegic.h" // LEGIC
#include "cmdhficlass.h" // ICLASS
#include "cmdhfmf.h" // CLASSIC
#include "cmdhfmfu.h" // ULTRALIGHT/NTAG etc
#include "cmdhfmfdes.h" // DESFIRE
#include "cmdhftopaz.h" // TOPAZ
#include "cmdhfemv.h" // EMV
#include "protocols.h"
static int CmdHelp(const char *Cmd);
@ -658,14 +639,8 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
for (int j = 0; j < data_len && j/16 < 16; j++) {
int oddparity = 0x01;
int k;
for (k=0 ; k<8 ; k++) {
oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
}
uint8_t parityBits = parityBytes[j>>3];
if (protocol != LEGIC && protocol != ISO_14443B && protocol != ISO_7816_4 && (isResponse || protocol == ISO_14443A) && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
if (protocol != LEGIC && protocol != ISO_14443B && protocol != ISO_7816_4 && (isResponse || protocol == ISO_14443A) && (oddparity8(frame[j]) != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]);
} else {
snprintf(line[j/16]+(( j % 16) * 4),110, "%02x ", frame[j]);
@ -751,6 +726,10 @@ int usage_hf_list(){
PrintAndLog(" 14a - interpret data as iso14443a communications");
PrintAndLog(" 14b - interpret data as iso14443b communications");
PrintAndLog(" des - interpret data as DESFire communications");
#ifdef WITH_EMV
PrintAndLog(" emv - interpret data as EMV / communications");
#endif
PrintAndLog(" iclass - interpret data as iclass communications");
PrintAndLog(" topaz - interpret data as topaz communications");
PrintAndLog(" 7816 - interpret data as iso7816-4 communications");
@ -809,14 +788,14 @@ int CmdHFList(const char *Cmd) {
param_getstr(Cmd,0,type);
// validate type of output
if(strcmp(type, "iclass") == 0) protocol = ICLASS;
else if(strcmp(type, "14a") == 0) protocol = ISO_14443A;
else if(strcmp(type, "14b") == 0) protocol = ISO_14443B;
else if(strcmp(type, "topaz")== 0) protocol = TOPAZ;
else if(strcmp(type, "7816")== 0) protocol = ISO_7816_4;
else if(strcmp(type,"des")== 0) protocol = MFDES;
else if(strcmp(type,"legic")==0) protocol = LEGIC;
else if(strcmp(type, "raw")== 0) protocol = -1;//No crc, no annotations
if (strcmp(type, "iclass") == 0) protocol = ICLASS;
else if(strcmp(type, "14a") == 0) protocol = ISO_14443A;
else if(strcmp(type, "14b") == 0) protocol = ISO_14443B;
else if(strcmp(type, "topaz")== 0) protocol = TOPAZ;
else if(strcmp(type, "7816")== 0) protocol = ISO_7816_4;
else if(strcmp(type, "des")== 0) protocol = MFDES;
else if(strcmp(type, "legic")==0) protocol = LEGIC;
else if(strcmp(type, "raw")== 0) protocol = -1;//No crc, no annotations
else errors = true;
if (errors) return usage_hf_list();
@ -923,19 +902,19 @@ int CmdHFSnoop(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"14a", CmdHF14A, 1, "{ ISO14443A RFIDs... }"},
{"14b", CmdHF14B, 1, "{ ISO14443B RFIDs... }"},
{"15", CmdHF15, 1, "{ ISO15693 RFIDs... }"},
{"14a", CmdHF14A, 1, "{ ISO14443A RFIDs... }"},
{"14b", CmdHF14B, 1, "{ ISO14443B RFIDs... }"},
{"15", CmdHF15, 1, "{ ISO15693 RFIDs... }"},
{"epa", CmdHFEPA, 1, "{ German Identification Card... }"},
#ifdef WITH_EMV
{"emv", CmdHFEmv, 1, "{ EMV RFIDs... }"},
{"emv", CmdHFEmv, 1, "{ EMV RFIDs... }"},
#endif
{"legic", CmdHFLegic, 1, "{ LEGIC RFIDs... }"},
{"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"},
{"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"},
{"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"},
{"mfdes", CmdHFMFDes, 1, "{ MIFARE Desfire RFIDs... }"},
{"topaz", CmdHFTopaz, 1, "{ TOPAZ (NFC Type 1) RFIDs... }"},
{"legic", CmdHFLegic, 1, "{ LEGIC RFIDs... }"},
{"iclass", CmdHFiClass, 1, "{ ICLASS RFIDs... }"},
{"mf", CmdHFMF, 1, "{ MIFARE RFIDs... }"},
{"mfu", CmdHFMFUltra, 1, "{ MIFARE Ultralight RFIDs... }"},
{"mfdes", CmdHFMFDes, 1, "{ MIFARE Desfire RFIDs... }"},
{"topaz", CmdHFTopaz, 1, "{ TOPAZ (NFC Type 1) RFIDs... }"},
{"tune", CmdHFTune, 0, "Continuously measure HF antenna tuning"},
{"list", CmdHFList, 1, "List protocol data in trace buffer"},
{"search", CmdHFSearch, 1, "Search for known HF tags [preliminary]"},

View file

@ -11,8 +11,34 @@
#ifndef CMDHF_H__
#define CMDHF_H__
int CmdHF(const char *Cmd);
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "proxmark3.h"
#include "graph.h"
#include "ui.h"
#include "cmdparser.h"
#include "cmdhf14a.h"
#include "cmdhf14b.h"
#include "cmdhf15.h"
#include "cmdhfepa.h"
#include "cmdhflegic.h" // LEGIC
#include "cmdhficlass.h" // ICLASS
#include "cmdhfmf.h" // CLASSIC
#include "cmdhfmfu.h" // ULTRALIGHT/NTAG etc
#include "cmdhfmfdes.h" // DESFIRE
#include "cmdhftopaz.h" // TOPAZ
#include "cmdhfemv.h" // EMV
#include "protocols.h"
#include "parity.h" // oddparity
extern int CmdHF(const char *Cmd);
extern int CmdHFTune(const char *Cmd);
extern int CmdHFList(const char *Cmd);
extern int CmdHFSearch(const char *Cmd);
extern int CmdHFSnoop(const char *Cmd);
extern int usage_hf_list();
extern int usage_hf_search();
extern int usage_hf_snoop();
#endif

View file

@ -9,25 +9,7 @@
//-----------------------------------------------------------------------------
// High frequency ISO14443A commands
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "util.h"
#include "iso14443crc.h"
#include "data.h"
#include "proxmark3.h"
#include "ui.h"
#include "cmdparser.h"
#include "cmdhf14a.h"
#include "common.h"
#include "cmdmain.h"
#include "mifare.h"
#include "cmdhfmf.h"
#include "cmdhfmfu.h"
#include "mifarehost.h"
#include "cmdhf.h"
static int CmdHelp(const char *Cmd);
static void waitCmd(uint8_t iLen);
@ -430,7 +412,7 @@ int CmdHF14ACUIDs(const char *Cmd) {
n = n > 0 ? n : 1;
PrintAndLog("Collecting %d UIDs", n);
PrintAndLog("Start: %u", time(NULL));
PrintAndLog("Start: %" PRIu64, msclock()/1000);
// repeat n times
for (int i = 0; i < n; i++) {
// execute anticollision procedure
@ -453,7 +435,7 @@ int CmdHF14ACUIDs(const char *Cmd) {
PrintAndLog("%s", uid_string);
}
}
PrintAndLog("End: %u", time(NULL));
PrintAndLog("End: %" PRIu64, msclock()/1000);
return 1;
}

View file

@ -1,7 +1,7 @@
//-----------------------------------------------------------------------------
// 2011, Merlok
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
//
// 2015,216,2017 iceman, marshmellow, piwi
// 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.
@ -12,17 +12,36 @@
#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 CmdHF14ASniff(const char *Cmd);
int CmdHF14AEMVTransaction(const char *Cmd);
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "proxmark3.h"
#include "common.h"
#include "ui.h"
#include "util.h"
#include "cmdparser.h"
#include "cmdmain.h"
#include "iso14443crc.h"
#include "data.h"
#include "mifare.h"
#include "cmdhfmf.h"
#include "cmdhfmfu.h"
#include "cmdhf.h" // list cmd
#include "mifarehost.h"
char* getTagInfo(uint8_t uid);
extern int CmdHF14A(const char *Cmd);
extern int CmdHF14AList(const char *Cmd);
extern int CmdHF14AReader(const char *Cmd);
extern int CmdHF14ASim(const char *Cmd);
extern int CmdHF14ASniff(const char *Cmd);
extern int CmdHF14ACmdRaw(const char *Cmd);
extern int CmdHF14ACUIDs(const char *Cmd);
int usage_hf_14a_sim(void);
int usage_hf_14a_sniff(void);
int usage_hf_14a_raw(void);
extern char* getTagInfo(uint8_t uid);
extern int usage_hf_14a_sim(void);
extern int usage_hf_14a_sniff(void);
extern int usage_hf_14a_raw(void);
#endif

View file

@ -221,10 +221,10 @@ int CmdHF14BCmdRaw (const char *Cmd) {
bool success = true;
// get back iso14b_card_select_t, don't print it.
if (select)
success = waitCmd(false);
success = waitCmd14b(false);
// get back response from the raw bytes you sent.
if (success && datalen>0) waitCmd(true);
if (success && datalen>0) waitCmd14b(true);
return 1;
}
@ -802,7 +802,7 @@ int srix4kValid(const char *Cmd){
return 0;
}
bool waitCmd(bool verbose) {
bool waitCmd14b(bool verbose) {
bool crc = false;
uint8_t b1 = 0, b2 = 0;

View file

@ -54,5 +54,5 @@ int CmdHF14BCmdRaw (const char *Cmd);
int CmdHF14BReadSri(const char *Cmd);
int CmdHF14BWriteSri(const char *Cmd);
bool waitCmd(bool verbose);
bool waitCmd14b(bool verbose);
#endif

View file

@ -7,16 +7,7 @@
//-----------------------------------------------------------------------------
// Commands related to the German electronic Identification Card
//-----------------------------------------------------------------------------
#include "cmdhfepa.h"
#include <time.h>
#include "util.h"
#include "proxmark3.h"
#include "ui.h"
#include "cmdparser.h"
#include "common.h"
#include "cmdmain.h"
#include "sleep.h"
static int CmdHelp(const char *Cmd);
@ -24,11 +15,11 @@ static int CmdHelp(const char *Cmd);
int CmdHFEPACollectPACENonces(const char *Cmd)
{
// requested nonce size
unsigned int m = 0;
uint32_t m = 0;
// requested number of Nonces
unsigned int n = 0;
uint32_t n = 0;
// delay between requests
unsigned int d = 0;
uint32_t d = 0;
sscanf(Cmd, "%u %u %u", &m, &n, &d);
@ -37,14 +28,14 @@ int CmdHFEPACollectPACENonces(const char *Cmd)
n = n > 0 ? n : 1;
PrintAndLog("Collecting %u %u byte nonces", n, m);
PrintAndLog("Start: %u", time(NULL));
PrintAndLog("Start: %" PRIu64, msclock()/1000);
// repeat n times
for (unsigned int i = 0; i < n; i++) {
for (uint32_t i = 0; i < n; i++) {
// execute PACE
UsbCommand c = {CMD_EPA_PACE_COLLECT_NONCE, {(int)m, 0, 0}};
clearCommandBuffer();
SendCommand(&c);
UsbCommand resp;
WaitForResponse(CMD_ACK,&resp);
// check if command failed
@ -64,13 +55,10 @@ int CmdHFEPACollectPACENonces(const char *Cmd)
sleep(d);
}
}
PrintAndLog("End: %u", time(NULL));
PrintAndLog("End: %" PRIu64, msclock()/1000);
return 1;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////The commands lie below here/////////////////////////////////////////////////////////////////////////////////////////
// perform the PACE protocol by replaying APDUs
int CmdHFEPAPACEReplay(const char *Cmd)
{
@ -139,6 +127,8 @@ int CmdHFEPAPACEReplay(const char *Cmd)
memcpy(usb_cmd.d.asBytes, // + (j * sizeof(usb_cmd.d.asBytes)),
apdus[i] + (j * sizeof(usb_cmd.d.asBytes)),
packet_length);
clearCommandBuffer();
SendCommand(&usb_cmd);
WaitForResponse(CMD_ACK, &resp);
if (resp.arg[0] != 0) {
@ -150,6 +140,7 @@ int CmdHFEPAPACEReplay(const char *Cmd)
// now perform the replay
usb_cmd.arg[0] = 0;
clearCommandBuffer();
SendCommand(&usb_cmd);
WaitForResponse(CMD_ACK, &resp);
if (resp.arg[0] != 0) {
@ -168,35 +159,25 @@ int CmdHFEPAPACEReplay(const char *Cmd)
PrintAndLog("GA Perform Key Agreement: %u us", resp.d.asDwords[3]);
PrintAndLog("GA Mutual Authenticate: %u us", resp.d.asDwords[4]);
}
return 1;
}
////////////////////////////////The new commands lie above here/////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// UI-related stuff
static const command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"cnonces", CmdHFEPACollectPACENonces, 0,
"<m> <n> <d> Acquire n>0 encrypted PACE nonces of size m>0 with d sec pauses"},
{"preplay", CmdHFEPAPACEReplay, 0,
"<mse> <get> <map> <pka> <ma> Perform PACE protocol by replaying given APDUs"},
{NULL, NULL, 0, NULL}
{"help", CmdHelp, 1, "This help"},
{"cnonces", CmdHFEPACollectPACENonces, 0, "<m> <n> <d> Acquire n>0 encrypted PACE nonces of size m>0 with d sec pauses"},
{"preplay", CmdHFEPAPACEReplay, 0, "<mse> <get> <map> <pka> <ma> Perform PACE protocol by replaying given APDUs"},
{NULL, NULL, 0, NULL}
};
int CmdHelp(const char *Cmd) {
CmdsHelp(CommandTable);
return 0;
CmdsHelp(CommandTable);
return 0;
}
int CmdHFEPA(const char *Cmd) {
// flush
clearCommandBuffer();
//WaitForResponseTimeout(CMD_ACK,NULL,100);
// parse
CmdsParse(CommandTable, Cmd);
return 0;
}

View file

@ -11,8 +11,22 @@
#ifndef CMDHFEPA_H__
#define CMDHFEPA_H__
int CmdHFEPA(const char *Cmd);
#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <stdio.h>
#include "util.h"
#include "proxmark3.h"
#include "common.h"
#include "ui.h"
#include "cmdparser.h"
#include "cmdmain.h"
#include "util_posix.h"
int CmdHFEPACollectPACENonces(const char *Cmd);
extern int CmdHFEPA(const char *Cmd);
extern int CmdHFEPACollectPACENonces(const char *Cmd);
extern int CmdHFEPAPACEReplay(const char *Cmd);
#endif // CMDHFEPA_H__

View file

@ -319,6 +319,7 @@ int HFiClassReader(const char *Cmd, bool loop, bool verbose) {
c.arg[0] |= FLAG_ICLASS_READER_ONLY_ONCE | FLAG_ICLASS_READER_ONE_TRY;
UsbCommand resp;
while (!ukbhit()){
clearCommandBuffer();
SendCommand(&c);
if (WaitForResponseTimeout(CMD_ACK,&resp, 4500)) {
@ -336,8 +337,23 @@ int HFiClassReader(const char *Cmd, bool loop, bool verbose) {
PrintAndLog("CSN: %s",sprint_hex(data,8));
tagFound = true;
}
if( readStatus & FLAG_ICLASS_READER_CC) PrintAndLog("CC: %s", sprint_hex(data+16, 8));
if( readStatus & FLAG_ICLASS_READER_CONF) printIclassDumpInfo(data);
if( readStatus & FLAG_ICLASS_READER_CC) {
PrintAndLog(" CC: %s",sprint_hex(data+16,8));
}
if( readStatus & FLAG_ICLASS_READER_CONF) {
printIclassDumpInfo(data);
}
if (readStatus & FLAG_ICLASS_READER_AA) {
bool legacy = true;
PrintAndLog(" AppIA: %s",sprint_hex(data+8*5,8));
for (int i = 0; i<8; i++) {
if (data[8*5+i] != 0xFF) {
legacy = false;
}
}
PrintAndLog(" : Possible iClass %s",(legacy) ? "(legacy tag)" : "(NOT legacy tag)");
}
if (tagFound && !loop) return 1;
} else {
if (verbose) PrintAndLog("Command execute timeout");
@ -876,9 +892,6 @@ int CmdHFiClassReader_Dump(const char *Cmd) {
// add diversified keys to dump
if (have_debit_key) memcpy(tag_data+(3*8),div_key,8);
if (have_credit_key) memcpy(tag_data+(4*8),c_div_key,8);
printf("Num of bytes: %zu\n", gotBytes);
// print the dump
printf("------+--+-------------------------+\n");
printf("CSN |00| %s|\n", sprint_hex(tag_data, 8));
@ -1160,20 +1173,21 @@ int CmdHFiClassCloneTag(const char *Cmd) {
return 1;
}
static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool rawkey, bool verbose) {
static int ReadBlock(uint8_t *KEY, uint8_t blockno, uint8_t keyType, bool elite, bool rawkey, bool verbose, bool auth) {
uint8_t MAC[4]={0x00,0x00,0x00,0x00};
uint8_t div_key[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
// block 0,1 should always be able to read, and block 5 on some cards.
if (blockno >= 2 ) {
if (auth || blockno >= 2) {
if (!select_and_auth(KEY, MAC, div_key, (keyType==0x18), elite, rawkey, verbose))
return 0;
} else {
uint8_t CSN[8]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uint8_t CCNR[12]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
if (!select_only(CSN, CCNR, false, verbose))
return false;
if (!select_only(CSN, CCNR, (keyType==0x18), verbose))
return 0;
}
UsbCommand resp;
UsbCommand w = {CMD_ICLASS_READBLOCK, {blockno}};
clearCommandBuffer();
@ -1203,6 +1217,7 @@ int CmdHFiClass_ReadBlock(const char *Cmd) {
bool elite = false;
bool rawkey = false;
bool errors = false;
bool auth = false;
uint8_t cmdp = 0;
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch(param_getchar(Cmd, cmdp)) {
@ -1229,6 +1244,7 @@ int CmdHFiClass_ReadBlock(const char *Cmd) {
break;
case 'k':
case 'K':
auth = true;
dataLen = param_getstr(Cmd, cmdp+1, tempStr);
if (dataLen == 16) {
errors = param_gethex(tempStr, 0, KEY, dataLen);
@ -1259,7 +1275,10 @@ int CmdHFiClass_ReadBlock(const char *Cmd) {
}
if (errors || cmdp < 4) return usage_hf_iclass_readblock();
return ReadBlock(KEY, blockno, keyType, elite, rawkey, true);
if (!auth)
PrintAndLog("warning: no authentication used with read, only a few specific blocks can be read accurately without authentication.");
return ReadBlock(KEY, blockno, keyType, elite, rawkey, true, auth);
}
int CmdHFiClass_loclass(const char *Cmd) {
@ -1597,8 +1616,8 @@ int CmdHFiClassManageKeys(const char *Cmd) {
case 'n':
case 'N':
keyNbr = param_get8(Cmd, cmdp+1);
if (keyNbr == 0) {
PrintAndLog("Wrong block number");
if (keyNbr >= ICLASS_KEYS_MAX) {
PrintAndLog("Invalid block number");
errors = true;
}
cmdp += 2;

View file

@ -172,19 +172,34 @@ int CmdLegicInfo(const char *Cmd) {
int i = 0, k = 0, segmentNum = 0, segment_len = 0, segment_flag = 0;
int crc = 0, wrp = 0, wrc = 0;
uint8_t stamp_len = 0;
uint8_t data[1024]; // receiver buffer
uint16_t datalen = 0;
char token_type[5] = {0,0,0,0,0};
int dcf = 0;
int bIsSegmented = 0;
CmdLegicRdmem("0 22 55");
// copy data from device
GetEMLFromBigBuf(data, sizeof(data), 0);
if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2000)){
PrintAndLog("Command execute timeout");
// tagtype
legic_card_select_t card;
if (legic_get_type(&card)) {
PrintAndLog("Failed to identify tagtype");
return 1;
}
PrintAndLog("Reading tag memory %d b...", card.cardsize);
// allocate receiver buffer
uint8_t *data = malloc(card.cardsize);
if (!data) {
PrintAndLog("Cannot allocate memory");
return 2;
}
memset(data, 0, card.cardsize);
int status = legic_read_mem(0, card.cardsize, 0x55, data, &datalen);
if ( status > 0 ) {
PrintAndLog("Failed reading memory");
free(data);
return 3;
}
// Output CDF System area (9 bytes) plus remaining header area (12 bytes)
crc = data[4];
@ -298,8 +313,9 @@ int CmdLegicInfo(const char *Cmd) {
uint32_t segCalcCRC = 0;
uint32_t segCRC = 0;
// Data card?
if(dcf <= 60000) {
// Not Data card?
if (dcf > 60000)
goto out;
PrintAndLog("\nADF: User Area");
PrintAndLog("------------------------------------------------------");
@ -398,7 +414,8 @@ int CmdLegicInfo(const char *Cmd) {
PrintAndLog("-----+------------------------------------------------\n");
// end with last segment
if (segment_flag & 0x8) return 0;
if (segment_flag & 0x8)
goto out;
} // end for loop
@ -449,7 +466,9 @@ int CmdLegicInfo(const char *Cmd) {
PrintAndLog("-----+------------------------------------------------\n");
}
}
out:
free(data);
return 0;
}
@ -461,65 +480,28 @@ int CmdLegicRdmem(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
if ( cmdp == 'H' || cmdp == 'h' ) return usage_legic_rdmem();
uint32_t offset = 0, len = 0, IV = 1;
sscanf(Cmd, "%x %x %x", &offset, &len, &IV);
// tagtype
legic_card_select_t card;
if (legic_get_type(&card)) {
PrintAndLog("Failed to identify tagtype");
return 1;
}
legic_print_type(card.cardsize, 0);
// OUT-OF-BOUNDS check
// UID 4 bytes can't be written to.
if ( len + offset >= card.cardsize ) {
len = card.cardsize - offset;
PrintAndLog("Out-of-bounds, Cardsize = %d, Trunc offset+len = %d", card.cardsize, len + offset);
}
uint32_t offset = 0, len = 0, iv = 1;
uint16_t datalen = 0;
sscanf(Cmd, "%x %x %x", &offset, &len, &iv);
legic_chk_iv(&IV);
PrintAndLog("Reading %d bytes, from offset %d", len, offset);
UsbCommand c = {CMD_READER_LEGIC_RF, {offset, len, IV}};
clearCommandBuffer();
SendCommand(&c);
UsbCommand resp;
if ( !WaitForResponseTimeout(CMD_ACK, &resp, 3000) ) {
PrintAndLog("command execution time out");
return 1;
}
uint8_t isOK = resp.arg[0] & 0xFF;
uint16_t readlen = resp.arg[1];
if ( !isOK ) {
PrintAndLog("failed reading tag");
return 2;
}
uint8_t *data = malloc(readlen);
// allocate receiver buffer
uint8_t *data = malloc(len);
if ( !data ){
PrintAndLog("Cannot allocate memory");
return 2;
}
if ( readlen != len )
PrintAndLog("Fail, only managed to read 0x%02X bytes", readlen);
// copy data from device
GetEMLFromBigBuf(data, readlen, 0);
if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2500)){
PrintAndLog("Command execute timeout");
free(data);
return 1;
}
memset(data, 0, len);
int status = legic_read_mem(offset, len, iv, data, &datalen);
if ( status == 0 ) {
PrintAndLog("\n ## | 0 1 2 3 4 5 6 7 8 9 A B C D E F 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F");
PrintAndLog("-----+------------------------------------------------------------------------------------------------");
print_hex_break( data, readlen, 32);
print_hex_break(data, datalen, 32);
}
free(data);
return 0;
return status;
}
// should say which tagtype
@ -752,6 +734,37 @@ int CmdLegicCalcCrc(const char *Cmd){
return 0;
}
int legic_read_mem(uint32_t offset, uint32_t len, uint32_t iv, uint8_t *out, uint16_t *outlen) {
legic_chk_iv(&iv);
UsbCommand c = {CMD_READER_LEGIC_RF, {offset, len, iv}};
clearCommandBuffer();
SendCommand(&c);
UsbCommand resp;
if ( !WaitForResponseTimeout(CMD_ACK, &resp, 3000) ) {
PrintAndLog("command execution time out");
return 1;
}
uint8_t isOK = resp.arg[0] & 0xFF;
*outlen = resp.arg[1];
if ( !isOK ) {
PrintAndLog("failed reading tag");
return 2;
}
if ( *outlen != len )
PrintAndLog("Fail, only managed to read %u bytes", *outlen);
// copy data from device
if ( !GetEMLFromBigBuf(out, *outlen, 0) ) {
PrintAndLog("Fail, transfer from device time-out");
return 4;
}
return 0;
}
int legic_print_type(uint32_t tagtype, uint8_t spaces){
char spc[11] = " ";
spc[10]=0x00;
@ -798,8 +811,9 @@ void legic_chk_iv(uint32_t *iv){
}
void legic_seteml(uint8_t *src, uint32_t offset, uint32_t numofbytes) {
size_t len = 0;
UsbCommand c = {CMD_LEGIC_ESET, {0, 0, 0}};
for(size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) {
for(size_t i = offset; i < numofbytes; i += USB_CMD_DATA_SIZE) {
len = MIN((numofbytes - i), USB_CMD_DATA_SIZE);
c.arg[0] = i; // offset
@ -810,6 +824,7 @@ void legic_seteml(uint8_t *src, uint32_t offset, uint32_t numofbytes) {
}
}
int HFLegicReader(const char *Cmd, bool verbose) {
char cmdp = param_getchar(Cmd, 0);
@ -818,9 +833,10 @@ int HFLegicReader(const char *Cmd, bool verbose) {
legic_card_select_t card;
switch(legic_get_type(&card)){
case 1:
return 2;
case 2:
if ( verbose ) PrintAndLog("command execution time out");
return 1;
case 2:
case 3:
if ( verbose ) PrintAndLog("legic card select failed");
return 2;
@ -878,7 +894,7 @@ int CmdLegicDump(const char *Cmd){
dumplen = card.cardsize;
legic_print_type(dumplen, 0);
PrintAndLog("Reading tag memory...");
PrintAndLog("Reading tag memory %d b...", dumplen);
UsbCommand c = {CMD_READER_LEGIC_RF, {0x00, dumplen, 0x55}};
clearCommandBuffer();
@ -907,8 +923,7 @@ int CmdLegicDump(const char *Cmd){
PrintAndLog("Fail, only managed to read 0x%02X bytes of 0x%02X", readlen, dumplen);
// copy data from device
GetEMLFromBigBuf(data, readlen, 0);
if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2500)) {
if (!GetEMLFromBigBuf(data, readlen, 0) ) {
PrintAndLog("Fail, transfer from device time-out");
free(data);
return 4;
@ -1154,8 +1169,7 @@ int CmdLegicESave(const char *Cmd) {
// download emulator memory
PrintAndLog("Reading emulator memory...");
GetEMLFromBigBuf(data, numofbytes, 0);
if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2500)) {
if (!GetEMLFromBigBuf(data, numofbytes, 0)) {
PrintAndLog("Fail, transfer from device time-out");
free(data);
return 4;

View file

@ -26,25 +26,26 @@
int CmdHFLegic(const char *Cmd);
int CmdLegicInfo(const char *Cmd);
int CmdLegicRdmem(const char *Cmd);
int CmdLegicLoad(const char *Cmd);
int CmdLegicRfSim(const char *Cmd);
int CmdLegicRfWrite(const char *Cmd);
int CmdLegicCalcCrc(const char *Cmd);
int CmdLegicDump(const char *Cmd);
int CmdLegicRestore(const char *Cmd);
int CmdLegicReader(const char *Cmd);
int CmdLegicELoad(const char *Cmd);
int CmdLegicESave(const char *Cmd);
int CmdLegicList(const char *Cmd);
int CmdLegicWipe(const char *Cmd);
extern int CmdLegicInfo(const char *Cmd);
extern int CmdLegicRdmem(const char *Cmd);
extern int CmdLegicLoad(const char *Cmd);
extern int CmdLegicRfSim(const char *Cmd);
extern int CmdLegicRfWrite(const char *Cmd);
extern int CmdLegicCalcCrc(const char *Cmd);
extern int CmdLegicDump(const char *Cmd);
extern int CmdLegicRestore(const char *Cmd);
extern int CmdLegicReader(const char *Cmd);
extern int CmdLegicELoad(const char *Cmd);
extern int CmdLegicESave(const char *Cmd);
extern int CmdLegicList(const char *Cmd);
extern int CmdLegicWipe(const char *Cmd);
int HFLegicReader(const char *Cmd, bool verbose);
int legic_print_type(uint32_t tagtype, uint8_t spaces);
int legic_get_type(legic_card_select_t *card);
void legic_chk_iv(uint32_t *iv);
void legic_seteml(uint8_t *src, uint32_t offset, uint32_t numofbytes);
int legic_read_mem(uint32_t offset, uint32_t len, uint32_t iv, uint8_t *out, uint16_t *outlen);
int usage_legic_calccrc(void);
int usage_legic_load(void);

View file

@ -1100,7 +1100,8 @@ int CmdHF14AMfNestedHard(const char *Cmd) {
slow ? "Yes" : "No",
tests);
int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, know_target_key?trgkey:NULL, nonce_file_read, nonce_file_write, slow, tests);
uint64_t foundkey = 0;
int16_t isOK = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, know_target_key ? trgkey : NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey);
if (isOK) {
switch (isOK) {
@ -1350,7 +1351,7 @@ int CmdHF14AMfChk(const char *Cmd) {
}
//print them
//print keys
printKeyTable( SectorsCnt, e_sector );
if (transferToEml) {
@ -1533,7 +1534,7 @@ int CmdHF14AMf1kSim(const char *Cmd) {
if(flags & FLAG_INTERACTIVE) {
PrintAndLog("Press pm3-button or send another cmd to abort simulation");
while( !ukbhit() ){
while( !ukbhit() ){
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1500) ) continue;
if ( !(flags & FLAG_NR_AR_ATTACK) ) break;
if ( (resp.arg[0] & 0xffff) != CMD_SIMULATE_MIFARE_CARD ) break;
@ -1553,7 +1554,6 @@ int CmdHF14AMfSniff(const char *Cmd){
bool wantSaveToEmlFile = false;
//var
int tmpchar;
int res = 0;
int len = 0;
int blockLen = 0;
@ -1597,8 +1597,7 @@ int CmdHF14AMfSniff(const char *Cmd){
printf(".");
fflush(stdout);
if (ukbhit()) {
tmpchar = getchar();
(void)tmpchar;
int gc = getchar(); (void)gc;
printf("\naborted via keyboard!\n");
break;
}

View file

@ -67,4 +67,5 @@ extern int CmdHf14AMfSetMod(const char *Cmd);
void showSectorTable(void);
void readerAttack(nonces_t data, bool setEmulatorMem, bool verbose);
void printKeyTable( uint8_t sectorscnt, sector_t *e_sector );
void printKeyTable_fast( uint8_t sectorscnt, icesector_t *e_sector, uint64_t bar, uint64_t foo );
#endif

View file

@ -1,6 +1,7 @@
//-----------------------------------------------------------------------------
// Copyright (C) 2015, 2016 by piwi
//
// fiddled with 2016 Azcid (hardnested bitsliced Bruteforce imp)
// fiddled with 2016 Matrix ( sub testing of nonces while collecting )
// 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.
@ -507,12 +508,7 @@ static void init_sum_bitarrays(void)
bitarray_OR(sum_a0_bitarrays[ODD_STATE][sum_a0_idx], part_sum_a0_bitarrays[ODD_STATE][p]);
}
}
// for (uint16_t sum_a0 = 0; sum_a0 < NUM_SUMS; sum_a0++) {
// for (odd_even_t odd_even = EVEN_STATE; odd_even <= ODD_STATE; odd_even++) {
// uint32_t count = count_states(sum_a0_bitarrays[odd_even][sum_a0]);
// printf("sum_a0_bitarray[%s][%d] has %d states (%5.2f%%)\n", odd_even==EVEN_STATE?"even":"odd ", sums[sum_a0], count, (float)count/(1<<24)*100.0);
// }
// }
}
@ -658,19 +654,7 @@ static void free_nonces_memory(void)
}
// static double p_hypergeometric_cache[257][NUM_SUMS][257];
// #define CACHE_INVALID -1.0
// static void init_p_hypergeometric_cache(void)
// {
// for (uint16_t n = 0; n <= 256; n++) {
// for (uint16_t i_K = 0; i_K < NUM_SUMS; i_K++) {
// for (uint16_t k = 0; k <= 256; k++) {
// p_hypergeometric_cache[n][i_K][k] = CACHE_INVALID;
// }
// }
// }
// }
static double p_hypergeometric(uint16_t i_K, uint16_t n, uint16_t k)
@ -688,9 +672,7 @@ static double p_hypergeometric(uint16_t i_K, uint16_t n, uint16_t k)
uint16_t const N = 256;
uint16_t K = sums[i_K];
// if (p_hypergeometric_cache[n][i_K][k] != CACHE_INVALID) {
// return p_hypergeometric_cache[n][i_K][k];
// }
if (n-k > N-K || k > K) return 0.0; // avoids log(x<=0) in calculation below
if (k == 0) {
@ -702,7 +684,6 @@ static double p_hypergeometric(uint16_t i_K, uint16_t n, uint16_t k)
for (int16_t i = N; i >= N-n+1; i--) {
log_result -= log(i);
}
// p_hypergeometric_cache[n][i_K][k] = exp(log_result);
return exp(log_result);
} else {
if (n-k == N-K) { // special case. The published recursion below would fail with a divide by zero exception
@ -713,7 +694,6 @@ static double p_hypergeometric(uint16_t i_K, uint16_t n, uint16_t k)
for (int16_t i = K+1; i <= N; i++) {
log_result -= log(i);
}
// p_hypergeometric_cache[n][i_K][k] = exp(log_result);
return exp(log_result);
} else { // recursion
return (p_hypergeometric(i_K, n, k-1) * (K-k+1) * (n-k+1) / (k * (N-K-n+k)));
@ -1459,7 +1439,7 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_
bool reported_suma8 = false;
FILE *fnonces = NULL;
UsbCommand resp;
uint8_t timeout = 0;
num_acquired_nonces = 0;
clearCommandBuffer();
@ -1472,17 +1452,28 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_
UsbCommand c = {CMD_MIFARE_ACQUIRE_ENCRYPTED_NONCES, {blockNo + keyType * 0x100, trgBlockNo + trgKeyType * 0x100, flags}};
memcpy(c.d.asBytes, key, 6);
clearCommandBuffer();
SendCommand(&c);
if (field_off) break;
if (initialize) {
if (!WaitForResponseTimeout(CMD_ACK, &resp, 3000)) return 1;
while(!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
timeout++;
printf(".");
if (timeout > 3) {
PrintAndLog("\nNo response from Proxmark. Aborting...");
if (fnonces) fclose(fnonces);
return 1;
}
}
if (resp.arg[0]) return resp.arg[0]; // error during nested_hard
if (resp.arg[0]) {
if (fnonces) fclose(fnonces);
return resp.arg[0]; // error during nested_hard
}
cuid = resp.arg[1];
// PrintAndLog("Acquiring nonces for CUID 0x%08x", cuid);
if (nonce_file_write && fnonces == NULL) {
if ((fnonces = fopen("nonces.bin","wb")) == NULL) {
PrintAndLog("Could not create file nonces.bin");
@ -1493,7 +1484,9 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_
fwrite(write_buf, 1, 4, fnonces);
fwrite(&trgBlockNo, 1, 1, fnonces);
fwrite(&trgKeyType, 1, 1, fnonces);
fflush(fnonces);
}
initialize = false;
}
if (!initialize) {
@ -1513,6 +1506,7 @@ static int acquire_nonces(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_
if (nonce_file_write) {
fwrite(bufp, 1, 9, fnonces);
fflush(fnonces);
}
bufp += 9;
}
@ -2171,12 +2165,12 @@ static void pre_XOR_nonces(void)
}
static bool brute_force(void)
static bool brute_force(uint64_t *found_key)
{
if (known_target_key != -1) {
TestIfKeyExists(known_target_key);
}
return brute_force_bs(NULL, candidates, cuid, num_acquired_nonces, maximum_states, nonces, best_first_bytes);
return brute_force_bs(NULL, candidates, cuid, num_acquired_nonces, maximum_states, nonces, best_first_bytes, found_key);
}
@ -2253,7 +2247,7 @@ static void set_test_state(uint8_t byte)
}
int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *trgkey, bool nonce_file_read, bool nonce_file_write, bool slow, int tests)
int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *trgkey, bool nonce_file_read, bool nonce_file_write, bool slow, int tests, uint64_t *foundkey)
{
char progress_text[80];
@ -2324,8 +2318,8 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
best_first_bytes[0] = best_first_byte_smallest_bitarray;
pre_XOR_nonces();
prepare_bf_test_nonces(nonces, best_first_bytes[0]);
hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force1, 0);
key_found = brute_force();
//hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force1, 0);
key_found = brute_force(foundkey);
free(candidates->states[ODD_STATE]);
free(candidates->states[EVEN_STATE]);
free_candidates_memory(candidates);
@ -2344,8 +2338,8 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
// printf("Estimated remaining states: %" PRIu64 " (2^%1.1f)\n", nonces[best_first_bytes[0]].sum_a8_guess[j].num_states, log(nonces[best_first_bytes[0]].sum_a8_guess[j].num_states)/log(2.0));
generate_candidates(first_byte_Sum, nonces[best_first_bytes[0]].sum_a8_guess[j].sum_a8_idx);
// printf("Time for generating key candidates list: %1.0f sec (%1.1f sec CPU)\n", difftime(time(NULL), start_time), (float)(msclock() - start_clock)/1000.0);
hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force, 0);
key_found = brute_force();
//hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force, 0);
key_found = brute_force(foundkey);
free_statelist_cache();
free_candidates_memory(candidates);
candidates = NULL;
@ -2439,8 +2433,8 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
best_first_bytes[0] = best_first_byte_smallest_bitarray;
pre_XOR_nonces();
prepare_bf_test_nonces(nonces, best_first_bytes[0]);
hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force1, 0);
key_found = brute_force();
//hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force1, 0);
key_found = brute_force(foundkey);
free(candidates->states[ODD_STATE]);
free(candidates->states[EVEN_STATE]);
free_candidates_memory(candidates);
@ -2459,8 +2453,8 @@ int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBloc
// printf("Estimated remaining states: %" PRIu64 " (2^%1.1f)\n", nonces[best_first_bytes[0]].sum_a8_guess[j].num_states, log(nonces[best_first_bytes[0]].sum_a8_guess[j].num_states)/log(2.0));
generate_candidates(first_byte_Sum, nonces[best_first_bytes[0]].sum_a8_guess[j].sum_a8_idx);
// printf("Time for generating key candidates list: %1.0f sec (%1.1f sec CPU)\n", difftime(time(NULL), start_time), (float)(msclock() - start_clock)/1000.0);
hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force, 0);
key_found = brute_force();
//hardnested_print_progress(num_acquired_nonces, "Starting brute force...", expected_brute_force, 0);
key_found = brute_force(foundkey);
free_statelist_cache();
free_candidates_memory(candidates);
candidates = NULL;

View file

@ -41,7 +41,7 @@ typedef struct noncelist {
noncelistentry_t *first;
} noncelist_t;
extern int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *trgkey, bool nonce_file_read, bool nonce_file_write, bool slow, int tests);
extern int mfnestedhard(uint8_t blockNo, uint8_t keyType, uint8_t *key, uint8_t trgBlockNo, uint8_t trgKeyType, uint8_t *trgkey, bool nonce_file_read, bool nonce_file_write, bool slow, int tests, uint64_t *foundkey);
extern void hardnested_print_progress(uint32_t nonces, char *activity, float brute_force, uint64_t min_diff_print_time);
#endif

View file

@ -30,11 +30,16 @@ int usage_lf_cmdread(void) {
return 0;
}
int usage_lf_read(void){
PrintAndLog("Usage: lf read [h] [s]");
PrintAndLog("Usage: lf read [h] [s] [d numofsamples]");
PrintAndLog("Options:");
PrintAndLog(" h This help");
PrintAndLog(" s silent run no printout");
PrintAndLog(" d #samples # samples to collect (optional)");
PrintAndLog("Use 'lf config' to set parameters.");
PrintAndLog("");
PrintAndLog("Samples:");
PrintAndLog(" lf read s d 12000 - collects 12000samples silent");
PrintAndLog(" lf read s");
return 0;
}
int usage_lf_snoop(void) {
@ -42,6 +47,8 @@ int usage_lf_snoop(void) {
PrintAndLog("Usage: lf snoop [h]");
PrintAndLog("Options:");
PrintAndLog(" h This help");
PrintAndLog("This function takes no arguments. ");
PrintAndLog("Use 'lf config' to set parameters.");
return 0;
}
int usage_lf_config(void) {
@ -244,234 +251,6 @@ int CmdFlexdemod(const char *Cmd)
RepaintGraphWindow();
return 0;
}
int CmdIndalaDemod(const char *Cmd)
{
// PSK1, Bitrate 32,
// 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, worst = 0, worstPos = 0;
// PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32);
// loop through raw signal - since we know it is psk1 rf/32 fc/2 skip every other value (+=2)
for (i = 0; i < GraphTraceLen-1; i += 2) {
count += 1;
if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) {
// appears redundant - marshmellow
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)) {
//appears redundant
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;
}
}
if ( rawbit<1 ) return 0;
if (g_debugMode) {
PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32);
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) {
if (g_debugMode) 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] = {0x00};
char showbits[225] = {0x00};
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;
}
//convert UID to HEX
uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
int idx;
uid1 = uid2 = 0;
if (uidlen==64){
for( idx=0; idx<64; idx++) {
if (showbits[idx] == '0') {
uid1 = (uid1<<1) | (uid2>>31);
uid2 = (uid2<<1) | 0;
} else {
uid1 = (uid1<<1) | (uid2>>31);
uid2 = (uid2<<1) | 1;
}
}
PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2);
} else {
uid3 = uid4 = uid5 = uid6 = uid7 = 0;
for( idx=0; idx<224; idx++) {
uid1 = (uid1<<1) | (uid2>>31);
uid2 = (uid2<<1) | (uid3>>31);
uid3 = (uid3<<1) | (uid4>>31);
uid4 = (uid4<<1) | (uid5>>31);
uid5 = (uid5<<1) | (uid6>>31);
uid6 = (uid6<<1) | (uid7>>31);
if (showbits[idx] == '0')
uid7 = (uid7<<1) | 0;
else
uid7 = (uid7<<1) | 1;
}
PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7);
}
// Checking UID against next occurrences
int failed = 0;
for (; i + uidlen <= rawbit;) {
failed = 0;
for (bit = 0; bit < uidlen; bit++) {
if (bits[bit] != rawbits[i++]) {
failed = 1;
break;
}
}
if (failed == 1) {
break;
}
times += 1;
}
if (g_debugMode) PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen);
// Remodulating for tag cloning
// HACK: 2015-01-04 this will have an impact on our new way of seening lf commands (demod)
// since this changes graphbuffer data.
GraphTraceLen = 32 * uidlen;
i = 0;
int phase = 0;
for (bit = 0; bit < uidlen; bit++) {
phase = (bits[bit] == 0) ? 0 : 1;
int j;
for (j = 0; j < 32; j++) {
GraphBuffer[i++] = phase;
phase = !phase;
}
}
RepaintGraphWindow();
return 1;
}
int CmdIndalaClone(const char *Cmd){
UsbCommand c;
unsigned int uid1, uid2, uid3, uid4, uid5, uid6, uid7;
uid1 = uid2 = uid3 = uid4 = uid5 = uid6 = uid7 = 0;
int n = 0, i = 0;
if (strchr(Cmd,'l') != 0) {
while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
uid1 = (uid1 << 4) | (uid2 >> 28);
uid2 = (uid2 << 4) | (uid3 >> 28);
uid3 = (uid3 << 4) | (uid4 >> 28);
uid4 = (uid4 << 4) | (uid5 >> 28);
uid5 = (uid5 << 4) | (uid6 >> 28);
uid6 = (uid6 << 4) | (uid7 >> 28);
uid7 = (uid7 << 4) | (n & 0xf);
}
PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1, uid2, uid3, uid4, uid5, uid6, uid7);
c.cmd = CMD_INDALA_CLONE_TAG_L;
c.d.asDwords[0] = uid1;
c.d.asDwords[1] = uid2;
c.d.asDwords[2] = uid3;
c.d.asDwords[3] = uid4;
c.d.asDwords[4] = uid5;
c.d.asDwords[5] = uid6;
c.d.asDwords[6] = uid7;
} else {
while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
uid1 = (uid1 << 4) | (uid2 >> 28);
uid2 = (uid2 << 4) | (n & 0xf);
}
PrintAndLog("Cloning 64bit tag with UID %x%08x", uid1, uid2);
c.cmd = CMD_INDALA_CLONE_TAG;
c.arg[0] = uid1;
c.arg[1] = uid2;
}
clearCommandBuffer();
SendCommand(&c);
return 0;
}
int CmdLFSetConfig(const char *Cmd) {
uint8_t divisor = 0;//Frequency divisor
@ -541,12 +320,33 @@ int CmdLFSetConfig(const char *Cmd) {
return 0;
}
bool lf_read(bool silent, uint32_t samples) {
if (offline) return false;
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {silent, samples, 0}};
clearCommandBuffer();
SendCommand(&c);
UsbCommand resp;
if (g_lf_threshold_set) {
WaitForResponse(CMD_ACK, &resp);
} else {
if ( !WaitForResponseTimeout(CMD_ACK, &resp, 2500) ) {
PrintAndLog("command execution time out");
return false;
}
}
getSamples(resp.arg[0], silent);
return true;
}
int CmdLFRead(const char *Cmd) {
if (offline) return 0;
bool errors = false;
bool arg1 = false;
bool silent = false;
uint32_t samples = 0;
uint8_t cmdp = 0;
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch(param_getchar(Cmd, cmdp)) {
@ -555,9 +355,14 @@ int CmdLFRead(const char *Cmd) {
return usage_lf_read();
case 's':
case 'S':
arg1 = true;
silent = true;
cmdp++;
break;
case 'd':
case 'D':
samples = param_get32ex(Cmd, cmdp, 0, 10);
cmdp +=2;
break;
default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
@ -568,18 +373,7 @@ int CmdLFRead(const char *Cmd) {
//Validations
if (errors) return usage_lf_read();
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {arg1,0,0}};
clearCommandBuffer();
SendCommand(&c);
if ( g_lf_threshold_set ) {
WaitForResponse(CMD_ACK,NULL);
} else {
if ( !WaitForResponseTimeout(CMD_ACK, NULL ,2500) ) {
PrintAndLog("command execution time out");
return 1;
}
}
return 0;
return lf_read(silent, samples);
}
int CmdLFSnoop(const char *Cmd) {
@ -590,7 +384,7 @@ int CmdLFSnoop(const char *Cmd) {
clearCommandBuffer();
SendCommand(&c);
WaitForResponse(CMD_ACK,NULL);
getSamples("", false);
getSamples(0, false);
return 0;
}
@ -700,9 +494,10 @@ int CmdLFfskSim(const char *Cmd)
//Validations
if (errors) return usage_lf_simfsk();
int firstClockEdge = 0;
if (dataLen == 0){ //using DemodBuffer
if (clk == 0 || fcHigh == 0 || fcLow == 0){ //manual settings must set them all
uint8_t ans = fskClocks(&fcHigh, &fcLow, &clk, 0);
uint8_t ans = fskClocks(&fcHigh, &fcLow, &clk, 0, &firstClockEdge);
if (ans==0){
if (!fcHigh) fcHigh = 10;
if (!fcLow) fcLow = 8;
@ -1016,30 +811,30 @@ int CmdVchDemod(const char *Cmd) {
return 0;
}
//by marshmellow
int CheckChipset(bool getDeviceData) {
int CheckChipType(bool getDeviceData) {
if (!getDeviceData) return 0;
uint32_t word = 0;
save_restoreGB(1);
save_restoreGB(GRAPH_SAVE);
//check for em4x05/em4x69 chips first
if (EM4x05IsBlock0(&word)) {
save_restoreGB(0);
save_restoreGB(GRAPH_RESTORE);
PrintAndLog("\nValid EM4x05/EM4x69 Chipset found\nTry `lf em 4x05` commands\n");
return 1;
}
//TODO check for t55xx chip...
// if ( t55xxIsBlock0(() {
// save_restoreGB(0);
// PrintAndLog("\nValid T55xx Chipset found\nTry `lf t55xx` commands\n");
// return 1;
// }
//check for t55xx chip...
if (tryDetectP1(true)) {
PrintAndLog("\nValid T55xx Chip Found\nTry `lf t55xx` commands\n");
save_restoreGB(GRAPH_RESTORE);
save_restoreGB(0);
return 1;
}
save_restoreDB(GRAPH_RESTORE);
return 0;
}
@ -1054,8 +849,7 @@ int CmdLFfind(const char *Cmd) {
bool getDeviceData = (!offline && (cmdp != '1') );
if (getDeviceData) {
CmdLFRead("s");
getSamples("30000", false);
lf_read(true, 30000);
} else if (GraphTraceLen < minLength) {
PrintAndLog("Data in Graphbuffer was too small.");
return 0;
@ -1074,7 +868,7 @@ int CmdLFfind(const char *Cmd) {
// only run if graphbuffer is just noise as it should be for hitag/cotag
if (graphJustNoise(GraphBuffer, testLen)) {
if (CheckChipset(getDeviceData) )
if (CheckChipType(getDeviceData) )
return 1;
ans=CmdLFHitagReader("26");
@ -1092,102 +886,135 @@ int CmdLFfind(const char *Cmd) {
}
// identify chipset
CheckChipset(getDeviceData);
CheckChipType(getDeviceData);
ans=CmdFSKdemodIO("");
ans=CmdIOProxDemod("");
if (ans>0) {
PrintAndLog("\nValid IO Prox ID Found!");
return 1;
return CheckChipType(getDeviceData);
}
ans=CmdFSKdemodPyramid("");
ans=CmdPyramidDemod("");
if (ans>0) {
PrintAndLog("\nValid Pyramid ID Found!");
return 1;
return CheckChipType(getDeviceData);
}
ans=CmdFSKdemodParadox("");
ans=CmdParadoxDemod("");
if (ans>0) {
PrintAndLog("\nValid Paradox ID Found!");
return 1;
return CheckChipType(getDeviceData);
}
ans=CmdFSKdemodAWID("");
ans=CmdAWIDDemod("");
if (ans>0) {
PrintAndLog("\nValid AWID ID Found!");
return 1;
return CheckChipType(getDeviceData);
}
ans=CmdFSKdemodHID("");
ans=CmdHIDDemod("");
if (ans>0) {
PrintAndLog("\nValid HID Prox ID Found!");
return 1;
return CheckChipType(getDeviceData);
}
ans=CmdAskEM410xDemod("");
if (ans>0) {
PrintAndLog("\nValid EM410x ID Found!");
return 1;
return CheckChipType(getDeviceData);
}
ans=CmdG_Prox_II_Demod("");
ans=CmdVisa2kDemod("");
if (ans>0) {
PrintAndLog("\nValid Visa2000 ID Found!");
return CheckChipType(getDeviceData);
}
ans=CmdGuardDemod("");
if (ans>0) {
PrintAndLog("\nValid Guardall G-Prox II ID Found!");
return 1;
return CheckChipType(getDeviceData);
}
ans=CmdFDXBdemodBI("");
ans=CmdFdxDemod(""); //biphase
if (ans>0) {
PrintAndLog("\nValid FDX-B ID Found!");
return 1;
return CheckChipType(getDeviceData);
}
ans=EM4x50Read("", false);
if (ans>0) {
PrintAndLog("\nValid EM4x50 ID Found!");
return 1;
}
ans=CmdJablotronDemod("");
if (ans>0) {
PrintAndLog("\nValid Jablotron ID Found!");
return CheckChipType(getDeviceData);
}
ans=CmdNoralsyDemod("");
if (ans>0) {
PrintAndLog("\nValid Noralsy ID Found!");
return CheckChipType(getDeviceData);
}
ans=CmdSecurakeyDemod("");
if (ans>0) {
PrintAndLog("\nValid Securakey ID Found!");
return CheckChipType(getDeviceData);
}
ans=CmdVikingDemod("");
if (ans>0) {
PrintAndLog("\nValid Viking ID Found!");
return 1;
return CheckChipType(getDeviceData);
}
ans=CmdIndalaDecode("");
ans=CmdIndalaDemod("");
if (ans>0) {
PrintAndLog("\nValid Indala ID Found!");
return 1;
return CheckChipType(getDeviceData);
}
ans=CmdPSKNexWatch("");
ans=CmdNexWatchDemod("");
if (ans>0) {
PrintAndLog("\nValid NexWatch ID Found!");
return 1;
return CheckChipType(getDeviceData);
}
ans=CmdPSKIdteck("");
if (ans>0) {
PrintAndLog("\nValid Idteck ID Found!");
return 1;
return CheckChipType(getDeviceData);
}
ans=CmdJablotronDemod("");
if (ans>0) {
PrintAndLog("\nValid Jablotron ID Found!");
return 1;
return CheckChipType(getDeviceData);
}
ans=CmdLFNedapDemod("");
if (ans>0) {
PrintAndLog("\nValid NEDAP ID Found!");
return 1;
return CheckChipType(getDeviceData);
}
ans=CmdVisa2kDemod("");
if (ans>0) {
PrintAndLog("\nValid Visa2000 ID Found!");
return 1;
return CheckChipType(getDeviceData);
}
ans=CmdNoralsyDemod("");
if (ans>0) {
PrintAndLog("\nValid Noralsy ID Found!");
return 1;
return CheckChipType(getDeviceData);
}
ans=CmdPrescoDemod("");
if (ans>0) {
PrintAndLog("\nValid Presco ID Found!");
return 1;
return CheckChipType(getDeviceData);
}
ans=CmdPacDemod("");
if (ans>0) {
PrintAndLog("\nValid PAC/Stanley ID Found!");
return 1;
return CheckChipType(getDeviceData);
}
// TIdemod?
@ -1229,7 +1056,7 @@ int CmdLFfind(const char *Cmd) {
ans=FSKrawDemod("",true);
if (ans>0) {
PrintAndLog("\nUnknown FSK Modulated Tag Found!");
return 1;
return CheckChipType(getDeviceData);;
}
}
bool st = true;
@ -1237,7 +1064,7 @@ int CmdLFfind(const char *Cmd) {
if (ans>0) {
PrintAndLog("\nUnknown ASK Modulated and Manchester encoded Tag Found!");
PrintAndLog("\nif it does not look right it could instead be ASK/Biphase - try 'data rawdemod ab'");
return 1;
return CheckChipType(getDeviceData);
}
ans=CmdPSK1rawDemod("");
@ -1245,7 +1072,7 @@ int CmdLFfind(const char *Cmd) {
PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data rawdemod p2'");
PrintAndLog("\nCould also be PSK3 - [currently not supported]");
PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod");
return 1;
return CheckChipType(getDeviceData);
}
PrintAndLog("\nNo Data Found!\n");
}
@ -1254,34 +1081,32 @@ int CmdLFfind(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"animal", CmdLFFdx, 1, "{ Animal RFIDs... }"},
{"awid", CmdLFAWID, 1, "{ AWID RFIDs... }"},
{"cotag", CmdLFCOTAG, 1, "{ COTAG RFIDs... }"},
{"em", CmdLFEM4X, 1, "{ EM4X RFIDs... }"},
{"guard", CmdLFGuard, 1, "{ Guardall RFIDs... }"},
{"cotag", CmdLFCOTAG, 1, "{ COTAG CHIPs... }"},
{"em", CmdLFEM4X, 1, "{ EM4X CHIPs & RFIDs... }"},
{"fdx", CmdLFFdx, 1, "{ FDX-B RFIDs... }"},
{"gproxii", CmdLFGuard, 1, "{ Guardall Prox II RFIDs... }"},
{"hid", CmdLFHID, 1, "{ HID RFIDs... }"},
{"hitag", CmdLFHitag, 1, "{ HITAG RFIDs... }"},
// {"indala", CmdLFIndala, 1, "{ Indala RFIDs... }"},
{"io", CmdLFIO, 1, "{ IOPROX RFIDs... }"},
{"hitag", CmdLFHitag, 1, "{ Hitag CHIPs... }"},
{"indala", CmdLFINDALA, 1, "{ Indala RFIDs... }"},
{"io", CmdLFIO, 1, "{ ioProx RFIDs... }"},
{"jablotron", CmdLFJablotron, 1, "{ Jablotron RFIDs... }"},
{"nedap", CmdLFNedap, 1, "{ Nedap RFIDs... }"},
{"nexwatch", CmdLFNexWatch, 1, "{ NexWatch RFIDs... }"},
{"nexwatch", CmdLFNEXWATCH, 1, "{ NexWatch RFIDs... }"},
{"noralsy", CmdLFNoralsy, 1, "{ Noralsy RFIDs... }"},
{"pac", CmdLFPac, 1, "{ PAC/Stanley RFIDs... }"},
{"pcf7931", CmdLFPCF7931, 1, "{ PCF7931 RFIDs... }"},
{"paradox", CmdLFParadox, 1, "{ Paradox RFIDs... }"},
{"pcf7931", CmdLFPCF7931, 1, "{ PCF7931 CHIPs... }"},
{"presco", CmdLFPresco, 1, "{ Presco RFIDs... }"},
{"pyramid", CmdLFPyramid, 1, "{ Farpointe/Pyramid RFIDs... }"},
{"securakey", CmdLFSecurakey, 1, "{ Securakey RFIDs... }"},
{"ti", CmdLFTI, 1, "{ TI RFIDs... }"},
{"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"},
{"ti", CmdLFTI, 1, "{ TI CHIPs... }"},
{"t55xx", CmdLFT55XX, 1, "{ T55xx CHIPs... }"},
{"viking", CmdLFViking, 1, "{ Viking RFIDs... }"},
{"visa2000", CmdLFVisa2k, 1, "{ Visa2000 RFIDs... }"},
{"config", CmdLFSetConfig, 0, "Set config for LF sampling, bit/sample, decimation, frequency"},
{"cmdread", CmdLFCommandRead, 0, "<off period> <'0' period> <'1' period> <command> ['h' 134] \n\t\t-- Modulate LF reader field to send command before read (all periods in microseconds)"},
{"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"},
{"indalademod", CmdIndalaDemod, 1, "['224'] -- Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
{"indalaclone", CmdIndalaClone, 0, "<UID> ['l']-- Clone Indala to T55x7 (tag must be in antenna)(UID in HEX)(option 'l' for 224 UID"},
{"read", CmdLFRead, 0, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
{"search", CmdLFfind, 1, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) \n\t\t-- 'u' to search for unknown tags"},
{"sim", CmdLFSim, 0, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"},

View file

@ -14,7 +14,6 @@
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <limits.h>
#include "proxmark3.h"
@ -44,6 +43,10 @@
#include "cmdlfnoralsy.h" // for NORALSY meny
#include "cmdlffdx.h" // for FDX-B meny
#include "cmdlfcotag.h" // for COTAG meny
#include "cmdlfindala.h" // for indala menu
#include "cmdlfguard.h"// for gproxii menu
#include "cmdlffdx.h" // for fdx-b menu
#include "cmdlfparadox.h"// for paradox menu
#include "cmdlfnexwatch.h" //for nexwatch menu
#include "cmdlfsecurakey.h" //for securakey menu
#include "cmdlfpac.h" // for pac menu
@ -56,8 +59,6 @@ extern int CmdLFSetConfig(const char *Cmd);
extern int CmdLFCommandRead(const char *Cmd);
extern int CmdFlexdemod(const char *Cmd);
extern int CmdIndalaDemod(const char *Cmd);
extern int CmdIndalaClone(const char *Cmd);
extern int CmdLFRead(const char *Cmd);
extern int CmdLFSim(const char *Cmd);
extern int CmdLFaskSim(const char *Cmd);
@ -68,6 +69,7 @@ extern int CmdLFSnoop(const char *Cmd);
extern int CmdVchDemod(const char *Cmd);
extern int CmdLFfind(const char *Cmd);
extern bool lf_read(bool silent, uint32_t samples);
// usages helptext
extern int usage_lf_cmdread(void);

View file

@ -8,24 +8,25 @@
// the license.
//-----------------------------------------------------------------------------
// Low frequency AWID26/50 commands
// FSK2a, RF/50, 96 bits (complete)
//-----------------------------------------------------------------------------
#include "cmdlfawid.h" // AWID function declarations
static int CmdHelp(const char *Cmd);
int usage_lf_awid_fskdemod(void) {
int usage_lf_awid_read(void) {
PrintAndLog("Enables AWID compatible reader mode printing details of scanned AWID26 or AWID50 tags.");
PrintAndLog("By default, values are printed and logged until the button is pressed or another USB command is issued.");
PrintAndLog("If the [1] option is provided, reader mode is exited after reading a single AWID card.");
PrintAndLog("");
PrintAndLog("Usage: lf awid fskdemod [h] [1]");
PrintAndLog("Usage: lf awid read [h] [1]");
PrintAndLog("Options:");
PrintAndLog(" h : This help");
PrintAndLog(" 1 : (optional) stop after reading a single card");
PrintAndLog("");
PrintAndLog("Samples:");
PrintAndLog(" lf awid fskdemod");
PrintAndLog(" lf awid fskdemod 1");
PrintAndLog(" lf awid read");
PrintAndLog(" lf awid read 1");
return 0;
}
@ -115,22 +116,6 @@ static bool sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, ui
return true;
}
int CmdAWIDDemodFSK(const char *Cmd) {
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_awid_fskdemod();
uint8_t findone = (Cmd[0] == '1') ? 1 : 0;
UsbCommand c = {CMD_AWID_DEMOD_FSK, {findone, 0, 0}};
clearCommandBuffer();
SendCommand(&c);
return 0;
}
int CmdAWIDRead(const char *Cmd) {
CmdLFRead("s");
getSamples("12000", true);
return CmdFSKdemodAWID(Cmd);
}
//refactored by marshmellow
int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits) {
@ -225,6 +210,154 @@ static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn){
}
}
// this read is the "normal" read, which download lf signal and tries to demod here.
int CmdAWIDRead(const char *Cmd) {
lf_read(true, 12000);
return CmdAWIDDemod(Cmd);
}
// this read loops on device side.
// uses the demod in lfops.c
int CmdAWIDRead_device(const char *Cmd) {
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_awid_read();
uint8_t findone = (Cmd[0] == '1') ? 1 : 0;
UsbCommand c = {CMD_AWID_DEMOD_FSK, {findone, 0, 0}};
clearCommandBuffer();
SendCommand(&c);
return 0;
}
//by marshmellow
//AWID Prox demod - FSK RF/50 with preamble of 00000001 (always a 96 bit data stream)
//print full AWID Prox ID and some bit format details if found
int CmdAWIDDemod(const char *Cmd) {
uint8_t bits[MAX_GRAPH_TRACE_LEN]={0};
size_t size = getFromGraphBuf(bits);
if (size==0) {
PrintAndLog("DEBUG: Error - AWID not enough samples");
return 0;
}
//get binary from fsk wave
int waveIdx = 0;
int idx = detectAWID(bits, &size, &waveIdx);
if (idx <= 0){
if (g_debugMode){
if (idx == -1)
PrintAndLog("DEBUG: Error - AWID not enough samples");
else if (idx == -2)
PrintAndLog("DEBUG: Error - AWID only noise found");
else if (idx == -3)
PrintAndLog("DEBUG: Error - AWID problem during FSK demod");
else if (idx == -4)
PrintAndLog("DEBUG: Error - AWID preamble not found");
else if (idx == -5)
PrintAndLog("DEBUG: Error - AWID size not correct: %d", size);
else
PrintAndLog("DEBUG: Error - AWID error %d",idx);
}
return 0;
}
// Index map
// 0 10 20 30 40 50 60
// | | | | | | |
// 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96
// -----------------------------------------------------------------------------
// 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1
// premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96
// |---26 bit---| |-----117----||-------------142-------------|
// b = format bit len, o = odd parity of last 3 bits
// f = facility code, c = card number
// w = wiegand parity
// (26 bit format shown)
//get raw ID before removing parities
uint32_t rawLo = bytebits_to_byte(bits + idx + 64, 32);
uint32_t rawHi = bytebits_to_byte(bits + idx + 32, 32);
uint32_t rawHi2 = bytebits_to_byte(bits + idx, 32);
setDemodBuf(bits, 96, idx);
size = removeParity(bits, idx+8, 4, 1, 88);
if (size != 66){
if (g_debugMode) PrintAndLog("DEBUG: Error - AWID at parity check-tag size does not match AWID format");
return 0;
}
// ok valid card found!
// Index map
// 0 10 20 30 40 50 60
// | | | | | | |
// 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456
// -----------------------------------------------------------------------------
// 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000
// bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// |26 bit| |-117--| |-----142------|
//
// 00110010 0 0000111110100000 00000000000100010010100010000111 1 000000000
// bbbbbbbb w ffffffffffffffff cccccccccccccccccccccccccccccccc w xxxxxxxxx
// |50 bit| |----4000------| |-----------2248975------------|
// b = format bit len, o = odd parity of last 3 bits
// f = facility code, c = card number
// w = wiegand parity
uint32_t fc = 0;
uint32_t cardnum = 0;
uint32_t code1 = 0;
uint32_t code2 = 0;
uint8_t fmtLen = bytebits_to_byte(bits, 8);
switch(fmtLen) {
case 26:
fc = bytebits_to_byte(bits + 9, 8);
cardnum = bytebits_to_byte(bits + 17, 16);
code1 = bytebits_to_byte(bits + 8,fmtLen);
PrintAndLog("AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo);
break;
case 34:
fc = bytebits_to_byte(bits + 9, 8);
cardnum = bytebits_to_byte(bits + 17, 24);
code1 = bytebits_to_byte(bits + 8, (fmtLen-32) );
code2 = bytebits_to_byte(bits + 8 + (fmtLen-32), 32);
PrintAndLog("AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, code2, rawHi2, rawHi, rawLo);
break;
case 37:
fc = bytebits_to_byte(bits + 9, 13);
cardnum = bytebits_to_byte(bits + 22, 18);
code1 = bytebits_to_byte(bits + 8, (fmtLen-32) );
code2 = bytebits_to_byte(bits + 8 + (fmtLen-32), 32);
PrintAndLog("AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, code2, rawHi2, rawHi, rawLo);
break;
// case 40:
// break;
case 50:
fc = bytebits_to_byte(bits + 9, 16);
cardnum = bytebits_to_byte(bits + 25, 32);
code1 = bytebits_to_byte(bits + 8, (fmtLen-32) );
code2 = bytebits_to_byte(bits + 8 + (fmtLen-32), 32);
PrintAndLog("AWID Found - BitLength: %d, FC: %d, Card: %u - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, code2, rawHi2, rawHi, rawLo);
break;
default:
if (fmtLen > 32 ) {
cardnum = bytebits_to_byte(bits + 8 + (fmtLen-17), 16);
code1 = bytebits_to_byte(bits + 8, fmtLen-32);
code2 = bytebits_to_byte(bits + 8 + (fmtLen-32), 32);
PrintAndLog("AWID Found - BitLength: %d -unknown BitLength- (%u) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo);
} else {
cardnum = bytebits_to_byte(bits + 8 + (fmtLen-17), 16);
code1 = bytebits_to_byte(bits + 8, fmtLen);
PrintAndLog("AWID Found - BitLength: %d -unknown BitLength- (%u) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo);
}
break;
}
if (g_debugMode){
PrintAndLog("DEBUG: AWID idx: %d, Len: %d Printing Demod Buffer:", idx, 96);
printDemodBuff();
}
return 1;
}
int CmdAWIDSim(const char *Cmd) {
uint32_t fc = 0, cn = 0;
uint8_t fmtlen = 0;
@ -320,7 +453,7 @@ int CmdAWIDClone(const char *Cmd) {
return 0;
}
int CmdAWIDBrute(const char *Cmd){
int CmdAWIDBrute(const char *Cmd) {
bool errors = false;
uint32_t fc = 0, cn = 0, delay = 1000;
@ -399,6 +532,7 @@ int CmdAWIDBrute(const char *Cmd){
return 2;
}
if (ukbhit()) {
int gc = getchar(); (void)gc;
PrintAndLog("aborted via keyboard!");
return sendPing();
}
@ -416,12 +550,12 @@ int CmdAWIDBrute(const char *Cmd){
}
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"fskdemod", CmdAWIDDemodFSK, 0, "Realtime AWID FSK demodulator"},
{"read", CmdAWIDRead, 0, "Attempt to read and extract tag data"},
{"sim", CmdAWIDSim, 0, "AWID tag simulator"},
{"clone", CmdAWIDClone, 0, "Clone AWID to T55x7"},
{"brute", CmdAWIDBrute, 0, "Bruteforce card number against reader"},
{"help", CmdHelp, 1, "This help"},
{"demod", CmdAWIDDemod, 0, "Demodulate an AWID FSK tag from the GraphBuffer"},
{"read", CmdAWIDRead, 0, "Attempt to read and extract tag data"},
{"sim", CmdAWIDSim, 0, "AWID tag simulator"},
{"clone", CmdAWIDClone, 0, "Clone AWID to T55x7"},
{"brute", CmdAWIDBrute, 0, "Bruteforce card number against reader"},
{NULL, NULL, 0, NULL}
};

View file

@ -21,19 +21,20 @@
#include "cmdlf.h" // lf read
#include "protocols.h" // for T55xx config register definitions
#include "cmdmain.h"
#include "sleep.h"
#include "util_posix.h"
int CmdLFAWID(const char *Cmd);
int CmdAWIDDemodFSK(const char *Cmd);
int CmdAWIDRead(const char *Cmd);
int CmdAWIDSim(const char *Cmd);
int CmdAWIDClone(const char *Cmd);
int CmdAWIDBrute(const char *Cmd);
int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *AWIDBits);
int usage_lf_awid_fskdemod(void);
int usage_lf_awid_clone(void);
int usage_lf_awid_sim(void);
int usage_lf_awid_brute(void);
extern int CmdLFAWID(const char *Cmd);
extern int CmdAWIDDemod(const char *Cmd);
extern int CmdAWIDRead(const char *Cmd);
extern int CmdAWIDSim(const char *Cmd);
extern int CmdAWIDClone(const char *Cmd);
extern int CmdAWIDBrute(const char *Cmd);
extern int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits);
extern int usage_lf_awid_read(void);
extern int usage_lf_awid_sim(void);
extern int usage_lf_awid_clone(void);
extern int usage_lf_awid_brute(void);
#endif

View file

@ -33,7 +33,8 @@ int CmdCOTAGDemod(const char *Cmd) {
size_t bitlen = COTAG_BITS;
memcpy(bits, DemodBuffer, COTAG_BITS);
int err = manrawdecode(bits, &bitlen, 1);
uint8_t alignPos = 0;
int err = manrawdecode(bits, &bitlen, 1, &alignPos);
if (err){
if (g_debugMode) PrintAndLog("DEBUG: Error - COTAG too many errors: %d", err);
return -1;
@ -85,7 +86,7 @@ int CmdCOTAGRead(const char *Cmd) {
case 2: {
CmdPlot("");
CmdGrid("384");
getSamples("", true); break;
getSamples(0, true); break;
}
case 1: {
GetFromBigBuf(DemodBuffer, COTAG_BITS, 0);

View file

@ -1,11 +1,11 @@
//-----------------------------------------------------------------------------
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
// Authored by Iceman
//
// 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.
//-----------------------------------------------------------------------------
// Low frequency AWID commands
// Low frequency COTAG commands
//-----------------------------------------------------------------------------
#ifndef CMDLFCOTAG_H__
@ -23,9 +23,9 @@
#define COTAG_BITS 264
#endif
int CmdLFCOTAG(const char *Cmd);
int CmdCOTAGRead(const char *Cmd);
int CmdCOTAGDemod(const char *Cmd);
extern int CmdLFCOTAG(const char *Cmd);
extern int CmdCOTAGRead(const char *Cmd);
extern int CmdCOTAGDemod(const char *Cmd);
int usage_lf_cotag_read(void);
extern int usage_lf_cotag_read(void);
#endif

View file

@ -14,6 +14,56 @@ uint64_t g_em410xid = 0;
static int CmdHelp(const char *Cmd);
//////////////// 410x commands
int usage_lf_em410x_demod(void){
PrintAndLog("Usage: data askem410xdemod [clock] <0|1> [maxError]");
PrintAndLog(" [set clock as integer] optional, if not set, autodetect.");
PrintAndLog(" <invert>, 1 for invert output");
PrintAndLog(" [set maximum allowed errors], default = 100.");
PrintAndLog("");
PrintAndLog(" sample: data askem410xdemod = demod an EM410x Tag ID from GraphBuffer");
PrintAndLog(" : data askem410xdemod 32 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32");
PrintAndLog(" : data askem410xdemod 32 1 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32 and inverting data");
PrintAndLog(" : data askem410xdemod 1 = demod an EM410x Tag ID from GraphBuffer while inverting data");
PrintAndLog(" : data askem410xdemod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors");
return 0;
}
int usage_lf_em410x_write(void) {
PrintAndLog("Writes EM410x ID to a T55x7 / T5555 (Q5) tag");
PrintAndLog("");
PrintAndLog("Usage: lf em 410xwrite [h] <id> <card> [clock]");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" <id> - ID number");
PrintAndLog(" <card> - 0|1 T5555 (Q5) / T55x7");
PrintAndLog(" <clock> - 16|32|40|64, optional, set R/F clock rate, defaults to 64");
PrintAndLog("samples:");
PrintAndLog(" lf em 410xwrite 0F0368568B");
return 0;
}
int usage_lf_em410x_ws(void) {
PrintAndLog("Watch 'nd Spoof, activates reader, waits until a EM410x tag gets presented then it starts simulating the found UID");
PrintAndLog("");
PrintAndLog("Usage: lf em 410xspoof [h]");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog("samples:");
PrintAndLog(" lf em 410xspoof");
return 0;
}
int usage_lf_em410x_clone(void) {
PrintAndLog("Simulating EM410x tag");
PrintAndLog("");
PrintAndLog("Usage: lf em 410xclone [h] <uid> <clock>");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" uid - uid (10 HEX symbols)");
PrintAndLog(" clock - clock (32|64) (optional)");
PrintAndLog("samples:");
PrintAndLog(" lf em 410xclone 0F0368568B");
PrintAndLog(" lf em 410xclone 0F0368568B 32");
return 0;
}
int usage_lf_em410x_sim(void) {
PrintAndLog("Simulating EM410x tag");
PrintAndLog("");
@ -27,57 +77,122 @@ int usage_lf_em410x_sim(void) {
PrintAndLog(" lf em 410xsim 0F0368568B 32");
return 0;
}
int CmdEMdemodASK(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0);
uint8_t findone = (cmdp == '1') ? 1 : 0;
UsbCommand c = {CMD_EM410X_DEMOD, {findone, 0, 0}};
SendCommand(&c);
int usage_lf_em410x_brute(void) {
PrintAndLog("Bruteforcing by emulating EM410x tag");
PrintAndLog("");
PrintAndLog("Usage: lf em 410xbrute [h] ids.txt [d 2000] [c clock]");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" ids.txt - file with UIDs in HEX format, one per line");
PrintAndLog(" d (2000) - pause delay in milliseconds between UIDs simulation, default 1000 ms (optional)");
PrintAndLog(" c (32) - clock (32|64), default 64 (optional)");
PrintAndLog("samples:");
PrintAndLog(" lf em 410xbrute ids.txt");
PrintAndLog(" lf em 410xbrute ids.txt c 32");
PrintAndLog(" lf em 410xbrute ids.txt d 3000");
PrintAndLog(" lf em 410xbrute ids.txt d 3000 c 32");
return 0;
}
/* 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)
{
uint32_t hi = 0;
uint64_t lo = 0;
if(!AskEm410xDemod("", &hi, &lo, false)) return 0;
printEM410x(hi, lo);
g_em410xid = lo;
return 1;
//////////////// 4050 / 4450 commands
int usage_lf_em4x50_dump(void) {
PrintAndLog("Dump EM4x50/EM4x69. Tag must be on antenna. ");
PrintAndLog("");
PrintAndLog("Usage: lf em 4x50dump [h] <pwd>");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" pwd - password (hex) (optional)");
PrintAndLog("samples:");
PrintAndLog(" lf em 4x50dump");
PrintAndLog(" lf em 4x50dump 11223344");
return 0;
}
int usage_lf_em4x50_read(void) {
PrintAndLog("Read EM 4x50/EM4x69. Tag must be on antenna. ");
PrintAndLog("");
PrintAndLog("Usage: lf em 4x50read [h] <address> <pwd>");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" address - memory address to read. (0-15)");
PrintAndLog(" pwd - password (hex) (optional)");
PrintAndLog("samples:");
PrintAndLog(" lf em 4x50read 1");
PrintAndLog(" lf em 4x50read 1 11223344");
return 0;
}
int usage_lf_em4x50_write(void) {
PrintAndLog("Write EM 4x50/4x69. Tag must be on antenna. ");
PrintAndLog("");
PrintAndLog("Usage: lf em 4x50write [h] <address> <data> <pwd>");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" address - memory address to write to. (0-15)");
PrintAndLog(" data - data to write (hex)");
PrintAndLog(" pwd - password (hex) (optional)");
PrintAndLog("samples:");
PrintAndLog(" lf em 4x50write 1 deadc0de");
PrintAndLog(" lf em 4x50write 1 deadc0de 11223344");
return 0;
}
// emulate an EM410X tag
int CmdEM410xSim(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
if (cmdp == 'h' || cmdp == 'H') return usage_lf_em410x_sim();
//////////////// 4205 / 4305 commands
int usage_lf_em4x05_dump(void) {
PrintAndLog("Dump EM4x05/EM4x69. Tag must be on antenna. ");
PrintAndLog("");
PrintAndLog("Usage: lf em 4x05dump [h] <pwd>");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" pwd - password (hex) (optional)");
PrintAndLog("samples:");
PrintAndLog(" lf em 4x05dump");
PrintAndLog(" lf em 4x05dump 11223344");
return 0;
}
int usage_lf_em4x05_read(void) {
PrintAndLog("Read EM4x05/EM4x69. Tag must be on antenna. ");
PrintAndLog("");
PrintAndLog("Usage: lf em 4x05read [h] <address> <pwd>");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" address - memory address to read. (0-15)");
PrintAndLog(" pwd - password (hex) (optional)");
PrintAndLog("samples:");
PrintAndLog(" lf em 4x05read 1");
PrintAndLog(" lf em 4x05read 1 11223344");
return 0;
}
int usage_lf_em4x05_write(void) {
PrintAndLog("Write EM4x05/4x69. Tag must be on antenna. ");
PrintAndLog("");
PrintAndLog("Usage: lf em 4x05write [h] <address> <data> <pwd>");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" address - memory address to write to. (0-15)");
PrintAndLog(" data - data to write (hex)");
PrintAndLog(" pwd - password (hex) (optional)");
PrintAndLog("samples:");
PrintAndLog(" lf em 4x05write 1 deadc0de");
PrintAndLog(" lf em 4x05write 1 deadc0de 11223344");
return 0;
}
int usage_lf_em4x05_info(void) {
PrintAndLog("Tag information EM4205/4305/4469//4569 tags. Tag must be on antenna.");
PrintAndLog("");
PrintAndLog("Usage: lf em 4x05info [h] <pwd>");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" pwd - password (hex) (optional)");
PrintAndLog("samples:");
PrintAndLog(" lf em 4x05info");
PrintAndLog(" lf em 4x05info deadc0de");
return 0;
}
// Construct the graph for emulating an EM410X tag
void ConstructEM410xEmulGraph(const char *uid,const uint8_t clock) {
int i, n, j, binary[4], parity[4];
uint8_t uid[5] = {0x00};
/* clock is 64 in EM410x tags */
uint8_t clock = 64;
if (param_gethex(Cmd, 0, uid, 10)) {
PrintAndLog("UID must include 10 HEX symbols");
return 0;
}
param_getdec(Cmd, 1, &clock);
PrintAndLog("Starting simulating UID %02X%02X%02X%02X%02X clock: %d", uid[0],uid[1],uid[2],uid[3],uid[4],clock);
PrintAndLog("Press pm3-button to about simulation");
/* clear our graph */
ClearGraph(0);
@ -87,10 +202,9 @@ int CmdEM410xSim(const char *Cmd) {
/* for each hex char */
parity[0] = parity[1] = parity[2] = parity[3] = 0;
for (i = 0; i < 10; i++)
{
for (i = 0; i < 10; i++){
/* read each hex char */
sscanf(&Cmd[i], "%1x", &n);
sscanf(&uid[i], "%1x", &n);
for (j = 3; j >= 0; j--, n/= 2)
binary[j] = n % 2;
@ -118,11 +232,330 @@ int CmdEM410xSim(const char *Cmd) {
/* stop bit */
AppendGraph(1, clock, 0);
}
//by marshmellow
//print 64 bit EM410x ID in multiple formats
void printEM410x(uint32_t hi, uint64_t id) {
if (!id && !hi) return;
PrintAndLog("EM410x %s pattern found", (hi) ? "XL" : "" );
uint64_t iii=1;
uint64_t id2lo=0;
uint32_t ii=0;
uint32_t i=0;
for (ii=5; ii>0;ii--){
for (i=0;i<8;i++){
id2lo=(id2lo<<1LL) | ((id & (iii << (i+((ii-1)*8)))) >> (i+((ii-1)*8)));
}
}
if (hi){
//output 88 bit em id
PrintAndLog("\nEM TAG ID : %06X%016" PRIX64, hi, id);
} else {
//output 40 bit em id
PrintAndLog("\nEM TAG ID : %010" PRIX64, id);
PrintAndLog("\nPossible de-scramble patterns");
PrintAndLog("Unique TAG ID : %010" PRIX64, id2lo);
PrintAndLog("HoneyWell IdentKey {");
PrintAndLog("DEZ 8 : %08" PRIu64, id & 0xFFFFFF);
PrintAndLog("DEZ 10 : %010" PRIu64, id & 0xFFFFFFFF);
PrintAndLog("DEZ 5.5 : %05" PRIu64 ".%05" PRIu64, (id>>16LL) & 0xFFFF, (id & 0xFFFF));
PrintAndLog("DEZ 3.5A : %03" PRIu64 ".%05" PRIu64, (id>>32ll), (id & 0xFFFF));
PrintAndLog("DEZ 3.5B : %03" PRIu64 ".%05" PRIu64, (id & 0xFF000000) >> 24, (id & 0xFFFF));
PrintAndLog("DEZ 3.5C : %03" PRIu64 ".%05" PRIu64, (id & 0xFF0000) >> 16, (id & 0xFFFF));
PrintAndLog("DEZ 14/IK2 : %014" PRIu64, id);
PrintAndLog("DEZ 15/IK3 : %015" PRIu64, id2lo);
PrintAndLog("DEZ 20/ZK : %02" PRIu64 "%02" PRIu64 "%02" PRIu64 "%02" PRIu64 "%02" PRIu64 "%02" PRIu64 "%02" PRIu64 "%02" PRIu64 "%02" PRIu64 "%02" PRIu64,
(id2lo & 0xf000000000) >> 36,
(id2lo & 0x0f00000000) >> 32,
(id2lo & 0x00f0000000) >> 28,
(id2lo & 0x000f000000) >> 24,
(id2lo & 0x0000f00000) >> 20,
(id2lo & 0x00000f0000) >> 16,
(id2lo & 0x000000f000) >> 12,
(id2lo & 0x0000000f00) >> 8,
(id2lo & 0x00000000f0) >> 4,
(id2lo & 0x000000000f)
);
uint64_t paxton = (((id>>32) << 24) | (id & 0xffffff)) + 0x143e00;
PrintAndLog("}\nOther : %05" PRIu64 "_%03" PRIu64 "_%08" PRIu64, (id&0xFFFF), ((id>>16LL) & 0xFF), (id & 0xFFFFFF));
PrintAndLog("Pattern Paxton : %" PRIu64 " [0x%" PRIX64 "]", paxton, paxton);
uint32_t p1id = (id & 0xFFFFFF);
uint8_t arr[32] = {0x00};
int i =0;
int j = 23;
for (; i < 24; ++i, --j ){
arr[i] = (p1id >> i) & 1;
}
uint32_t p1 = 0;
p1 |= arr[23] << 21;
p1 |= arr[22] << 23;
p1 |= arr[21] << 20;
p1 |= arr[20] << 22;
p1 |= arr[19] << 18;
p1 |= arr[18] << 16;
p1 |= arr[17] << 19;
p1 |= arr[16] << 17;
p1 |= arr[15] << 13;
p1 |= arr[14] << 15;
p1 |= arr[13] << 12;
p1 |= arr[12] << 14;
p1 |= arr[11] << 6;
p1 |= arr[10] << 2;
p1 |= arr[9] << 7;
p1 |= arr[8] << 1;
p1 |= arr[7] << 0;
p1 |= arr[6] << 8;
p1 |= arr[5] << 11;
p1 |= arr[4] << 3;
p1 |= arr[3] << 10;
p1 |= arr[2] << 4;
p1 |= arr[1] << 5;
p1 |= arr[0] << 9;
PrintAndLog("Pattern 1 : %d [0x%X]", p1, p1);
uint16_t sebury1 = id & 0xFFFF;
uint8_t sebury2 = (id >> 16) & 0x7F;
uint32_t sebury3 = id & 0x7FFFFF;
PrintAndLog("Pattern Sebury : %d %d %d [0x%X 0x%X 0x%X]", sebury1, sebury2, sebury3, sebury1, sebury2, sebury3);
}
}
/* 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 AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo ) {
size_t idx = 0;
size_t size = DemodBufferLen;
uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0};
memcpy(BitStream, DemodBuffer, size);
int ans = Em410xDecode(BitStream, &size, &idx, hi, lo);
if ( ans < 0){
if (g_debugMode){
if (ans == -1)
PrintAndLog("DEBUG: Error - Em410x not only 0|1 in decoded bitstream");
else if (ans == -2)
PrintAndLog("DEBUG: Error - Em410x preamble not found");
else if (ans == -3)
PrintAndLog("DEBUG: Error - Em410x Size not correct: %d", size);
else if (ans == -4)
PrintAndLog("DEBUG: Error - Em410x parity failed");
}
return 0;
}
if (!lo && !hi) {
PrintAndLog("DEBUG: Error - Em410x decoded to all zeros");
return 0;
}
//set GraphBuffer for clone or sim command
setDemodBuf(BitStream, size, idx);
if (g_debugMode){
PrintAndLog("DEBUG: Em410x idx: %d, Len: %d, Printing Demod Buffer:", idx, size);
printDemodBuff();
}
if (verbose)
printEM410x(*hi, *lo);
return 1;
}
int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose) {
bool st = true;
if (!ASKDemod_ext(Cmd, false, false, 1, &st)) return 0;
return AskEm410xDecode(verbose, hi, lo);
}
//by marshmellow
//takes 3 arguments - clock, invert and maxErr as integers
//attempts to demodulate ask while decoding manchester
//prints binary found and saves in graphbuffer for further commands
int CmdAskEM410xDemod(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H')
return usage_lf_em410x_demod();
uint64_t lo = 0;
uint32_t hi = 0;
return AskEm410xDemod(Cmd, &hi, &lo, true);
}
int CmdEMdemodASK(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
uint8_t findone = (cmdp == '1') ? 1 : 0;
UsbCommand c = {CMD_EM410X_DEMOD, {findone, 0, 0}};
SendCommand(&c);
return 0;
}
/* 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) {
uint32_t hi = 0;
uint64_t lo = 0;
if(!AskEm410xDemod("", &hi, &lo, false)) return 0;
printEM410x(hi, lo);
g_em410xid = lo;
return 1;
}
// emulate an EM410X tag
int CmdEM410xSim(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
if (cmdp == 'h' || cmdp == 'H') return usage_lf_em410x_sim();
uint8_t uid[5] = {0x00};
/* clock is 64 in EM410x tags */
uint8_t clock = 64;
if (param_gethex(Cmd, 0, uid, 10)) {
PrintAndLog("UID must include 10 HEX symbols");
return 0;
}
param_getdec(Cmd, 1, &clock);
PrintAndLog("Starting simulating UID %02X%02X%02X%02X%02X clock: %d", uid[0],uid[1],uid[2],uid[3],uid[4],clock);
PrintAndLog("Press pm3-button to abort simulation");
ConstructEM410xEmulGraph(Cmd, clock);
CmdLFSim("0"); //240 start_gap.
return 0;
}
int CmdEM410xBrute(const char *Cmd) {
char filename[FILE_PATH_SIZE] = {0};
FILE *f = NULL;
char buf[11];
uint32_t uidcnt = 0;
uint8_t stUidBlock = 20;
uint8_t *uidBlock = NULL, *p = NULL;
uint8_t uid[5] = {0x00};
/* clock is 64 in EM410x tags */
uint8_t clock = 64;
/* default pause time: 1 second */
uint32_t delay = 1000;
char cmdp = param_getchar(Cmd, 0);
if (cmdp == 'h' || cmdp == 'H') return usage_lf_em410x_brute();
cmdp = param_getchar(Cmd, 1);
if (cmdp == 'd' || cmdp == 'D') {
delay = param_get32ex(Cmd, 2, 1000, 10);
param_getdec(Cmd, 4, &clock);
} else if (cmdp == 'c' || cmdp == 'C') {
param_getdec(Cmd, 2, &clock);
delay = param_get32ex(Cmd, 4, 1000, 10);
}
param_getstr(Cmd, 0, filename);
if (strlen(filename) == 0) {
PrintAndLog("Error: Please specify a filename");
return 1;
}
if ((f = fopen(filename, "r")) == NULL) {
PrintAndLog("Error: Could not open UIDs file [%s]", filename);
return 1;
}
uidBlock = calloc(stUidBlock, 5);
if (uidBlock == NULL) return 1;
while( fgets(buf, sizeof(buf), f) ) {
if (strlen(buf) < 10 || buf[9] == '\n') continue;
while (fgetc(f) != '\n' && !feof(f)); //goto next line
//The line start with # is comment, skip
if( buf[0]=='#' ) continue;
if (param_gethex(buf, 0, uid, 10)) {
PrintAndLog("UIDs must include 10 HEX symbols");
free(uidBlock);
fclose(f);
return 1;
}
buf[10] = 0;
if ( stUidBlock - uidcnt < 2) {
p = realloc(uidBlock, 5 * (stUidBlock += 10) );
if (!p) {
PrintAndLog("Cannot allocate memory for UIDs");
free(uidBlock);
fclose(f);
return 1;
}
uidBlock = p;
}
memset(uidBlock + 5 * uidcnt, 0, 5);
num_to_bytes(strtoll(buf, NULL, 16), 5, uidBlock + 5 * uidcnt);
uidcnt++;
memset(buf, 0, sizeof(buf));
}
fclose(f);
if (uidcnt == 0) {
PrintAndLog("No UIDs found in file");
free(uidBlock);
return 1;
}
PrintAndLog("Loaded %d UIDs from %s, pause delay: %d ms", uidcnt, filename, delay);
// loop
for(uint32_t c = 0; c < uidcnt; ++c ) {
char testuid[11];
testuid[10] = 0;
if (ukbhit()) {
int gc = getchar(); (void)gc;
printf("\nAborted via keyboard!\n");
free(uidBlock);
return 0;
}
sprintf(testuid, "%010" PRIX64, bytes_to_num(uidBlock + 5*c, 5));
PrintAndLog("Bruteforce %d / %d: simulating UID %s, clock %d", c + 1, uidcnt, testuid, clock);
ConstructEM410xEmulGraph(testuid, clock);
CmdLFSim("0"); //240 start_gap.
msleep(delay);
}
free(uidBlock);
return 0;
}
/* Function is equivalent of lf read + data samples + em410xread
* looped until an EM410x tag is detected
*
@ -137,33 +570,38 @@ int CmdEM410xSim(const char *Cmd) {
int CmdEM410xWatch(const char *Cmd) {
do {
if (ukbhit()) {
int gc = getchar(); (void)gc;
printf("\naborted via keyboard!\n");
break;
}
CmdLFRead("s");
getSamples("6144",true);
lf_read(true, 8201);
} while (!CmdEM410xRead(""));
return 0;
}
//currently only supports manchester modulations
// todo: helptext
int CmdEM410xWatchnSpoof(const char *Cmd)
{
int CmdEM410xWatchnSpoof(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
if (cmdp == 'h' || cmdp == 'H') return usage_lf_em410x_ws();
// loops if the captured ID was in XL-format.
CmdEM410xWatch(Cmd);
PrintAndLog("# Replaying captured ID: %" PRIu64 , g_em410xid);
PrintAndLog("# Replaying captured ID: %010" PRIx64 , g_em410xid);
CmdLFaskSim("");
return 0;
}
int CmdEM410xWrite(const char *Cmd)
{
int CmdEM410xWrite(const char *Cmd) {
char cmdp = param_getchar(Cmd, 0);
if (cmdp == 'h' || cmdp == 'H') return usage_lf_em410x_write();
uint64_t id = 0xFFFFFFFFFFFFFFFF; // invalid id value
int card = 0xFF; // invalid card value
uint32_t clock = 0; // invalid clock value
sscanf(Cmd, "%" PRIx64 " %d %d", &id, &card, &clock);
sscanf(Cmd, "%" SCNx64 " %d %d", &id, &card, &clock);
// Check ID
if (id == 0xFFFFFFFFFFFFFFFF) {
@ -186,7 +624,6 @@ int CmdEM410xWrite(const char *Cmd)
}
// Check Clock
// Default: 64
if (clock == 0)
clock = 64;
@ -216,8 +653,8 @@ int CmdEM410xWrite(const char *Cmd)
return 0;
}
bool EM_EndParityTest(uint8_t *BitStream, size_t size, uint8_t rows, uint8_t cols, uint8_t pType)
{
//**************** Start of EM4x50 Code ************************
bool EM_EndParityTest(uint8_t *BitStream, size_t size, uint8_t rows, uint8_t cols, uint8_t pType) {
if (rows*cols>size) return false;
uint8_t colP=0;
//assume last col is a parity and do not test
@ -230,8 +667,7 @@ bool EM_EndParityTest(uint8_t *BitStream, size_t size, uint8_t rows, uint8_t col
return true;
}
bool EM_ByteParityTest(uint8_t *BitStream, size_t size, uint8_t rows, uint8_t cols, uint8_t pType)
{
bool EM_ByteParityTest(uint8_t *BitStream, size_t size, uint8_t rows, uint8_t cols, uint8_t pType) {
if (rows*cols>size) return false;
uint8_t rowP=0;
//assume last row is a parity row and do not test
@ -281,50 +717,9 @@ bool EMwordparitytest(uint8_t *bits){
return true;
}
//////////////// 4050 / 4450 commands
int usage_lf_em4x50_dump(void) {
PrintAndLog("Dump EM4x50/EM4x69. Tag must be on antenna. ");
PrintAndLog("");
PrintAndLog("Usage: lf em 4x50dump [h] <pwd>");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" pwd - password (hex) (optional)");
PrintAndLog("samples:");
PrintAndLog(" lf em 4x50dump");
PrintAndLog(" lf em 4x50dump 11223344");
return 0;
}
int usage_lf_em4x50_read(void) {
PrintAndLog("Read EM 4x50/EM4x69. Tag must be on antenna. ");
PrintAndLog("");
PrintAndLog("Usage: lf em 4x50read [h] <address> <pwd>");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" address - memory address to read. (0-15)");
PrintAndLog(" pwd - password (hex) (optional)");
PrintAndLog("samples:");
PrintAndLog(" lf em 4x50read 1");
PrintAndLog(" lf em 4x50read 1 11223344");
return 0;
}
int usage_lf_em4x50_write(void) {
PrintAndLog("Write EM 4x50/4x69. Tag must be on antenna. ");
PrintAndLog("");
PrintAndLog("Usage: lf em 4x50write [h] <address> <data> <pwd>");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" address - memory address to write to. (0-15)");
PrintAndLog(" data - data to write (hex)");
PrintAndLog(" pwd - password (hex) (optional)");
PrintAndLog("samples:");
PrintAndLog(" lf em 4x50write 1 deadc0de");
PrintAndLog(" lf em 4x50write 1 deadc0de 11223344");
return 0;
}
uint32_t OutputEM4x50_Block(uint8_t *BitStream, size_t size, bool verbose, bool pTest)
{
uint32_t OutputEM4x50_Block(uint8_t *BitStream, size_t size, bool verbose, bool pTest) {
if (size<45) return 0;
uint32_t code = bytebits_to_byte(BitStream,8);
@ -394,9 +789,6 @@ int EM4x50Read(const char *Cmd, bool verbose) {
// get user entry if any
sscanf(Cmd, "%i %i", &clk, &invert);
// save GraphBuffer - to restore it later
save_restoreGB(1);
// first get high and low values
for (i = 0; i < GraphTraceLen; i++) {
if (GraphBuffer[i] > high)
@ -496,6 +888,8 @@ int EM4x50Read(const char *Cmd, bool verbose) {
} else if (start < 0) return 0;
start = skip;
snprintf(tmp2, sizeof(tmp2),"%d %d 1000 %d", clk, invert, clk*47);
// save GraphBuffer - to restore it later
save_restoreGB(GRAPH_SAVE);
// get rid of leading crap
snprintf(tmp, sizeof(tmp), "%i", skip);
CmdLtrim(tmp);
@ -523,7 +917,7 @@ int EM4x50Read(const char *Cmd, bool verbose) {
phaseoff = 0;
i += 2;
if (ASKDemod(tmp2, false, false, 1) < 1) {
save_restoreGB(0);
save_restoreGB(GRAPH_RESTORE);
return 0;
}
//set DemodBufferLen to just one block
@ -562,7 +956,7 @@ int EM4x50Read(const char *Cmd, bool verbose) {
}
//restore GraphBuffer
save_restoreGB(0);
save_restoreGB(GRAPH_RESTORE);
return (int)AllPTest;
}
@ -731,58 +1125,6 @@ bool demodEM4x05resp(uint32_t *word) {
}
//////////////// 4205 / 4305 commands
int usage_lf_em4x05_dump(void) {
PrintAndLog("Dump EM4x05/EM4x69. Tag must be on antenna. ");
PrintAndLog("");
PrintAndLog("Usage: lf em 4x05dump [h] <pwd>");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" pwd - password (hex) (optional)");
PrintAndLog("samples:");
PrintAndLog(" lf em 4x05dump");
PrintAndLog(" lf em 4x05dump 11223344");
return 0;
}
int usage_lf_em4x05_read(void) {
PrintAndLog("Read EM4x05/EM4x69. Tag must be on antenna. ");
PrintAndLog("");
PrintAndLog("Usage: lf em 4x05read [h] <address> <pwd>");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" address - memory address to read. (0-15)");
PrintAndLog(" pwd - password (hex) (optional)");
PrintAndLog("samples:");
PrintAndLog(" lf em 4x05read 1");
PrintAndLog(" lf em 4x05read 1 11223344");
return 0;
}
int usage_lf_em4x05_write(void) {
PrintAndLog("Write EM4x05/4x69. Tag must be on antenna. ");
PrintAndLog("");
PrintAndLog("Usage: lf em 4x05write [h] <address> <data> <pwd>");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" address - memory address to write to. (0-15)");
PrintAndLog(" data - data to write (hex)");
PrintAndLog(" pwd - password (hex) (optional)");
PrintAndLog("samples:");
PrintAndLog(" lf em 4x05write 1 deadc0de");
PrintAndLog(" lf em 4x05write 1 deadc0de 11223344");
return 0;
}
int usage_lf_em4x05_info(void) {
PrintAndLog("Tag information EM4205/4305/4469//4569 tags. Tag must be on antenna.");
PrintAndLog("");
PrintAndLog("Usage: lf em 4x05info [h] <pwd>");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" pwd - password (hex) (optional)");
PrintAndLog("samples:");
PrintAndLog(" lf em 4x05info");
PrintAndLog(" lf em 4x05info deadc0de");
return 0;
}
int EM4x05ReadWord_ext(uint8_t addr, uint32_t pwd, bool usePwd, uint32_t *word) {
UsbCommand c = {CMD_EM4X_READ_WORD, {addr, pwd, usePwd}};
clearCommandBuffer();
@ -852,8 +1194,7 @@ int CmdEM4x05Read(const char *Cmd) {
}
if ( pwd == 1 ) {
PrintAndLog("Reading address %02u", addr);
}
else {
} else {
usePwd = true;
PrintAndLog("Reading address %02u | password %08X", addr, pwd);
}
@ -927,8 +1268,8 @@ void printEM4x05config(uint32_t wordData) {
uint8_t delay = (wordData >> 12) & 0x3;
char cdelay[33];
memset(cdelay,0,sizeof(cdelay));
uint8_t LWR = (wordData >> 14) & 0xF; //last word read
uint8_t numblks = EM4x05_GET_NUM_BLOCKS(wordData);
uint8_t LWR = numblks+5-1; //last word read
switch (encoder) {
case 0: snprintf(enc,sizeof(enc),"NRZ"); break;
case 1: snprintf(enc,sizeof(enc),"Manchester"); break;
@ -956,21 +1297,29 @@ void printEM4x05config(uint32_t wordData) {
case 2: snprintf(cdelay, sizeof(cdelay),"BP/4 or 1/4th bit period delay"); break;
case 3: snprintf(cdelay, sizeof(cdelay),"no delay"); break;
}
uint8_t readLogin = (wordData & EM4x05_READ_LOGIN_REQ)>>18;
uint8_t readHKL = (wordData & EM4x05_READ_HK_LOGIN_REQ)>>19;
uint8_t writeLogin = (wordData & EM4x05_WRITE_LOGIN_REQ)>>20;
uint8_t writeHKL = (wordData & EM4x05_WRITE_HK_LOGIN_REQ)>>21;
uint8_t raw = (wordData & EM4x05_READ_AFTER_WRITE)>>22;
uint8_t disable = (wordData & EM4x05_DISABLE_ALLOWED)>>23;
uint8_t rtf = (wordData & EM4x05_READER_TALK_FIRST)>>24;
uint8_t pigeon = (wordData & (1<<26))>>26;
PrintAndLog("ConfigWord: %08X (Word 4)\n", wordData);
PrintAndLog("Config Breakdown:", wordData);
PrintAndLog("Config Breakdown:");
PrintAndLog(" Data Rate: %02u | RF/%u", wordData & 0x3F, datarate);
PrintAndLog(" Encoder: %u | %s", encoder, enc);
PrintAndLog(" PSK CF: %u | %s", PSKcf, cf);
PrintAndLog(" Delay: %u | %s", delay, cdelay);
PrintAndLog(" LastWordR: %02u | Address of last word for default read", LWR);
PrintAndLog(" ReadLogin: %u | Read Login is %s", (wordData & 0x40000)>>18, (wordData & 0x40000) ? "Required" : "Not Required");
PrintAndLog(" ReadHKL: %u | Read Housekeeping Words Login is %s", (wordData & 0x80000)>>19, (wordData & 0x80000) ? "Required" : "Not Required");
PrintAndLog("WriteLogin: %u | Write Login is %s", (wordData & 0x100000)>>20, (wordData & 0x100000) ? "Required" : "Not Required");
PrintAndLog(" WriteHKL: %u | Write Housekeeping Words Login is %s", (wordData & 0x200000)>>21, (wordData & 0x200000) ? "Required" : "Not Required");
PrintAndLog(" R.A.W.: %u | Read After Write is %s", (wordData & 0x400000)>>22, (wordData & 0x400000) ? "On" : "Off");
PrintAndLog(" Disable: %u | Disable Command is %s", (wordData & 0x800000)>>23, (wordData & 0x800000) ? "Accepted" : "Not Accepted");
PrintAndLog(" R.T.F.: %u | Reader Talk First is %s", (wordData & 0x1000000)>>24, (wordData & 0x1000000) ? "Enabled" : "Disabled");
PrintAndLog(" Pigeon: %u | Pigeon Mode is %s\n", (wordData & 0x4000000)>>26, (wordData & 0x4000000) ? "Enabled" : "Disabled");
PrintAndLog(" LastWordR: %02u | Address of last word for default read - meaning %u blocks are output", LWR, numblks);
PrintAndLog(" ReadLogin: %u | Read Login is %s", readLogin, readLogin ? "Required" : "Not Required");
PrintAndLog(" ReadHKL: %u | Read Housekeeping Words Login is %s", readHKL, readHKL ? "Required" : "Not Required");
PrintAndLog("WriteLogin: %u | Write Login is %s", writeLogin, writeLogin ? "Required" : "Not Required");
PrintAndLog(" WriteHKL: %u | Write Housekeeping Words Login is %s", writeHKL, writeHKL ? "Required" : "Not Required");
PrintAndLog(" R.A.W.: %u | Read After Write is %s", raw, raw ? "On" : "Off");
PrintAndLog(" Disable: %u | Disable Command is %s", disable, disable ? "Accepted" : "Not Accepted");
PrintAndLog(" R.T.F.: %u | Reader Talk First is %s", rtf, rtf ? "Enabled" : "Disabled");
PrintAndLog(" Pigeon: %u | Pigeon Mode is %s\n", pigeon, pigeon ? "Enabled" : "Disabled");
}
void printEM4x05info(uint32_t block0, uint32_t serial) {
@ -1065,19 +1414,20 @@ int CmdEM4x05Info(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"410xdemod", CmdEMdemodASK, 0, "[findone] -- Extract ID from EM410x tag (option 0 for continuous loop, 1 for only 1 tag)"},
{"410xread", CmdEM410xRead, 1, "[clock rate] -- Extract ID from EM410x tag in GraphBuffer"},
{"410xsim", CmdEM410xSim, 0, "simulate EM410x tag"},
{"410xwatch", CmdEM410xWatch, 0, "['h'] -- Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
{"410xspoof", CmdEM410xWatchnSpoof, 0, "['h'] --- Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
{"410xwrite", CmdEM410xWrite, 0, "<UID> <'0' T5555> <'1' T55x7> [clock rate] -- Write EM410x UID to T5555(Q5) or T55x7 tag, optionally setting clock rate"},
{"4x05dump", CmdEM4x05Dump, 0, "dump EM4205/4305 tag"},
{"4x05info", CmdEM4x05Info, 0, "tag information EM4x05/EM4x69"},
{"4x05read", CmdEM4x05Read, 0, "read word data from EM4205/4305"},
{"4x05write", CmdEM4x05Write, 0, "write word data to EM4205/4305"},
{"4x50read", CmdEM4x50Read, 0, "read word data from EM4x50"},
{"4x50write", CmdEM4x50Write, 0, "write word data to EM4x50"},
{"4x50dump", CmdEM4x50Dump, 0, "dump EM4x50 tag"},
{"410x_demod", CmdEMdemodASK, 0, "Extract ID from EM410x tag on antenna)"},
{"410x_read", CmdEM410xRead, 1, "Extract ID from EM410x tag from GraphBuffer"},
{"410x_sim", CmdEM410xSim, 0, "simulate EM410x tag"},
{"410x_brute", CmdEM410xBrute, 0, "Reader bruteforce attack by simulating EM410x tags"},
{"410x_watch", CmdEM410xWatch, 0, "Watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
{"410x_spoof", CmdEM410xWatchnSpoof, 0, "Watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
{"410x_write", CmdEM410xWrite, 0, "Write EM410x UID to T5555(Q5) or T55x7 tag"},
{"4x05_dump", CmdEM4x05Dump, 0, "dump EM4x05/EM4x69 tag"},
{"4x05_info", CmdEM4x05Info, 0, "tag information EM4x05/EM4x69"},
{"4x05_read", CmdEM4x05Read, 0, "read word data from EM4x05/EM4x69"},
{"4x05_write", CmdEM4x05Write, 0, "write word data to EM4x05/EM4x69"},
{"4x50_read", CmdEM4x50Read, 0, "read word data from EM4x50"},
{"4x50_write", CmdEM4x50Write, 0, "write word data to EM4x50"},
{"4x50_dump", CmdEM4x50Dump, 0, "dump EM4x50 tag"},
{NULL, NULL, 0, NULL}
};

View file

@ -1,6 +1,6 @@
//-----------------------------------------------------------------------------
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
//
// 2016, 2017 marshmellow, iceman
// 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.
@ -26,22 +26,46 @@
#include "cmdlf.h"
#include "lfdemod.h"
extern int CmdLFEM4X(const char *Cmd);
extern int CmdEMdemodASK(const char *Cmd);
extern int CmdAskEM410xDemod(const char *Cmd);
extern int CmdEM410xRead(const char *Cmd);
extern int CmdEM410xSim(const char *Cmd);
extern int CmdEM410xBrute(const char *Cmd);
extern int CmdEM410xWatch(const char *Cmd);
extern int CmdEM410xWatchnSpoof(const char *Cmd);
extern int CmdEM410xWrite(const char *Cmd);
extern int CmdEM4x05Dump(const char *Cmd);
extern int CmdEM4x05Info(const char *Cmd);
extern int CmdEM4x05Read(const char *Cmd);
extern int CmdEM4x05Write(const char *Cmd);
extern int CmdEM4x50Read(const char *Cmd);
extern int CmdLFEM4X(const char *Cmd);
extern int CmdReadWord(const char *Cmd);
extern int CmdWriteWord(const char *Cmd);
extern int EM4x50Read(const char *Cmd, bool verbose);
extern int CmdEM4x50Write(const char *Cmd);
extern int CmdEM4x50Dump(const char *Cmd);
extern int EM4x50Read(const char *Cmd, bool verbose);
bool EM4x05IsBlock0(uint32_t *word);
int usage_lf_em410x_sim(void);
int usage_lf_em_read(void);
int usage_lf_em_write(void);
extern void printEM410x(uint32_t hi, uint64_t id);
extern int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo );
extern int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose);
extern int usage_lf_em410x_sim(void);
extern int usage_lf_em410x_ws(void);
extern int usage_lf_em410x_clone(void);
extern int usage_lf_em410x_sim(void);
extern int usage_lf_em410x_brute(void);
extern int usage_lf_em4x50_dump(void);
extern int usage_lf_em4x50_read(void);
extern int usage_lf_em4x50_write(void);
extern int usage_lf_em4x05_dump(void);
extern int usage_lf_em4x05_read(void);
extern int usage_lf_em4x05_write(void);
extern int usage_lf_em4x05_info(void);
#endif

View file

@ -4,7 +4,8 @@
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Low frequency Presco tag commands
// Low frequency fdx-b tag commands
// Differential Biphase, rf/32, 128 bits (known)
//-----------------------------------------------------------------------------
#include "cmdlffdx.h"
@ -32,7 +33,7 @@ static int CmdHelp(const char *Cmd);
int usage_lf_fdx_clone(void){
PrintAndLog("Clone a FDX-B animal tag to a T55x7 tag.");
PrintAndLog("Usage: lf animal clone [h] <country id> <animal id> <Q5>");
PrintAndLog("Usage: lf fdx clone [h] <country id> <animal id> <Q5>");
PrintAndLog("Options:");
PrintAndLog(" h : This help");
PrintAndLog(" <country id> : Country id");
@ -43,7 +44,7 @@ int usage_lf_fdx_clone(void){
// extended data
PrintAndLog(" <Q5> : Specify write to Q5 (t5555 instead of t55x7)");
PrintAndLog("");
PrintAndLog("Sample: lf animal clone 999 112233");
PrintAndLog("Sample: lf fdx clone 999 112233");
return 0;
}
@ -51,15 +52,31 @@ int usage_lf_fdx_sim(void) {
PrintAndLog("Enables simulation of FDX-B animal tag");
PrintAndLog("Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLog("");
PrintAndLog("Usage: lf animal sim [h] <country id> <animal id>");
PrintAndLog("Usage: lf fdx sim [h] <country id> <animal id>");
PrintAndLog("Options:");
PrintAndLog(" h : This help");
PrintAndLog(" <country id> : Country ID");
PrintAndLog(" <animal id> : Animal ID");
PrintAndLog("");
PrintAndLog("Sample: lf animal sim 999 112233");
PrintAndLog("Sample: lf fdx sim 999 112233");
return 0;
}
// Ask/Biphase Demod then try to locate an ISO 11784/85 ID
// BitStream must contain previously askrawdemod and biphasedemoded data
int detectFDXB(uint8_t *dest, size_t *size) {
//make sure buffer has enough data
if (*size < 128*2) return -1;
size_t startIdx = 0;
uint8_t preamble[] = {0,0,0,0,0,0,0,0,0,0,1};
if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx))
return -2; //preamble not found
if (*size != 128) return -3; //wrong demoded size
//return start position
return (int)startIdx;
}
// clearing the topbit needed for the preambl detection.
static void verify_values(uint32_t countryid, uint64_t animalid){
if ((animalid & 0x3FFFFFFFFF) != animalid) {
@ -122,6 +139,98 @@ int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t
return 1;
}
// FDX-B ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits)
// 8 databits + 1 parity (1)
// CIITT 16 chksum
// NATIONAL CODE, ICAR database
// COUNTRY CODE (ISO3166) or http://cms.abvma.ca/uploads/ManufacturersISOsandCountryCodes.pdf
// FLAG (animal/non-animal)
/*
38 IDbits
10 country code
1 extra app bit
14 reserved bits
1 animal bit
16 ccitt CRC chksum over 64bit ID CODE.
24 appli bits.
-- sample: 985121004515220 [ 37FF65B88EF94 ]
*/
int CmdFDXBdemodBI(const char *Cmd){
int invert = 1;
int clk = 32;
int errCnt = 0;
int offset = 0, maxErr = 0;
uint8_t BitStream[MAX_DEMOD_BUF_LEN];
size_t size = getFromGraphBuf(BitStream);
errCnt = askdemod(BitStream, &size, &clk, &invert, maxErr, 0, 0);
if ( errCnt < 0 || errCnt > maxErr ) {
if (g_debugMode) PrintAndLog("DEBUG: Error - FDXB no data or error found %d, clock: %d", errCnt, clk);
return 0;
}
errCnt = BiphaseRawDecode(BitStream, &size, &offset, 1);
if (errCnt < 0 || errCnt > maxErr ) {
if (g_debugMode) PrintAndLog("DEBUG: Error - FDXB BiphaseRawDecode: %d", errCnt);
return 0;
}
int preambleIndex = detectFDXB(BitStream, &size);
if (preambleIndex < 0){
if (g_debugMode) PrintAndLog("DEBUG: Error - FDXB preamble not found :: %d",preambleIndex);
return 0;
}
if (size != 128) {
if (g_debugMode) PrintAndLog("DEBUG: Error - FDXB incorrect data length found");
return 0;
}
setDemodBuf(BitStream, 128, preambleIndex);
// remove marker bits (1's every 9th digit after preamble) (pType = 2)
size = removeParity(BitStream, preambleIndex + 11, 9, 2, 117);
if ( size != 104 ) {
if (g_debugMode) PrintAndLog("DEBUG: Error - FDXB error removeParity:: %d", size);
return 0;
}
PrintAndLog("\nFDX-B / ISO 11784/5 Animal Tag ID Found:");
//got a good demod
uint64_t NationalCode = ((uint64_t)(bytebits_to_byteLSBF(BitStream+32,6)) << 32) | bytebits_to_byteLSBF(BitStream,32);
uint32_t countryCode = bytebits_to_byteLSBF(BitStream+38,10);
uint8_t dataBlockBit = BitStream[48];
uint32_t reservedCode = bytebits_to_byteLSBF(BitStream+49,14);
uint8_t animalBit = BitStream[63];
uint32_t crc16 = bytebits_to_byteLSBF(BitStream+64,16);
uint32_t extended = bytebits_to_byteLSBF(BitStream+80,24);
uint64_t rawid = ((uint64_t)bytebits_to_byte(BitStream,32)<<32) | bytebits_to_byte(BitStream+32,32);
uint8_t raw[8];
num_to_bytes(rawid, 8, raw);
if (g_debugMode) PrintAndLog("Raw ID Hex: %s", sprint_hex(raw,8));
uint16_t calcCrc = crc16_ccitt_kermit(raw, 8);
PrintAndLog("Animal ID: %04u-%012" PRIu64, countryCode, NationalCode);
PrintAndLog("National Code: %012" PRIu64, NationalCode);
PrintAndLog("CountryCode: %04u", countryCode);
PrintAndLog("Reserved/RFU: %u", reservedCode);
PrintAndLog("Animal Tag: %s", animalBit ? "True" : "False");
PrintAndLog("Has extended data: %s [0x%X]", dataBlockBit ? "True" : "False", extended);
PrintAndLog("CRC: 0x%04X - [%04X] - %s", crc16, calcCrc, (calcCrc == crc16) ? "Passed" : "Failed");
if (g_debugMode) {
PrintAndLog("Start marker %d; Size %d", preambleIndex, size);
char *bin = sprint_bin_break(BitStream,size,16);
PrintAndLog("DEBUG BinStream:\n%s",bin);
}
return 1;
}
//see ASKDemod for what args are accepted
//almost the same demod as cmddata.c/CmdFDXBdemodBI
int CmdFdxDemod(const char *Cmd) {
@ -133,23 +242,24 @@ int CmdFdxDemod(const char *Cmd) {
return 0;
}
size_t size = DemodBufferLen;
int ans = FDXBdemodBI(DemodBuffer, &size);
if (ans < 0){
int preambleIndex = detectFDXB(DemodBuffer, &size);
if (preambleIndex < 0){
if (g_debugMode){
if (ans == -1)
if (preambleIndex == -1)
PrintAndLog("DEBUG: Error - FDX-B too few bits found");
else if (ans == -2)
else if (preambleIndex == -2)
PrintAndLog("DEBUG: Error - FDX-B preamble not found");
else if (ans == -3)
else if (preambleIndex == -3)
PrintAndLog("DEBUG: Error - FDX-B Size not correct: %d", size);
else
PrintAndLog("DEBUG: Error - FDX-B ans: %d", ans);
PrintAndLog("DEBUG: Error - FDX-B ans: %d", preambleIndex);
}
return 0;
}
setDemodBuf(DemodBuffer, 128, ans);
setGrid_Clock(32);
// set and leave DemodBuffer intact
setDemodBuf(DemodBuffer, 128, preambleIndex);
setClockGrid(g_DemodClock, g_DemodStartIdx + (preambleIndex*g_DemodClock));
// remove marker bits (1's every 9th digit after preamble) (pType = 2)
size = removeParity(DemodBuffer, 11, 9, 2, 117);
if ( size != 104 ) {
@ -165,14 +275,11 @@ int CmdFdxDemod(const char *Cmd) {
uint8_t animalBit = DemodBuffer[63];
uint32_t crc16 = bytebits_to_byteLSBF(DemodBuffer+64,16);
uint32_t extended = bytebits_to_byteLSBF(DemodBuffer+80,24);
uint64_t rawid = ((uint64_t)
//bytebits_to_byte(DemodBuffer, 8) << 96) |
//bytebits_to_byte(DemodBuffer,32) << 64) |
bytebits_to_byte(DemodBuffer,32) << 32) |
bytebits_to_byte(DemodBuffer+32, 32);
uint64_t rawid = (uint64_t)(bytebits_to_byte(DemodBuffer,32)) << 32 | bytebits_to_byte(DemodBuffer+32, 32);
uint8_t raw[8];
num_to_bytes(rawid, 8, raw);
uint16_t calcCrc = crc16_ccitt_kermit(raw, 8);
PrintAndLog("\nFDX-B / ISO 11784/5 Animal Tag ID Found: Raw : %s", sprint_hex(raw, 8));
@ -180,22 +287,24 @@ int CmdFdxDemod(const char *Cmd) {
PrintAndLog("National Code %012" PRIu64 " (0x%" PRIx64 ")", NationalCode, NationalCode);
PrintAndLog("Country Code %04u", countryCode);
PrintAndLog("Reserved/RFU %u (0x04%X)", reservedCode, reservedCode);
PrintAndLog("");
PrintAndLog("Animal Tag %s", animalBit ? "True" : "False");
PrintAndLog("Has extended data %s [0x%X]", dataBlockBit ? "True" : "False", extended);
PrintAndLog("CRC-16 0x%04X - 0x%04X [%s]", crc16, calcCrc, (calcCrc == crc16) ? "Ok" : "Failed");
if (g_debugMode) {
PrintAndLog("Start marker %d; Size %d", ans, size);
PrintAndLog("Start marker %d; Size %d", preambleIndex, size);
char *bin = sprint_bin_break(DemodBuffer, size, 16);
PrintAndLog("DEBUG bin stream:\n%s", bin);
}
// set block 0 for later
//g_DemodConfig = T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT;
return 1;
}
int CmdFdxRead(const char *Cmd) {
CmdLFRead("s");
getSamples("12000", true);
lf_read(true, 10000);
return CmdFdxDemod(Cmd);
}
@ -290,9 +399,9 @@ int CmdFdxSim(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"demod", CmdFdxDemod,1, "Attempt to extract tag data from graphbuf"},
{"read", CmdFdxRead, 0, "Attempt to read and extract tag data"},
{"clone", CmdFdxClone,0, "Clone animal ID tag to T55x7"},
{"demod", CmdFdxDemod, 1, "Attempt to extract FDX-B ISO11784/85 data from the GraphBuffer"},
{"read", CmdFdxRead, 0, "Attempt to read and extract FDX-B ISO11784/85 data"},
{"clone", CmdFdxClone, 0, "Clone animal ID tag to T55x7 (or to q5/T5555)"},
{"sim", CmdFdxSim, 0, "Animal ID tag simulator"},
{NULL, NULL, 0, NULL}
};

View file

@ -26,9 +26,10 @@ extern int CmdFdxRead(const char *Cmd);
extern int CmdFdxDemod(const char *Cmd);
int getFDXBits(uint64_t national_id, uint16_t country, uint8_t isanimal, uint8_t isextended, uint32_t extended, uint8_t *bits);
int usage_lf_fdx_clone(void);
int usage_lf_fdx_sim(void);
int usage_lf_fdx_read(void);
int usage_lf_fdx_demod(void);
extern int usage_lf_fdx_clone(void);
extern int usage_lf_fdx_sim(void);
extern int usage_lf_fdx_read(void);
extern int usage_lf_fdx_demod(void);
#endif

View file

@ -4,10 +4,11 @@
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Low frequency Farpoint / Pyramid tag commands
// Low frequency Farpoint G Prox II / Pyramid tag commands
// Biphase, rf/ , 96 bits (unknown key calc + some bits)
//-----------------------------------------------------------------------------
#include "cmdlfguard.h"
static int CmdHelp(const char *Cmd);
int usage_lf_guard_clone(void){
@ -136,10 +137,103 @@ int GetGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) {
return 1;
}
// by marshmellow
// demod gProxIIDemod
// error returns as -x
// success returns start position in BitStream
// BitStream must contain previously askrawdemod and biphasedemoded data
int detectGProxII(uint8_t BitStream[], size_t *size) {
size_t startIdx=0;
uint8_t preamble[] = {1,1,1,1,1,0};
if (!preambleSearch(BitStream, preamble, sizeof(preamble), size, &startIdx))
return -3; //preamble not found
if (*size != 96) return -2; //should have found 96 bits
//check first 6 spacer bits to verify format
if (!BitStream[startIdx+5] && !BitStream[startIdx+10] && !BitStream[startIdx+15] && !BitStream[startIdx+20] && !BitStream[startIdx+25] && !BitStream[startIdx+30]){
//confirmed proper separator bits found
//return start position
return (int) startIdx;
}
return -5; //spacer bits not found - not a valid gproxII
}
//by marshmellow
//attempts to demodulate and identify a G_Prox_II verex/chubb card
//WARNING: if it fails during some points it will destroy the DemodBuffer data
// but will leave the GraphBuffer intact.
//if successful it will push askraw data back to demod buffer ready for emulation
int CmdGuardDemod(const char *Cmd) {
if (!ASKbiphaseDemod(Cmd, false)){
if (g_debugMode) PrintAndLog("DEBUG: Error - gProxII ASKbiphaseDemod failed 1st try");
return 0;
}
size_t size = DemodBufferLen;
//call lfdemod.c demod for gProxII
int ans = detectGProxII(DemodBuffer, &size);
if (ans < 0){
if (g_debugMode) PrintAndLog("DEBUG: Error - gProxII demod");
return 0;
}
//got a good demod of 96 bits
uint8_t ByteStream[8] = {0x00};
uint8_t xorKey = 0;
size_t startIdx = ans + 6; //start after 6 bit preamble
uint8_t bits_no_spacer[90];
//so as to not mess with raw DemodBuffer copy to a new sample array
memcpy(bits_no_spacer, DemodBuffer + startIdx, 90);
// remove the 18 (90/5=18) parity bits (down to 72 bits (96-6-18=72))
size_t bitLen = removeParity(bits_no_spacer, 0, 5, 3, 90); //source, startloc, paritylen, ptype, length_to_run
if (bitLen != 72) {
if (g_debugMode)
PrintAndLog("DEBUG: Error - gProxII spacer removal did not produce 72 bits: %u, start: %u", bitLen, startIdx);
return 0;
}
// get key and then get all 8 bytes of payload decoded
xorKey = (uint8_t)bytebits_to_byteLSBF(bits_no_spacer, 8);
for (size_t idx = 0; idx < 8; idx++) {
ByteStream[idx] = ((uint8_t)bytebits_to_byteLSBF(bits_no_spacer+8 + (idx*8),8)) ^ xorKey;
if (g_debugMode) PrintAndLog("DEBUG: gProxII byte %u after xor: %02x", (unsigned int)idx, ByteStream[idx]);
}
//ByteStream contains 8 Bytes (64 bits) of decrypted raw tag data
uint8_t fmtLen = ByteStream[0]>>2;
uint32_t FC = 0;
uint32_t Card = 0;
//get raw 96 bits to print
uint32_t raw1 = bytebits_to_byte(DemodBuffer+ans,32);
uint32_t raw2 = bytebits_to_byte(DemodBuffer+ans+32, 32);
uint32_t raw3 = bytebits_to_byte(DemodBuffer+ans+64, 32);
bool unknown = false;
switch(fmtLen) {
case 36:
FC = ((ByteStream[3] & 0x7F)<<7) | (ByteStream[4]>>1);
Card = ((ByteStream[4]&1)<<19) | (ByteStream[5]<<11) | (ByteStream[6]<<3) | (ByteStream[7]>>5);
break;
case 26:
FC = ((ByteStream[3] & 0x7F)<<1) | (ByteStream[4]>>7);
Card = ((ByteStream[4]&0x7F)<<9) | (ByteStream[5]<<1) | (ByteStream[6]>>7);
break;
default :
unknown = true;
break;
}
if ( !unknown)
PrintAndLog("G-Prox-II Found: Format Len: %ubit - FC: %u - Card: %u, Raw: %08x%08x%08x", fmtLen, FC, Card, raw1, raw2, raw3);
else
PrintAndLog("Unknown G-Prox-II Fmt Found: Format Len: %u, Raw: %08x%08x%08x", fmtLen, raw1, raw2, raw3);
setDemodBuf(DemodBuffer, 96, ans);
setClockGrid(g_DemodClock, g_DemodStartIdx + (ans*g_DemodClock));
return 1;
}
int CmdGuardRead(const char *Cmd) {
CmdLFRead("s");
getSamples("12000", true);
return CmdG_Prox_II_Demod("");
lf_read(true, 10000);
return CmdGuardDemod(Cmd);
}
int CmdGuardClone(const char *Cmd) {
@ -240,9 +334,10 @@ int CmdGuardSim(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"read", CmdGuardRead, 0, "Attempt to read and extract tag data"},
{"clone", CmdGuardClone, 0, "<Facility-Code> <Card Number> clone Guardall tag"},
{"sim", CmdGuardSim, 0, "<Facility-Code> <Card Number> simulate Guardall tag"},
{"demod", CmdGuardDemod, 1, "Demodulate a G Prox II tag from the GraphBuffer"},
{"read", CmdGuardRead, 0, "Attempt to read and extract tag data from the antenna"},
{"clone", CmdGuardClone, 0, "<Facility-Code> <Card Number> clone Guardall tag"},
{"sim", CmdGuardSim, 0, "<Facility-Code> <Card Number> simulate Guardall tag"},
{NULL, NULL, 0, NULL}
};

View file

@ -4,7 +4,7 @@
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Low frequency T55xx commands
// Low frequency G Prox II tag commands
//-----------------------------------------------------------------------------
#ifndef CMDLFGUARD_H__
#define CMDLFGUARD_H__
@ -22,11 +22,12 @@
#include "lfdemod.h" // parityTest
#include "crc.h"
int CmdLFGuard(const char *Cmd);
int CmdGuardClone(const char *Cmd);
int CmdGuardSim(const char *Cmd);
extern int CmdLFGuard(const char *Cmd);
extern int CmdGuardDemod(const char *Cmd);
extern int CmdGuardRead(const char *Cmd);
extern int CmdGuardClone(const char *Cmd);
extern int CmdGuardSim(const char *Cmd);
int usage_lf_guard_clone(void);
int usage_lf_quard_sim(void);
extern int usage_lf_guard_clone(void);
extern int usage_lf_quard_sim(void);
#endif

View file

@ -1,6 +1,6 @@
//-----------------------------------------------------------------------------
// Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
//
// 2016,2017, marshmellow, iceman
// 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.
@ -16,27 +16,43 @@
static int CmdHelp(const char *Cmd);
int usage_lf_hid_read(void){
PrintAndLog("Enables HID compatible reader mode printing details.");
PrintAndLog("By default, values are printed and logged until the button is pressed or another USB command is issued.");
PrintAndLog("If the [1] option is provided, reader mode is exited after reading a single HID card.");
PrintAndLog("");
PrintAndLog("Usage: lf hid read [h] [1]");
PrintAndLog("Options:");
PrintAndLog(" h : This help");
PrintAndLog(" 1 : (optional) stop after reading a single card");
PrintAndLog("");
PrintAndLog("Samples:");
PrintAndLog(" lf hid read");
PrintAndLog(" lf hid read 1");
return 0;
}
int usage_lf_hid_wiegand(void){
PrintAndLog("This command converts facility code/card number to Wiegand code");
PrintAndLog("");
PrintAndLog("Usage: lf hid wiegand [h] [OEM] [FC] [CN]");
PrintAndLog("Options:");
PrintAndLog(" h - This help");
PrintAndLog(" OEM - OEM number / site code");
PrintAndLog(" FC - facility code");
PrintAndLog(" CN - card number");
PrintAndLog("Examples:");
PrintAndLog("Samples:");
PrintAndLog(" lf hid wiegand 0 101 2001");
return 0;
}
int usage_lf_hid_sim(void){
PrintAndLog("HID Tag simulator");
PrintAndLog("Enables simulation of HID card with card number.");
PrintAndLog("Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLog("");
PrintAndLog("Usage: lf hid sim [h] [ID]");
PrintAndLog("Options:");
PrintAndLog(" h - This help");
PrintAndLog(" ID - HID id");
PrintAndLog("Examples:");
PrintAndLog("Samples:");
PrintAndLog(" lf hid sim 224");
return 0;
}
@ -48,7 +64,7 @@ int usage_lf_hid_clone(void){
PrintAndLog(" h - This help");
PrintAndLog(" ID - HID id");
PrintAndLog(" L - 84bit ID");
PrintAndLog("Examples:");
PrintAndLog("Samples:");
PrintAndLog(" lf hid clone 224");
PrintAndLog(" lf hid clone 224 L");
return 0;
@ -100,7 +116,105 @@ static bool sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, ui
return true;
}
int CmdHIDDemodFSK(const char *Cmd) {
//by marshmellow (based on existing demod + holiman's refactor)
//HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded)
//print full HID Prox ID and some bit format details if found
int CmdHIDDemod(const char *Cmd) {
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
uint32_t hi2=0, hi=0, lo=0;
uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0};
size_t BitLen = getFromGraphBuf(BitStream);
if (BitLen==0) return 0;
//get binary from fsk wave
int waveIdx = 0;
int idx = HIDdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo, &waveIdx);
if (idx < 0) {
if (g_debugMode){
if (idx==-1){
PrintAndLog("DEBUG: Error - HID just noise detected");
} else if (idx == -2) {
PrintAndLog("DEBUG: Error - HID problem during FSK demod");
} else if (idx == -3) {
PrintAndLog("DEBUG: Error - HID preamble not found");
} else if (idx == -4) {
PrintAndLog("DEBUG: Error - HID error in Manchester data, SIZE: %d", BitLen);
} else {
PrintAndLog("DEBUG: Error - HID error demoding fsk %d", idx);
}
}
return 0;
}
if (hi2==0 && hi==0 && lo==0) {
if (g_debugMode) PrintAndLog("DEBUG: Error - HID no values found");
return 0;
}
if (hi2 != 0){ //extra large HID tags
PrintAndLog("HID Prox TAG ID: %x%08x%08x (%u)", hi2, hi, lo, (lo>>1) & 0xFFFF);
}
else { //standard HID tags <38 bits
uint8_t fmtLen = 0;
uint32_t fc = 0;
uint32_t cardnum = 0;
if ((( hi >> 5) & 1) == 1){//if bit 38 is set then < 37 bit format is used
uint32_t lo2=0;
lo2=(((hi & 31) << 12) | (lo >> 20)); //get bits 21-37 to check for format len bit
uint8_t idx3 = 1;
while ( lo2 > 1){ //find last bit set to 1 (format len bit)
lo2 >>= 1;
idx3++;
}
fmtLen = idx3 + 19;
fc = 0;
cardnum = 0;
if(fmtLen==26){
cardnum = (lo >> 1) & 0xFFFF;
fc = ( lo >> 17) & 0xFF;
}
if(fmtLen==34){
cardnum = (lo >> 1) & 0xFFFF;
fc= ((hi & 1)<< 15) | (lo >> 17);
}
if(fmtLen==35){
cardnum = (lo >> 1) & 0xFFFFF;
fc = ((hi & 1) << 11 ) | (lo >> 21);
}
}
else { //if bit 38 is not set then 37 bit format is used
fmtLen = 37;
fc = 0;
cardnum = 0;
if(fmtLen == 37){
cardnum = (lo >> 1 ) & 0x7FFFF;
fc = ((hi & 0xF) << 12) | (lo >> 20);
}
}
PrintAndLog("HID Prox TAG ID: %x%08x (%u) - Format Len: %ubit - FC: %u - Card: %u", hi, lo, (lo>>1) & 0xFFFF, fmtLen, fc, cardnum);
}
setDemodBuf(BitStream,BitLen,idx);
setClockGrid(50, waveIdx + (idx*50));
if (g_debugMode){
PrintAndLog("DEBUG: HID idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen);
printDemodBuff();
}
return 1;
}
// this read is the "normal" read, which download lf signal and tries to demod here.
int CmdHIDRead(const char *Cmd) {
lf_read(true, 12000);
return CmdHIDDemod(Cmd);
}
// this read loops on device side.
// uses the demod in lfops.c
int CmdHIDRead_device(const char *Cmd) {
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_hid_read();
uint8_t findone = ( Cmd[0] == '1' ) ? 1 : 0;
UsbCommand c = {CMD_HID_DEMOD_FSK, {findone, 0 , 0}};
clearCommandBuffer();
@ -426,6 +540,7 @@ int CmdHIDBrute(const char *Cmd){
}
if (ukbhit()) {
int gc = getchar(); (void)gc;
PrintAndLog("aborted via keyboard!");
return sendPing();
}
@ -443,12 +558,13 @@ int CmdHIDBrute(const char *Cmd){
}
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"fskdemod",CmdHIDDemodFSK, 0, "Realtime HID FSK demodulator"},
{"sim", CmdHIDSim, 0, "HID tag simulator"},
{"clone", CmdHIDClone, 0, "Clone HID to T55x7"},
{"wiegand", CmdHIDWiegand, 1, "Convert facility code/card number to Wiegand code"},
{"brute", CmdHIDBrute, 0, "Bruteforce card number against reader"},
{"help", CmdHelp, 1, "This help"},
{"demod", CmdHIDDemod, 0, "Demodulate HID Prox tag from the GraphBuffer"},
{"read", CmdHIDRead, 0, "Attempt to read and extract tag data"},
{"sim", CmdHIDSim, 0, "HID tag simulator"},
{"clone", CmdHIDClone, 0, "Clone HID to T55x7"},
{"wiegand", CmdHIDWiegand, 1, "Convert facility code/card number to Wiegand code"},
{"brute", CmdHIDBrute, 0, "Bruteforce card number against reader"},
{NULL, NULL, 0, NULL}
};

View file

@ -18,23 +18,26 @@
#include "graph.h"
#include "cmdparser.h"
#include "util.h" // wiegand_add_parity etc
#include "cmdmain.h"
#include "sleep.h"
#include "cmddata.h" //for g_debugMode, demodbuff cmds
#include "cmdlf.h" // lf_read
#include "cmdmain.h"
#include "util_posix.h"
#include "lfdemod.h"
int CmdLFHID(const char *Cmd);
//int CmdHIDDemod(const char *Cmd);
int CmdHIDDemodFSK(const char *Cmd);
int CmdHIDSim(const char *Cmd);
int CmdHIDClone(const char *Cmd);
int CmdHIDWiegand(const char *Cmd);
int CmdHIDBrute(const char *Cmd);
extern int CmdLFHID(const char *Cmd);
extern int CmdHIDDemod(const char *Cmd);
extern int CmdHIDRead(const char *Cmd);
extern int CmdHIDSim(const char *Cmd);
extern int CmdHIDClone(const char *Cmd);
extern int CmdHIDWiegand(const char *Cmd);
extern int CmdHIDBrute(const char *Cmd);
int usage_lf_hid_wiegand(void);
int usage_lf_hid_sim(void);
int usage_lf_hid_clone(void);
int usage_lf_hid_brute(void);
extern int usage_lf_hid_read(void);
extern int usage_lf_hid_wiegand(void);
extern int usage_lf_hid_sim(void);
extern int usage_lf_hid_clone(void);
extern int usage_lf_hid_brute(void);
//void calc26(uint16_t fc, uint32_t cardno, uint8_t *out);
void calcWiegand(uint8_t fmtlen, uint16_t fc, uint64_t cardno, uint8_t *bits);
extern void calcWiegand(uint8_t fmtlen, uint16_t fc, uint64_t cardno, uint8_t *bits);
#endif

View file

@ -17,9 +17,10 @@
#include "cmdparser.h"
#include "common.h"
#include "util.h"
#include "parity.h"
#include "hitag2.h"
#include "hitagS.h"
#include "sleep.h"
#include "util_posix.h"
#include "cmdmain.h"
static int CmdHelp(const char *Cmd);
@ -107,15 +108,9 @@ int CmdLFHitagList(const char *Cmd) {
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))) {
if (isResponse && (oddparity8(frame[j]) != ((parityBits >> (len - j - 1)) & 0x01))) {
sprintf(line+(j*4), "%02x! ", frame[j]);
}
else {
@ -355,7 +350,9 @@ int CmdLFHitagWP(const char *Cmd) {
c.arg[2]= param_get32ex(Cmd, 2, 0, 10);
num_to_bytes(param_get32ex(Cmd,3,0,16),4,htd->auth.data);
} break;
case 04: { //WHTSF_KEY
case 04:
case 24:
{ //WHTSF_KEY
num_to_bytes(param_get64ex(Cmd,1,0,16),6,htd->crypto.key);
c.arg[2]= param_get32ex(Cmd, 2, 0, 10);
num_to_bytes(param_get32ex(Cmd,3,0,16),4,htd->crypto.data);
@ -387,15 +384,15 @@ int CmdLFHitagWP(const char *Cmd) {
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"list", CmdLFHitagList, 1, "<outfile> List Hitag trace history"},
{"reader", CmdLFHitagReader, 1, "Act like a Hitag Reader"},
{"sim", CmdLFHitagSim, 1, "<infile> Simulate Hitag transponder"},
{"snoop", CmdLFHitagSnoop, 1, "Eavesdrop Hitag communication"},
{"writer", CmdLFHitagWP, 1, "Act like a Hitag Writer" },
{"simS", CmdLFHitagSimS, 1, "<hitagS.hts> Simulate HitagS transponder" },
{"checkChallenges", CmdLFHitagCheckChallenges, 1, "<challenges.cc> test all challenges" }, {
NULL,NULL, 0, NULL }
{"help", CmdHelp, 1, "This help"},
{"list", CmdLFHitagList, 1, "<outfile> List Hitag trace history"},
{"reader", CmdLFHitagReader, 1, "Act like a Hitag Reader"},
{"sim", CmdLFHitagSim, 1, "<infile> Simulate Hitag transponder"},
{"simS", CmdLFHitagSimS, 1, "<hitagS.hts> Simulate HitagS transponder" },
{"snoop", CmdLFHitagSnoop, 1, "Eavesdrop Hitag communication"},
{"writer", CmdLFHitagWP, 1, "Act like a Hitag Writer" },
{"check_challenges", CmdLFHitagCheckChallenges, 1, "<challenges.cc> test all challenges" },
{ NULL,NULL, 0, NULL }
};
int CmdLFHitag(const char *Cmd) {

View file

@ -1,6 +1,6 @@
//-----------------------------------------------------------------------------
// Copyright (C) 2012 Roel Verdult
//
// 2017 iceman
// 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.
@ -11,11 +11,14 @@
#ifndef CMDLFHITAG_H__
#define CMDLFHITAG_H__
int CmdLFHitag(const char *Cmd);
extern int CmdLFHitag(const char *Cmd);
int CmdLFHitagList(const char *Cmd);
int CmdLFHitagSnoop(const char *Cmd);
int CmdLFHitagSim(const char *Cmd);
int CmdLFHitagReader(const char *Cmd);
extern int CmdLFHitagList(const char *Cmd);
extern int CmdLFHitagReader(const char *Cmd);
extern int CmdLFHitagSim(const char *Cmd);
extern int CmdLFHitagSimS(const char *Cmd);
extern int CmdLFHitagSnoop(const char *Cmd);
extern int CmdLFHitagWP(const char *Cmd);
extern int CmdLFHitagCheckChallenges(const char *Cmd);
#endif

408
client/cmdlfindala.c Normal file
View file

@ -0,0 +1,408 @@
//-----------------------------------------------------------------------------
//
// 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.
//-----------------------------------------------------------------------------
// Low frequency Indala commands
// PSK1, rf/32, 64 or 224 bits (known)
//-----------------------------------------------------------------------------
#include "cmdlfindala.h"
static int CmdHelp(const char *Cmd);
int usage_lf_indala_demod(void) {
PrintAndLog("Enables Indala compatible reader mode printing details of scanned tags.");
PrintAndLog("By default, values are printed and logged until the button is pressed or another USB command is issued.");
PrintAndLog("");
PrintAndLog("Usage: lf indala demod [h]");
PrintAndLog("Options :");
PrintAndLog(" h : This help");
PrintAndLog("");
PrintAndLog("Samples");
PrintAndLog(" lf indala demod");
return 0;
}
int usage_lf_indala_sim(void) {
PrintAndLog("Enables simulation of Indala card with specified facility-code and card number.");
PrintAndLog("Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLog("");
PrintAndLog("Usage: lf indala sim [h] <version> <facility-code> <card-number>");
PrintAndLog("Options :");
PrintAndLog(" h : This help");
PrintAndLog(" <version> : 8bit version");
PrintAndLog(" <facility-code> : 8bit value facility code");
PrintAndLog(" <card number> : 16bit value card number");
PrintAndLog("");
PrintAndLog("Samples");
PrintAndLog(" lf indala sim 26 101 1337");
return 0;
}
int usage_lf_indala_clone(void) {
PrintAndLog("Enables cloning of Indala card with specified facility-code and card number onto T55x7.");
PrintAndLog("The T55x7 must be on the antenna when issuing this command. T55x7 blocks are calculated and printed in the process.");
PrintAndLog("");
PrintAndLog("Usage: lf indala clone [h] <uid> [Q5]");
PrintAndLog("Options :");
PrintAndLog(" h : This help");
PrintAndLog(" <uid> : 64/221 UID");
PrintAndLog(" Q5 : optional - clone to Q5 (T5555) instead of T55x7 chip");
PrintAndLog("");
PrintAndLog("Samples");
PrintAndLog(" lf indala clone 112233");
return 0;
}
// this read is the "normal" read, which download lf signal and tries to demod here.
int CmdIndalaRead(const char *Cmd) {
lf_read(true, 30000);
return CmdIndalaDemod(Cmd);
}
// Indala 26 bit decode
// by marshmellow
// optional arguments - same as PSKDemod (clock & invert & maxerr)
int CmdIndalaDemod(const char *Cmd) {
int ans;
if (strlen(Cmd) > 0)
ans = PSKDemod(Cmd, 0);
else //default to RF/32
ans = PSKDemod("32", 0);
if (!ans){
if (g_debugMode) PrintAndLog("DEBUG: Error - Indala can't demod signal: %d",ans);
return 0;
}
uint8_t invert = 0;
size_t size = DemodBufferLen;
int idx = detectIndala26(DemodBuffer, &size, &invert);
if (idx < 0 || size > 224) {
if (g_debugMode) PrintAndLog("DEBUG: Error - Indala wrong size, expected [64|224] got: %d", size);
return -1;
}
setDemodBuf(DemodBuffer, size, (size_t)idx);
setClockGrid(g_DemodClock, g_DemodStartIdx + (idx * g_DemodClock));
if (invert) {
if (g_debugMode) PrintAndLog("DEBUG: Error - Indala had to invert bits");
for (size_t i = 0; i < size; i++)
DemodBuffer[i] ^= 1;
}
//convert UID to HEX
uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
uid1 = bytebits_to_byte(DemodBuffer,32);
uid2 = bytebits_to_byte(DemodBuffer+32,32);
if (DemodBufferLen==64){
PrintAndLog("Indala Found - Bitlength %d, UID = (%x%08x)\n%s",
DemodBufferLen, uid1, uid2, sprint_bin_break(DemodBuffer,DemodBufferLen,32)
);
} else {
uid3 = bytebits_to_byte(DemodBuffer+64,32);
uid4 = bytebits_to_byte(DemodBuffer+96,32);
uid5 = bytebits_to_byte(DemodBuffer+128,32);
uid6 = bytebits_to_byte(DemodBuffer+160,32);
uid7 = bytebits_to_byte(DemodBuffer+192,32);
PrintAndLog("Indala Found - Bitlength %d, UID = (%x%08x%08x%08x%08x%08x%08x)\n%s",
DemodBufferLen,
uid1, uid2, uid3, uid4, uid5, uid6, uid7, sprint_bin_break(DemodBuffer,DemodBufferLen,32)
);
}
if (g_debugMode){
PrintAndLog("DEBUG: Indala - printing demodbuffer:");
printDemodBuff();
}
return 1;
}
// older alternative indala demodulate (has some positives and negatives)
// returns false positives more often - but runs against more sets of samples
// poor psk signal can be difficult to demod this approach might succeed when the other fails
// but the other appears to currently be more accurate than this approach most of the time.
int CmdIndalaDemodAlt(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;
//clear clock grid and demod plot
setClockGrid(0, 0);
DemodBufferLen = 0;
// PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32);
// loop through raw signal - since we know it is psk1 rf/32 fc/2 skip every other value (+=2)
for (i = 0; i < GraphTraceLen-1; i += 2) {
count += 1;
if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) {
// appears redundant - marshmellow
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)) {
//appears redundant
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;
}
}
if (rawbit>0){
PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32);
PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos);
} else {
return 0;
}
// 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] = {0x00};
char showbits[225] = {0x00};
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;
}
//convert UID to HEX
uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
int idx;
uid1 = uid2 = 0;
if (uidlen==64){
for( idx=0; idx<64; idx++) {
if (showbits[idx] == '0') {
uid1=(uid1<<1)|(uid2>>31);
uid2=(uid2<<1)|0;
} else {
uid1=(uid1<<1)|(uid2>>31);
uid2=(uid2<<1)|1;
}
}
PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2);
}
else {
uid3 = uid4 = uid5 = uid6 = uid7 = 0;
for( idx=0; idx<224; idx++) {
uid1=(uid1<<1)|(uid2>>31);
uid2=(uid2<<1)|(uid3>>31);
uid3=(uid3<<1)|(uid4>>31);
uid4=(uid4<<1)|(uid5>>31);
uid5=(uid5<<1)|(uid6>>31);
uid6=(uid6<<1)|(uid7>>31);
if (showbits[idx] == '0')
uid7 = (uid7<<1) | 0;
else
uid7 = (uid7<<1) | 1;
}
PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7);
}
// Checking UID against next occurrences
int failed = 0;
for (; i + uidlen <= rawbit;) {
failed = 0;
for (bit = 0; bit < uidlen; bit++) {
if (bits[bit] != rawbits[i++]) {
failed = 1;
break;
}
}
if (failed == 1) {
break;
}
times += 1;
}
PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen);
// Remodulating for tag cloning
// HACK: 2015-01-04 this will have an impact on our new way of seening lf commands (demod)
// since this changes graphbuffer data.
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 1;
}
int CmdIndalaSim(const char *Cmd) {
uint16_t cn = 0;
uint8_t bits[64];
uint8_t *bs = bits;
size_t size = sizeof(bits);
memset(bs, 0x00, size);
uint64_t arg1 = ( 10 << 8 ) + 8; // fcHigh = 10, fcLow = 8
uint64_t arg2 = (64 << 8)| + 1; // clk RF/64 invert=1
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_indala_sim();
PrintAndLog("Emulating Indala UID: %u \n", cn);
PrintAndLog("Press pm3-button to abort simulation or run another command");
UsbCommand c = {CMD_PSK_SIM_TAG, {arg1, arg2, size}};
memcpy(c.d.asBytes, bs, size);
clearCommandBuffer();
SendCommand(&c);
return 0;
}
// iceman - needs refactoring
int CmdIndalaClone(const char *Cmd) {
UsbCommand c;
uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
uid1 = uid2 = uid3 = uid4 = uid5 = uid6 = uid7 = 0;
int n = 0, i = 0;
if (strchr(Cmd,'l') != 0) {
while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
uid1 = (uid1 << 4) | (uid2 >> 28);
uid2 = (uid2 << 4) | (uid3 >> 28);
uid3 = (uid3 << 4) | (uid4 >> 28);
uid4 = (uid4 << 4) | (uid5 >> 28);
uid5 = (uid5 << 4) | (uid6 >> 28);
uid6 = (uid6 << 4) | (uid7 >> 28);
uid7 = (uid7 << 4) | (n & 0xf);
}
PrintAndLog("Cloning 224bit tag with UID %x%08x%08x%08x%08x%08x%08x", uid1, uid2, uid3, uid4, uid5, uid6, uid7);
c.cmd = CMD_INDALA_CLONE_TAG_L;
c.d.asDwords[0] = uid1;
c.d.asDwords[1] = uid2;
c.d.asDwords[2] = uid3;
c.d.asDwords[3] = uid4;
c.d.asDwords[4] = uid5;
c.d.asDwords[5] = uid6;
c.d.asDwords[6] = uid7;
} else {
while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
uid1 = (uid1 << 4) | (uid2 >> 28);
uid2 = (uid2 << 4) | (n & 0xf);
}
PrintAndLog("Cloning 64bit tag with UID %x%08x", uid1, uid2);
c.cmd = CMD_INDALA_CLONE_TAG;
c.arg[0] = uid1;
c.arg[1] = uid2;
}
clearCommandBuffer();
SendCommand(&c);
return 0;
}
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"demod", CmdIndalaDemod, 1, "Demodulate an indala tag (PSK1) from GraphBuffer"},
{"altdemod", CmdIndalaDemodAlt, 1, "Alternative method to Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
{"read", CmdIndalaRead, 0, "Read an Indala Prox tag from the antenna"},
{"sim", CmdIndalaSim, 0, "Indala tag simulator"},
{"clone", CmdIndalaClone, 0, "Clone Indala to T55x7"},
{NULL, NULL, 0, NULL}
};
int CmdLFINDALA(const char *Cmd){
clearCommandBuffer();
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
CmdsHelp(CommandTable);
return 0;
}

39
client/cmdlfindala.h Normal file
View file

@ -0,0 +1,39 @@
//-----------------------------------------------------------------------------
//
// 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.
//-----------------------------------------------------------------------------
// Low frequency Indala commands
//-----------------------------------------------------------------------------
#ifndef CMDLFINDALA_H__
#define CMDLFINDALA_H__
#include <stdio.h> // sscanf
#include <stdlib.h>
#include <string.h>
#include "proxmark3.h" // Definitions, USB controls, etc
#include "ui.h" // PrintAndLog
#include "cmdparser.h" // CmdsParse, CmdsHelp
#include "lfdemod.h" // parityTest
#include "util.h" // weigandparity
#include "protocols.h" // for T55xx config register definitions
#include "data.h"
#include "cmdmain.h"
#include "cmddata.h"
#include "cmdlf.h" // lf_read
#include "lfdemod.h" // bitbytes_to_byte
extern int CmdLFINDALA(const char *Cmd);
extern int CmdIndalaDemod(const char *Cmd);
extern int CmdIndalaDemodAlt(const char *Cmd);
extern int CmdIndalaRead(const char *Cmd);
extern int CmdIndalaClone(const char *Cmd);
extern int CmdIndalaSim(const char *Cmd);
extern int usage_lf_indala_demod(void);
extern int usage_lf_indala_clone(void);
extern int usage_lf_indala_sim(void);
#endif

View file

@ -1,20 +1,30 @@
//-----------------------------------------------------------------------------
//
// 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.
//-----------------------------------------------------------------------------
// Low frequency ioProx commands
// FSK2a, rf/64, 64 bits (complete)
//-----------------------------------------------------------------------------
#include "cmdlfio.h"
static int CmdHelp(const char *Cmd);
int usage_lf_io_fskdemod(void) {
int usage_lf_io_read(void) {
PrintAndLog("Enables IOProx compatible reader mode printing details of scanned tags.");
PrintAndLog("By default, values are printed and logged until the button is pressed or another USB command is issued.");
PrintAndLog("If the [1] option is provided, reader mode is exited after reading a single card.");
PrintAndLog("");
PrintAndLog("Usage: lf io fskdemod [h] [1]");
PrintAndLog("Usage: lf io read [h] [1]");
PrintAndLog("Options :");
PrintAndLog(" h : This help");
PrintAndLog(" 1 : (optional) stop after reading a single card");
PrintAndLog("");
PrintAndLog("Samples");
PrintAndLog(" lf io fskdemod");
PrintAndLog(" lf io fskdemod 1");
PrintAndLog(" lf io read");
PrintAndLog(" lf io read 1");
return 0;
}
@ -51,29 +61,124 @@ int usage_lf_io_clone(void) {
return 0;
}
int CmdIODemodFSK(const char *Cmd) {
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_io_fskdemod();
// this read is the "normal" read, which download lf signal and tries to demod here.
int CmdIOProxRead(const char *Cmd) {
lf_read(true, 12000);
return CmdIOProxDemod(Cmd);
}
// this read loops on device side.
// uses the demod in lfops.c
int CmdIOProxRead_device(const char *Cmd) {
if (Cmd[0] == 'h' || Cmd[0] == 'H') return usage_lf_io_read();
int findone = (Cmd[0]=='1') ? 1 : 0;
UsbCommand c = {CMD_IO_DEMOD_FSK};
c.arg[0] = findone;
UsbCommand c = {CMD_IO_DEMOD_FSK, {findone, 0, 0}};
clearCommandBuffer();
SendCommand(&c);
return 0;
}
/*
int CmdIOProxDemod(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) {
GraphBuffer[i] = (GraphBuffer[i] < 0) ? 0 : 1;
}
RepaintGraphWindow();
return 0;
}
*/
//by marshmellow
//IO-Prox demod - FSK RF/64 with preamble of 000000001
//print ioprox ID and some format details
int CmdIOProxDemod(const char *Cmd) {
int retval = 0;
int idx = 0;
char crcStr[20];
memset(crcStr, 0x00, sizeof(crcStr) );
//something in graphbuffer?
if (GraphTraceLen < 65) {
if (g_debugMode)PrintAndLog("DEBUG: Error - IO prox not enough samples in GraphBuffer");
return retval;
}
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
size_t bitlen = getFromGraphBuf(BitStream);
if (bitlen == 0) return retval;
int waveIdx = 0;
//get binary from fsk wave
idx = detectIOProx(BitStream, &bitlen, &waveIdx);
if (idx<0){
if (g_debugMode){
if (idx==-1){
PrintAndLog("DEBUG: Error - IO prox just noise detected");
} else if (idx == -2) {
PrintAndLog("DEBUG: Error - IO prox not enough samples");
} else if (idx == -3) {
PrintAndLog("DEBUG: Error - IO prox error during fskdemod");
} else if (idx == -4) {
PrintAndLog("DEBUG: Error - IO prox preamble not found");
} else if (idx == -5) {
PrintAndLog("DEBUG: Error - IO prox separator bits not found");
} else {
PrintAndLog("DEBUG: Error - IO prox error demoding fsk %d", idx);
}
}
return retval;
}
if (idx==0){
if (g_debugMode){
PrintAndLog("DEBUG: Error - IO prox data not found - FSK Bits: %d", bitlen);
if (bitlen > 92) PrintAndLog("%s", sprint_bin_break(BitStream,92,16));
}
return retval;
}
//Index map
//0 10 20 30 40 50 60
//| | | | | | |
//01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
//-----------------------------------------------------------------------------
//00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
//
//XSF(version)facility:codeone+codetwo (raw)
//Handle the data
if (idx + 64 > bitlen) {
if (g_debugMode) PrintAndLog("DEBUG: Error - IO prox not enough bits found - bitlen: %d", bitlen);
return retval;
}
if (g_debugMode) {
PrintAndLog("%d%d%d%d%d%d%d%d %d", BitStream[idx], BitStream[idx+1], BitStream[idx+2], BitStream[idx+3], BitStream[idx+4], BitStream[idx+5], BitStream[idx+6], BitStream[idx+7], BitStream[idx+8]);
PrintAndLog("%d%d%d%d%d%d%d%d %d", BitStream[idx+9], BitStream[idx+10], BitStream[idx+11],BitStream[idx+12],BitStream[idx+13],BitStream[idx+14],BitStream[idx+15],BitStream[idx+16],BitStream[idx+17]);
PrintAndLog("%d%d%d%d%d%d%d%d %d facility", BitStream[idx+18], BitStream[idx+19], BitStream[idx+20],BitStream[idx+21],BitStream[idx+22],BitStream[idx+23],BitStream[idx+24],BitStream[idx+25],BitStream[idx+26]);
PrintAndLog("%d%d%d%d%d%d%d%d %d version", BitStream[idx+27], BitStream[idx+28], BitStream[idx+29],BitStream[idx+30],BitStream[idx+31],BitStream[idx+32],BitStream[idx+33],BitStream[idx+34],BitStream[idx+35]);
PrintAndLog("%d%d%d%d%d%d%d%d %d code1", BitStream[idx+36], BitStream[idx+37], BitStream[idx+38],BitStream[idx+39],BitStream[idx+40],BitStream[idx+41],BitStream[idx+42],BitStream[idx+43],BitStream[idx+44]);
PrintAndLog("%d%d%d%d%d%d%d%d %d code2", BitStream[idx+45], BitStream[idx+46], BitStream[idx+47],BitStream[idx+48],BitStream[idx+49],BitStream[idx+50],BitStream[idx+51],BitStream[idx+52],BitStream[idx+53]);
PrintAndLog("%d%d%d%d%d%d%d%d %d%d checksum", BitStream[idx+54],BitStream[idx+55],BitStream[idx+56],BitStream[idx+57],BitStream[idx+58],BitStream[idx+59],BitStream[idx+60],BitStream[idx+61],BitStream[idx+62],BitStream[idx+63]);
}
uint32_t code = bytebits_to_byte(BitStream+idx,32);
uint32_t code2 = bytebits_to_byte(BitStream+idx+32,32);
uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4
uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ;
uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9
uint8_t crc = bytebits_to_byte(BitStream+idx+54,8);
uint16_t calccrc = 0;
for (uint8_t i = 1; i < 6; ++i){
calccrc += bytebits_to_byte(BitStream + idx + 9 * i ,8);
}
calccrc &= 0xff;
calccrc = 0xff - calccrc;
if (crc == calccrc) {
snprintf(crcStr, 3, "ok");
retval = 1;
} else {
if (g_debugMode) PrintAndLog("DEBUG: Error - IO prox crc failed");
snprintf(crcStr, 20, "failed 0x%02X != 0x%02X", crc, calccrc);
retval = 0;
}
PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x) [crc %s]",version,facilitycode,number,code,code2, crcStr);
setDemodBuf(BitStream,64,idx);
if (g_debugMode){
PrintAndLog("DEBUG: IO prox idx: %d, Len: %d, Printing demod buffer:", idx, 64);
printDemodBuff();
}
return retval;
}
//Index map
//0 10 20 30 40 50 60
@ -140,7 +245,7 @@ int getIOProxBits(uint8_t version, uint8_t fc, uint16_t cn, uint8_t *bits) {
return 1;
}
int CmdIOSim(const char *Cmd) {
int CmdIOProxSim(const char *Cmd) {
uint16_t cn = 0;
uint8_t version = 0, fc = 0;
uint8_t bits[64];
@ -183,7 +288,7 @@ int CmdIOSim(const char *Cmd) {
return 0;
}
int CmdIOClone(const char *Cmd) {
int CmdIOProxClone(const char *Cmd) {
uint32_t blocks[3] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0};
uint16_t cn = 0;
@ -233,10 +338,10 @@ int CmdIOClone(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
// {"demod", CmdIOProxDemod, 1, "Demodulate Stream"},
{"fskdemod",CmdIODemodFSK, 0, "['1'] Realtime IO FSK demodulator (option '1' for one tag only)"},
{"sim", CmdIOSim, 0, "<version> <facility-code> <card number> -- IOProx tag simulator"},
{"clone", CmdIOClone, 0, "<version> <facility-code> <card number> <Q5> -- Clone IOProx to T55x7"},
{"demod", CmdIOProxDemod, 1, "Demodulate an IOProx tag from the GraphBuffer"},
{"read", CmdIOProxRead, 1, "Attempt to read and extract tag data"},
{"sim", CmdIOProxSim, 0, "IOProx tag simulator"},
{"clone", CmdIOProxClone, 0, "Clone IOProx to T55x7"},
{NULL, NULL, 0, NULL}
};

View file

@ -5,26 +5,28 @@
#define CMDLFIO_H__
#include <stdio.h> // sscanf
#include <stdlib.h>
#include <string.h>
#include "proxmark3.h" // Definitions, USB controls, etc
#include "ui.h" // PrintAndLog
#include "cmdparser.h" // CmdsParse, CmdsHelp
#include "cmdlfawid.h" // AWID function declarations
#include "lfdemod.h" // parityTest
#include "util.h" // weigandparity
#include "protocols.h" // for T55xx config register definitions
#include <stdlib.h>
#include <string.h>
#include "data.h"
#include "cmdmain.h"
#include "cmddata.h"
#include "lfdemod.h" // bitbytes_to_byte
int CmdLFIO(const char *Cmd);
int CmdIODemodFSK(const char *Cmd);
int CmdIOClone(const char *Cmd);
extern int CmdLFIO(const char *Cmd);
extern int CmdIOProxDemod(const char *Cmd);
extern int CmdIOProxRead(const char *Cmd);
extern int CmdIOProxSim(const char *Cmd);
extern int CmdIOProxClone(const char *Cmd);
int getIOProxBits(uint8_t version, uint8_t fc, uint16_t cn, uint8_t *bits);
int usage_lf_io_fskdemod(void);
int usage_lf_io_clone(void);
int usage_lf_io_sim(void);
extern int usage_lf_io_read(void);
extern int usage_lf_io_clone(void);
extern int usage_lf_io_sim(void);
#endif

View file

@ -5,6 +5,7 @@
// the license.
//-----------------------------------------------------------------------------
// Low frequency Jablotron tag commands
// Differential Biphase, RF/64, 64 bits long (complete)
//-----------------------------------------------------------------------------
#include "cmdlfjablotron.h"
@ -58,6 +59,24 @@ int getJablotronBits(uint64_t fullcode, uint8_t *bits) {
return 1;
}
// ASK/Diphase fc/64 (inverted Biphase)
// Note: this is not a demod, this is only a detection
// the parameter *bits needs to be demoded before call
// 0xFFFF preamble, 64bits
int detectJablotron(uint8_t *bits, size_t *size) {
if (*size < 64*2) return -1; //make sure buffer has enough data
size_t startIdx = 0;
uint8_t preamble[] = {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0};
if (preambleSearch(bits, preamble, sizeof(preamble), size, &startIdx) == 0)
return -2; //preamble not found
if (*size != 64) return -3; // wrong demoded size
uint8_t checkchksum = jablontron_chksum(bits+startIdx);
uint8_t crc = bytebits_to_byte(bits+startIdx+56, 8);
if ( checkchksum != crc ) return -5;
return (int)startIdx;
}
static uint64_t getJablontronCardId( uint64_t rawcode ){
uint64_t id = 0;
uint8_t bytes[] = {0,0,0,0,0};
@ -79,7 +98,7 @@ int CmdJablotronDemod(const char *Cmd) {
return 0;
}
size_t size = DemodBufferLen;
int ans = JablotronDemod(DemodBuffer, &size);
int ans = detectJablotron(DemodBuffer, &size);
if (ans < 0){
if (g_debugMode){
if (ans == -1)
@ -96,8 +115,8 @@ int CmdJablotronDemod(const char *Cmd) {
return 0;
}
setDemodBuf(DemodBuffer+ans, 64, 0);
setGrid_Clock(64);
setDemodBuf(DemodBuffer, 64, ans);
setClockGrid(g_DemodClock, g_DemodStartIdx + (ans*g_DemodClock));
//got a good demod
uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32);
@ -106,7 +125,7 @@ int CmdJablotronDemod(const char *Cmd) {
uint64_t rawid = bytebits_to_byte(DemodBuffer+16, 40);
uint64_t id = getJablontronCardId(rawid);
PrintAndLog("Jablotron Tag Found: Card ID %u :: Raw: %08X%08X", id, raw1 ,raw2);
PrintAndLog("Jablotron Tag Found: Card ID: %"PRIx64" :: Raw: %08X%08X", id, raw1, raw2);
uint8_t chksum = raw2 & 0xFF;
PrintAndLog("Checksum: %02X [%s]",
@ -125,8 +144,7 @@ int CmdJablotronDemod(const char *Cmd) {
}
int CmdJablotronRead(const char *Cmd) {
CmdLFRead("s");
getSamples("10000", true);
lf_read(true, 10000);
return CmdJablotronDemod(Cmd);
}
@ -161,7 +179,6 @@ int CmdJablotronClone(const char *Cmd) {
return 1;
}
//
blocks[1] = bytebits_to_byte(bs,32);
blocks[2] = bytebits_to_byte(bs+32,32);
@ -219,7 +236,8 @@ int CmdJablotronSim(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"read", CmdJablotronRead, 0, "Attempt to read and extract tag data"},
{"demod", CmdJablotronDemod, 1, "Demodulate an Jablotron tag from the GraphBuffer"},
{"read", CmdJablotronRead, 0, "Attempt to read and extract tag data from the antenna"},
{"clone", CmdJablotronClone, 0, "clone jablotron tag"},
{"sim", CmdJablotronSim, 0, "simulate jablotron tag"},
{NULL, NULL, 0, NULL}

View file

@ -21,17 +21,21 @@
#include "cmdlf.h"
#include "protocols.h" // for T55xx config register definitions
#include "lfdemod.h" // parityTest
int CmdLFJablotron(const char *Cmd);
int CmdJablotronClone(const char *Cmd);
int CmdJablotronSim(const char *Cmd);
int CmdJablotronRead(const char *Cmd);
int CmdJablotronDemod(const char *Cmd);
int getJablotronBits(uint64_t fullcode, uint8_t *bits);
extern int CmdLFJablotron(const char *Cmd);
extern int CmdJablotronDemod(const char *Cmd);
extern int CmdJablotronRead(const char *Cmd);
extern int CmdJablotronClone(const char *Cmd);
extern int CmdJablotronSim(const char *Cmd);
extern int detectJablotron(uint8_t *bits, size_t *size);
extern int getJablotronBits(uint64_t fullcode, uint8_t *bits);
//extern int usage_lf_jablotron_demod(void);
//extern int usage_lf_jablotron_read(void);
extern int usage_lf_jablotron_clone(void);
extern int usage_lf_jablotron_sim(void);
int usage_lf_jablotron_clone(void);
int usage_lf_jablotron_sim(void);
int usage_lf_jablotron_read(void);
int usage_lf_jablotron_demod(void);
#endif

View file

@ -6,8 +6,7 @@
//-----------------------------------------------------------------------------
// Low frequency NEDAP tag commands
//-----------------------------------------------------------------------------
#include <string.h>
#include <inttypes.h>
#include "cmdlfnedap.h"
static int CmdHelp(const char *Cmd);
@ -37,6 +36,20 @@ int usage_lf_nedap_sim(void) {
return 0;
}
// find nedap preamble in already demoded data
int detectNedap(uint8_t *dest, size_t *size) {
//make sure buffer has data
if (*size < 128) return -3;
size_t startIdx = 0;
//uint8_t preamble[] = {1,1,1,1,1,1,1,1,1,0,0,0,1};
uint8_t preamble[] = {1,1,1,1,1,1,1,1,1,0};
if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx))
return -4; //preamble not found
return (int) startIdx;
}
int GetNedapBits(uint32_t cn, uint8_t *nedapBits) {
uint8_t pre[128];
@ -89,7 +102,7 @@ int CmdLFNedapDemod(const char *Cmd) {
return 0;
}
size_t size = DemodBufferLen;
int idx = NedapDemod(DemodBuffer, &size);
int idx = detectNedap(DemodBuffer, &size);
if (idx < 0){
if (g_debugMode){
// if (idx == -5)
@ -135,8 +148,8 @@ int CmdLFNedapDemod(const char *Cmd) {
raw[1] = bytebits_to_byte(DemodBuffer+idx+64,32);
raw[2] = bytebits_to_byte(DemodBuffer+idx+32,32);
raw[3] = bytebits_to_byte(DemodBuffer+idx,32);
setDemodBuf(DemodBuffer,128,idx);
setGrid_Clock(64);
setDemodBuf(DemodBuffer, 128, idx);
setClockGrid(g_DemodClock, g_DemodStartIdx + (idx*g_DemodClock));
uint8_t firstParity = GetParity( DemodBuffer, EVEN, 63);
if ( firstParity != DemodBuffer[63] ) {
@ -202,9 +215,8 @@ lf t55xx wr b 4 d 4c0003ff
*/
int CmdLFNedapRead(const char *Cmd) {
CmdLFRead("s");
getSamples("12000", true);
return CmdLFNedapDemod("");
lf_read(true, 12000);
return CmdLFNedapDemod(Cmd);
}
/*
int CmdLFNedapClone(const char *Cmd) {
@ -345,9 +357,9 @@ int CmdLFNedapChk(const char *Cmd){
return 0;
}
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"demod", CmdLFNedapDemod,0, "Demodulate an Nedap tag from the GraphBuffer"},
{"read", CmdLFNedapRead, 0, "Attempt to read and extract tag data"},
// {"clone", CmdLFNedapClone,0, "<Card Number> clone nedap tag"},
{"sim", CmdLFNedapSim, 0, "<Card Number> simulate nedap tag"},

View file

@ -4,10 +4,12 @@
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Low frequency T55xx commands
// Low frequency NEDAP tag commands
//-----------------------------------------------------------------------------
#ifndef CMDLFNEDAP_H__
#define CMDLFNEDAP_H__
#include <string.h>
#include <inttypes.h>
#include "proxmark3.h"
#include "ui.h"
#include "util.h"
@ -20,15 +22,17 @@
#include "lfdemod.h" // parityTest
#include "crc.h"
int CmdLFNedap(const char *Cmd);
int CmdLFNedapDemod(const char *Cmd);
int CmdLFNedapRead(const char *Cmd);
//int CmdLFNedapClone(const char *Cmd);
int CmdLFNedapSim(const char *Cmd);
int CmdLFNedapChk(const char *Cmd);
extern int CmdLFNedap(const char *Cmd);
extern int CmdLFNedapDemod(const char *Cmd);
extern int CmdLFNedapRead(const char *Cmd);
//extern int CmdLFNedapClone(const char *Cmd);
extern int CmdLFNedapSim(const char *Cmd);
extern int CmdLFNedapChk(const char *Cmd);
int usage_lf_nedap_read(void);
//int usage_lf_nedap_clone(void);
int usage_lf_nedap_sim(void);
extern int detectNedap(uint8_t *dest, size_t *size);
extern int usage_lf_nedap_read(void);
//extern int usage_lf_nedap_clone(void);
extern int usage_lf_nedap_sim(void);
#endif

View file

@ -7,50 +7,67 @@
// Low frequency Honeywell NexWatch tag commands
// PSK1 RF/16, RF/2, 128 bits long (known)
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <stdbool.h>
#include "cmdlfnexwatch.h"
#include "proxmark3.h"
#include "ui.h"
#include "util.h"
#include "graph.h"
#include "cmdparser.h"
#include "cmddata.h"
#include "cmdlf.h"
#include "lfdemod.h"
static int CmdHelp(const char *Cmd);
int CmdPSKNexWatch(const char *Cmd)
{
if (!PSKDemod("", false)) return 0;
uint8_t preamble[28] = {0,0,0,0,0,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
size_t startIdx = 0, size = DemodBufferLen;
int detectNexWatch(uint8_t *dest, size_t *size, bool *invert) {
uint8_t preamble[28] = {0,0,0,0,0,1,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
uint8_t preamble_i[28] = {1,1,1,1,1,0,1,0,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
// sanity check.
if ( size < sizeof(preamble) + 100) return 0;
if ( *size < sizeof(preamble) + 100) return -1;
bool invert = false;
if (!preambleSearch(DemodBuffer, preamble, sizeof(preamble), &size, &startIdx)){
size_t startIdx = 0;
if (!preambleSearch(DemodBuffer, preamble, sizeof(preamble), size, &startIdx)){
// if didn't find preamble try again inverting
if (!PSKDemod("1", false)) return 0;
size = DemodBufferLen;
if (!preambleSearch(DemodBuffer, preamble, sizeof(preamble), &size, &startIdx)) return 0;
invert = true;
if (!preambleSearch(DemodBuffer, preamble_i, sizeof(preamble_i), size, &startIdx)) return -4;
*invert ^= 1;
}
if (size != 128) return 0;
setDemodBuf(DemodBuffer, size, startIdx+4);
//setClockGrid(g_DemodClock, g_DemodStartIdx + ((startIdx+4)*g_DemodClock));
startIdx = 8+32; // 8 = preamble, 32 = reserved bits (always 0)
// size tests?
return (int) startIdx;
}
int CmdNexWatchDemod(const char *Cmd) {
if (!PSKDemod("", false)) {
if (g_debugMode) PrintAndLog("DEBUG: Error - NexWatch can't demod signal");
return 0;
}
bool invert = false;
size_t size = DemodBufferLen;
int idx = detectNexWatch(DemodBuffer, &size, &invert);
if (idx <= 0){
if (g_debugMode){
if (idx == -1)
PrintAndLog("DEBUG: Error - NexWatch not enough samples");
// else if (idx == -2)
// PrintAndLog("DEBUG: Error - NexWatch only noise found");
// else if (idx == -3)
// PrintAndLog("DEBUG: Error - NexWatch problem during PSK demod");
else if (idx == -4)
PrintAndLog("DEBUG: Error - NexWatch preamble not found");
// else if (idx == -5)
// PrintAndLog("DEBUG: Error - NexWatch size not correct: %d", size);
else
PrintAndLog("DEBUG: Error - NexWatch error %d",idx);
}
return 0;
}
setDemodBuf(DemodBuffer, size, idx+4);
setClockGrid(g_DemodClock, g_DemodStartIdx + ((idx+4)*g_DemodClock));
idx = 8+32; // 8 = preamble, 32 = reserved bits (always 0)
//get ID
uint32_t ID = 0;
for (uint8_t wordIdx=0; wordIdx<4; wordIdx++){
for (uint8_t idx=0; idx<8; idx++){
ID = (ID << 1) | DemodBuffer[startIdx+wordIdx+(idx*4)];
for (uint8_t k = 0; k < 4; k++){
for (uint8_t m = 0; m < 8; m++){
ID = (ID << 1) | DemodBuffer[m + k + (m*4)];
}
}
//parity check (TBD)
@ -60,9 +77,9 @@ int CmdPSKNexWatch(const char *Cmd)
//output
PrintAndLog("NexWatch ID: %d", ID);
if (invert){
PrintAndLog("DEBUG: Error - NexWatch had to Invert - probably NexKey");
for (uint8_t idx=0; idx<size; idx++)
DemodBuffer[idx] ^= 1;
PrintAndLog("Had to Invert - probably NexKey");
for (size_t i = 0; i < size; i++)
DemodBuffer[i] ^= 1;
}
CmdPrintDemodBuff("x");
@ -72,24 +89,18 @@ int CmdPSKNexWatch(const char *Cmd)
//by marshmellow
//see ASKDemod for what args are accepted
int CmdNexWatchRead(const char *Cmd) {
// read lf silently
//lf_read(true, 10000);
CmdLFRead("s");
getSamples("10000",true);
// demod and output viking ID
return CmdPSKNexWatch(Cmd);
lf_read(true, 10000);
return CmdNexWatchDemod(Cmd);
}
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"demod", CmdPSKNexWatch, 1, "Demodulate a NexWatch tag (nexkey, quadrakey) from the GraphBuffer"},
{"read", CmdNexWatchRead, 0, "Attempt to Read and Extract tag data from the antenna"},
{"help", CmdHelp, 1, "This help"},
{"demod", CmdNexWatchDemod, 1, "Demodulate a NexWatch tag (nexkey, quadrakey) from the GraphBuffer"},
{"read", CmdNexWatchRead, 0, "Attempt to Read and Extract tag data from the antenna"},
{NULL, NULL, 0, NULL}
};
int CmdLFNexWatch(const char *Cmd) {
int CmdLFNEXWATCH(const char *Cmd) {
CmdsParse(CommandTable, Cmd);
return 0;
}

View file

@ -8,7 +8,23 @@
//-----------------------------------------------------------------------------
#ifndef CMDLFNEXWATCH_H__
#define CMDLFNEXWATCH_H__
extern int CmdLFNexWatch(const char *Cmd);
extern int CmdPSKNexWatch(const char *Cmd);
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <stdbool.h>
#include "proxmark3.h"
#include "ui.h"
#include "util.h"
#include "graph.h"
#include "cmdparser.h"
#include "cmddata.h" // preamblesearch
#include "cmdlf.h"
#include "lfdemod.h"
extern int CmdLFNEXWATCH(const char *Cmd);
extern int CmdNexWatchDemod(const char *Cmd);
extern int CmdNexWatchRead(const char *Cmd);
extern int detectNexWatch(uint8_t *dest, size_t *size, bool *invert);
#endif

View file

@ -72,6 +72,18 @@ int getnoralsyBits(uint32_t id, uint16_t year, uint8_t *bits) {
return 1;
}
// by iceman
// find Noralsy preamble in already demoded data
int detectNoralsy(uint8_t *dest, size_t *size) {
if (*size < 96) return -1; //make sure buffer has data
size_t startIdx = 0;
uint8_t preamble[] = {1,0,1,1,1,0,1,1,0,0,0,0};
if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx))
return -2; //preamble not found
if (*size != 96) return -3; //wrong demoded size
//return start position
return (int)startIdx;
}
/*
*
* 2520116 | BB0214FF2529900116360000 | 10111011 00000011 00010100 11111111 00100101 00101001 10010000 00000001 00010110 00110110 00000000 00000000
@ -97,7 +109,7 @@ int CmdNoralsyDemod(const char *Cmd) {
if (!st) return 0;
size_t size = DemodBufferLen;
int ans = NoralsyDemod_AM(DemodBuffer, &size);
int ans = detectNoralsy(DemodBuffer, &size);
if (ans < 0){
if (g_debugMode){
if (ans == -1)
@ -112,7 +124,7 @@ int CmdNoralsyDemod(const char *Cmd) {
return 0;
}
setDemodBuf(DemodBuffer, 96, ans);
setGrid_Clock(32);
setClockGrid(g_DemodClock, g_DemodStartIdx + (ans*g_DemodClock));
//got a good demod
uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32);
@ -136,21 +148,24 @@ int CmdNoralsyDemod(const char *Cmd) {
chk2 = bytebits_to_byte(DemodBuffer+76, 4);
// test checksums
if ( chk1 != calc1 ) {
printf("checksum 1 failed %x - %x\n", chk1, calc1);
if (g_debugMode) PrintAndLog("DEBUG: Error - Noralsy: checksum 1 failed %x - %x\n", chk1, calc1);
return 0;
}
if ( chk2 != calc2 ) {
printf("checksum 2 failed %x - %x\n", chk2, calc2);
if (g_debugMode) PrintAndLog("DEBUG: Error - Noralsy: checksum 2 failed %x - %x\n", chk2, calc2);
return 0;
}
PrintAndLog("Noralsy Tag Found: Card ID %u, Year: %u Raw: %08X%08X%08X", cardid, year, raw1 ,raw2, raw3);
if (raw1 != 0xBB0214FF) {
PrintAndLog("Unknown bits set in first block! Expected 0xBB0214FF, Found: 0x%08X", raw1);
PrintAndLog("Please post this output in forum to further research on this format");
}
return 1;
}
int CmdNoralsyRead(const char *Cmd) {
CmdLFRead("s");
getSamples("8000",true);
lf_read(true, 8000);
return CmdNoralsyDemod(Cmd);
}
@ -246,9 +261,10 @@ int CmdNoralsySim(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"read", CmdNoralsyRead, 0, "Attempt to read and extract tag data"},
{"clone", CmdNoralsyClone,0, "clone Noralsy tag"},
{"sim", CmdNoralsySim, 0, "simulate Noralsy tag"},
{"demod", CmdNoralsyDemod,1, "Demodulate an Noralsy tag from the GraphBuffer"},
{"read", CmdNoralsyRead, 0, "Attempt to read and extract tag data from the antenna"},
{"sim", CmdNoralsySim, 0, "Noralsy tag simulator"},
{"clone", CmdNoralsyClone,0, "clone Noralsy to T55x7"},
{NULL, NULL, 0, NULL}
};

View file

@ -23,16 +23,16 @@
#include "lfdemod.h" // parityTest
extern int CmdLFNoralsy(const char *Cmd);
extern int CmdNoralsyDemod(const char *Cmd);
extern int CmdNoralsyRead(const char *Cmd);
extern int CmdNoralsyClone(const char *Cmd);
extern int CmdNoralsySim(const char *Cmd);
extern int CmdNoralsyRead(const char *Cmd);
extern int CmdNoralsyDemod(const char *Cmd);
int getnoralsyBits(uint32_t id, uint16_t year, uint8_t *bits);
int usage_lf_noralsy_clone(void);
int usage_lf_noralsy_sim(void);
int usage_lf_noralsy_read(void);
int usage_lf_noralsy_demod(void);
extern int usage_lf_noralsy_clone(void);
extern int usage_lf_noralsy_sim(void);
//extern int usage_lf_noralsy_read(void);
//extern int usage_lf_noralsy_demod(void);
#endif

View file

@ -8,23 +8,12 @@
// NRZ, RF/32, 128 bits long (unknown cs)
//-----------------------------------------------------------------------------
#include "cmdlfpac.h"
#include <string.h>
#include <inttypes.h>
#include "proxmark3.h"
#include "ui.h"
#include "util.h"
#include "graph.h"
#include "cmdparser.h"
#include "cmddata.h"
#include "cmdmain.h"
#include "cmdlf.h"
#include "lfdemod.h" // preamble test
static int CmdHelp(const char *Cmd);
// by marshmellow
// find PAC preamble in already demoded data
int PacFind(uint8_t *dest, size_t *size) {
int detectPac(uint8_t *dest, size_t *size) {
if (*size < 128) return -1; //make sure buffer has data
size_t startIdx = 0;
uint8_t preamble[] = {1,1,1,1,1,1,1,1,0,0,1,0,0,0,0,0,0,1,0};
@ -44,7 +33,7 @@ int CmdPacDemod(const char *Cmd) {
return 0;
}
size_t size = DemodBufferLen;
int ans = PacFind(DemodBuffer, &size);
int ans = detectPac(DemodBuffer, &size);
if (ans < 0) {
if (g_debugMode) {
if (ans == -1)
@ -59,7 +48,7 @@ int CmdPacDemod(const char *Cmd) {
return 0;
}
setDemodBuf(DemodBuffer, 128, ans);
// setClockGrid(g_DemodClock, g_DemodStartIdx + (ans*g_DemodClock));
setClockGrid(g_DemodClock, g_DemodStartIdx + (ans*g_DemodClock));
//got a good demod
uint32_t raw1 = bytebits_to_byte(DemodBuffer , 32);
@ -77,15 +66,13 @@ int CmdPacDemod(const char *Cmd) {
}
int CmdPacRead(const char *Cmd) {
//lf_read(true, 4096*2 + 20);
CmdLFRead("s");
getSamples("8192",true);
lf_read(true, 4096*2 + 20);
return CmdPacDemod(Cmd);
}
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"demod", CmdPacDemod,1, "Attempt to read and extract tag data from the GraphBuffer"},
{"demod", CmdPacDemod,1, "Demodulate an PAC tag from the GraphBuffer"},
{"read", CmdPacRead, 0, "Attempt to read and extract tag data from the antenna"},
{NULL, NULL, 0, NULL}
};

View file

@ -4,14 +4,27 @@
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Low frequency Securakey tag commands
// Low frequency Stanley/PAC tag commands
//-----------------------------------------------------------------------------
#ifndef CMDLFPAC_H__
#define CMDLFPAC_H__
#include <string.h>
#include <inttypes.h>
#include "proxmark3.h"
#include "ui.h"
#include "util.h"
#include "graph.h"
#include "cmdparser.h"
#include "cmddata.h"
#include "cmdmain.h"
#include "cmdlf.h"
#include "lfdemod.h" // preamble test
extern int CmdLFPac(const char *Cmd);
extern int CmdPacRead(const char *Cmd);
extern int CmdPacDemod(const char *Cmd);
extern int detectPac(uint8_t *dest, size_t *size);
#endif

135
client/cmdlfparadox.c Normal file
View file

@ -0,0 +1,135 @@
//-----------------------------------------------------------------------------
//
// 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.
//-----------------------------------------------------------------------------
// Low frequency Paradox tag commands
// FSK2a, rf/50, 96 bits (completely known)
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "cmdlfparadox.h"
#include "proxmark3.h"
#include "ui.h"
#include "util.h"
#include "graph.h"
#include "cmdparser.h"
#include "cmddata.h"
#include "cmdlf.h"
#include "lfdemod.h"
static int CmdHelp(const char *Cmd);
// loop to get raw paradox waveform then FSK demodulate the TAG ID from it
int detectParadox(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo, int *waveStartIdx) {
if (justNoise(dest, *size)) return -1;
size_t numStart = 0, startIdx = 0;
// FSK demodulator
*size = fskdemod(dest, *size, 50, 1, 10, 8, waveStartIdx); //fsk2a
if (*size < 96) return -2;
// 00001111 bit pattern represent start of frame, 01 pattern represents a 0 and 10 represents a 1
uint8_t preamble[] = {0,0,0,0,1,1,1,1};
if (preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx))
return -3; //preamble not found
numStart = startIdx + sizeof(preamble);
// final loop, go over previously decoded FSK data and manchester decode into usable tag ID
for (size_t idx = numStart; (idx-numStart) < *size - sizeof(preamble); idx+=2){
if (dest[idx] == dest[idx+1])
return -4; //not manchester data
*hi2 = (*hi2<<1)|(*hi>>31);
*hi = (*hi<<1)|(*lo>>31);
//Then, shift in a 0 or one into low
if (dest[idx] && !dest[idx+1]) // 1 0
*lo=(*lo<<1)|1;
else // 0 1
*lo=(*lo<<1)|0;
}
return (int)startIdx;
}
//by marshmellow
//Paradox Prox demod - FSK RF/50 with preamble of 00001111 (then manchester encoded)
//print full Paradox Prox ID and some bit format details if found
int CmdParadoxDemod(const char *Cmd) {
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
uint8_t bits[MAX_GRAPH_TRACE_LEN]={0};
size_t BitLen = getFromGraphBuf(bits);
if (BitLen==0) return 0;
uint32_t hi2=0, hi=0, lo=0;
int waveIdx=0;
//get binary from fsk wave
int idx = detectParadox(bits, &BitLen, &hi2, &hi, &lo, &waveIdx);
if (idx < 0){
if (g_debugMode){
if (idx == -1){
PrintAndLog("DEBUG: Error - Paradox just noise detected");
} else if (idx == -2) {
PrintAndLog("DEBUG: Error - Paradox error demoding fsk");
} else if (idx == -3) {
PrintAndLog("DEBUG: Error - Paradox preamble not found");
} else if (idx == -4) {
PrintAndLog("DEBUG: Error - Paradox error in Manchester data");
} else {
PrintAndLog("DEBUG: Error - Paradox error demoding fsk %d", idx);
}
}
return 0;
}
if (hi2==0 && hi==0 && lo==0){
if (g_debugMode) PrintAndLog("DEBUG: Error - Paradox no value found");
return 0;
}
uint32_t fc = ((hi & 0x3)<<6) | (lo>>26);
uint32_t cardnum = (lo>>10) & 0xFFFF;
uint32_t rawLo = bytebits_to_byte(bits + idx + 64, 32);
uint32_t rawHi = bytebits_to_byte(bits + idx + 32, 32);
uint32_t rawHi2 = bytebits_to_byte(bits + idx, 32);
PrintAndLog("Paradox TAG ID: %x%08x - FC: %d - Card: %d - Checksum: %02x - RAW: %08x%08x%08x",
hi >> 10,
(hi & 0x3)<<26 | (lo>>10),
fc, cardnum,
(lo>>2) & 0xFF,
rawHi2,
rawHi,
rawLo
);
setDemodBuf(bits, BitLen, idx);
setClockGrid(50, waveIdx + (idx*50));
if (g_debugMode){
PrintAndLog("DEBUG: Paradox idx: %d, len: %d, Printing Demod Buffer:", idx, BitLen);
printDemodBuff();
}
return 1;
}
//by marshmellow
//see ASKDemod for what args are accepted
int CmdParadoxRead(const char *Cmd) {
lf_read(true, 10000);
return CmdParadoxDemod(Cmd);
}
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"demod", CmdParadoxDemod, 1, "Demodulate a Paradox FSK tag from the GraphBuffer"},
{"read", CmdParadoxRead, 0, "Attempt to read and Extract tag data from the antenna"},
{NULL, NULL, 0, NULL}
};
int CmdLFParadox(const char *Cmd) {
CmdsParse(CommandTable, Cmd);
return 0;
}
int CmdHelp(const char *Cmd) {
CmdsHelp(CommandTable);
return 0;
}

16
client/cmdlfparadox.h Normal file
View file

@ -0,0 +1,16 @@
//-----------------------------------------------------------------------------
//
// 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.
//-----------------------------------------------------------------------------
// Low frequency Paradox tag commands
//-----------------------------------------------------------------------------
#ifndef CMDLFPARADOX_H__
#define CMDLFPARADOX_H__
extern int CmdLFParadox(const char *Cmd);
extern int CmdParadoxDemod(const char *Cmd);
extern int CmdParadoxRead(const char *Cmd);
extern int detectParadox(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo, int *waveStartIdx);
#endif

View file

@ -12,6 +12,7 @@
#include <string.h>
#include "proxmark3.h"
#include "ui.h"
#include "util.h"
#include "graph.h"
#include "cmdparser.h"
#include "cmddata.h"
@ -156,8 +157,7 @@ int CmdLFPCF7931Write(const char *Cmd){
return 0;
}
static command_t CommandTable[] =
{
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"read", CmdLFPCF7931Read, 0, "Read content of a PCF7931 transponder"},
{"write", CmdLFPCF7931Write, 0, "Write data on a PCF7931 transponder."},

View file

@ -6,8 +6,7 @@
//-----------------------------------------------------------------------------
// Low frequency Presco tag commands
//-----------------------------------------------------------------------------
#include <string.h>
#include <inttypes.h>
#include "cmdlfpresco.h"
static int CmdHelp(const char *Cmd);
@ -37,6 +36,18 @@ int usage_lf_presco_sim(void) {
return 0;
}
// find presco preamble 0x10D in already demoded data
int detectPresco(uint8_t *dest, size_t *size) {
if (*size < 128*2) return -1; //make sure buffer has data
size_t startIdx = 0;
uint8_t preamble[] = {0,0,0,1,0,0,0,0,1,1,0,1,0,0,0,0,0,0,0,0,0,0,0};
if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx))
return -2; //preamble not found
if (*size != 128) return -3; //wrong demoded size
//return start position
return (int)startIdx;
}
// convert base 12 ID to sitecode & usercode & 8 bit other unknown code
int GetWiegandFromPresco(const char *Cmd, uint32_t *sitecode, uint32_t *usercode, uint32_t *fullcode, bool *Q5) {
@ -57,12 +68,12 @@ int GetWiegandFromPresco(const char *Cmd, uint32_t *sitecode, uint32_t *usercode
*fullcode = param_get32ex(Cmd, cmdp+1, 0, 16);
cmdp+=2;
break;
case 'P':
case 'p':
case 'D':
case 'd':
//param get string int param_getstr(const char *line, int paramnum, char * str)
stringlen = param_getstr(Cmd, cmdp+1, id);
if (stringlen < 2) return -1;
cmdp+=2;
cmdp += 2;
break;
case 'Q':
case 'q':
@ -117,8 +128,7 @@ int CmdPrescoDemod(const char *Cmd) {
return 0;
}
size_t size = DemodBufferLen;
//call lfdemod.c demod for Presco
int ans = PrescoDemod(DemodBuffer, &size);
int ans = detectPresco(DemodBuffer, &size);
if (ans < 0) {
if (g_debugMode){
if (ans == -1)
@ -133,7 +143,7 @@ int CmdPrescoDemod(const char *Cmd) {
return 0;
}
setDemodBuf(DemodBuffer, 128, ans);
setGrid_Clock(32);
setClockGrid(g_DemodClock, g_DemodStartIdx + (ans*g_DemodClock));
//got a good demod
uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32);
@ -155,12 +165,7 @@ int CmdPrescoDemod(const char *Cmd) {
//see ASKDemod for what args are accepted
int CmdPrescoRead(const char *Cmd) {
// Presco Number: 123456789 --> Sitecode 30 | usercode 8665
// read lf silently
CmdLFRead("s");
// get samples silently
getSamples("12000", true);
// demod and output Presco ID
lf_read(true, 12000);
return CmdPrescoDemod(Cmd);
}

View file

@ -8,6 +8,8 @@
//-----------------------------------------------------------------------------
#ifndef CMDLFPRESCO_H__
#define CMDLFPRESCO_H__
#include <string.h>
#include <inttypes.h>
#include "proxmark3.h"
#include "ui.h"
#include "util.h"
@ -20,14 +22,15 @@
#include "lfdemod.h" // parityTest
extern int CmdLFPresco(const char *Cmd);
extern int CmdPrescoClone(const char *Cmd);
extern int CmdPrescoSim(const char *Cmd);
extern int CmdPrescoRead(const char *Cmd);
extern int CmdPrescoDemod(const char *Cmd);
extern int CmdPrescoClone(const char *Cmd);
extern int CmdPrescoSim(const char *Cmd);
extern int detectPresco(uint8_t *dest, size_t *size);
int GetWiegandFromPresco(const char *id, uint32_t *sitecode, uint32_t *usercode, uint32_t *fullcode, bool *Q5);
int usage_lf_presco_clone(void);
int usage_lf_presco_sim(void);
extern int usage_lf_presco_clone(void);
extern int usage_lf_presco_sim(void);
#endif

View file

@ -7,9 +7,8 @@
// Low frequency Farpoint / Pyramid tag commands
// FSK2a, rf/50, 128 bits (complete)
//-----------------------------------------------------------------------------
#include <string.h>
#include <inttypes.h>
#include "cmdlfpyramid.h"
static int CmdHelp(const char *Cmd);
int usage_lf_pyramid_clone(void){
@ -42,6 +41,26 @@ int usage_lf_pyramid_sim(void) {
return 0;
}
// by marshmellow
// FSK Demod then try to locate a Farpointe Data (pyramid) ID
int detectPyramid(uint8_t *dest, size_t *size, int *waveStartIdx) {
//make sure buffer has data
if (*size < 128*50) return -5;
//test samples are not just noise
if (justNoise(dest, *size)) return -1;
// FSK demodulator
*size = fskdemod(dest, *size, 50, 1, 10, 8, waveStartIdx); // fsk2a RF/50
if (*size < 128) return -2; //did we get a good demod?
size_t startIdx = 0;
uint8_t preamble[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1};
if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx))
return -4; //preamble not found
if (*size != 128) return -3;
return (int)startIdx;
}
// Works for 26bits.
int GetPyramidBits(uint32_t fc, uint32_t cn, uint8_t *pyramidBits) {
@ -73,10 +92,155 @@ int GetPyramidBits(uint32_t fc, uint32_t cn, uint8_t *pyramidBits) {
return 1;
}
//by marshmellow
//Pyramid Prox demod - FSK RF/50 with preamble of 0000000000000001 (always a 128 bit data stream)
//print full Farpointe Data/Pyramid Prox ID and some bit format details if found
int CmdPyramidDemod(const char *Cmd) {
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
size_t size = getFromGraphBuf(BitStream);
if (size==0) return 0;
int waveIdx=0;
//get binary from fsk wave
int idx = detectPyramid(BitStream, &size, &waveIdx);
if (idx < 0){
if (g_debugMode){
if (idx == -5)
PrintAndLog("DEBUG: Error - Pyramid: not enough samples");
else if (idx == -1)
PrintAndLog("DEBUG: Error - Pyramid: only noise found");
else if (idx == -2)
PrintAndLog("DEBUG: Error - Pyramid: problem during FSK demod");
else if (idx == -3)
PrintAndLog("DEBUG: Error - Pyramid: size not correct: %d", size);
else if (idx == -4)
PrintAndLog("DEBUG: Error - Pyramid: preamble not found");
else
PrintAndLog("DEBUG: Error - Pyramid: idx: %d",idx);
}
return 0;
}
// Index map
// 0 10 20 30 40 50 60
// | | | | | | |
// 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3
// -----------------------------------------------------------------------------
// 0000000 0 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1
// premable xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o
// 64 70 80 90 100 110 120
// | | | | | | |
// 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7
// -----------------------------------------------------------------------------
// 0000000 1 0000000 1 0000000 1 0110111 0 0011000 1 0000001 0 0001100 1 1001010 0
// xxxxxxx o xxxxxxx o xxxxxxx o xswffff o ffffccc o ccccccc o ccccccw o ppppppp o
// |---115---||---------71---------|
// s = format start bit, o = odd parity of last 7 bits
// f = facility code, c = card number
// w = wiegand parity, x = extra space for other formats
// p = CRC8maxim checksum
// (26 bit format shown)
//get bytes for checksum calc
uint8_t checksum = bytebits_to_byte(BitStream + idx + 120, 8);
uint8_t csBuff[14] = {0x00};
for (uint8_t i = 0; i < 13; i++){
csBuff[i] = bytebits_to_byte(BitStream + idx + 16 + (i*8), 8);
}
//check checksum calc
//checksum calc thanks to ICEMAN!!
uint32_t checkCS = CRC8Maxim(csBuff, 13);
//get raw ID before removing parities
uint32_t rawLo = bytebits_to_byte(BitStream+idx+96, 32);
uint32_t rawHi = bytebits_to_byte(BitStream+idx+64, 32);
uint32_t rawHi2 = bytebits_to_byte(BitStream+idx+32, 32);
uint32_t rawHi3 = bytebits_to_byte(BitStream+idx, 32);
setDemodBuf(BitStream, 128, idx);
setClockGrid(50, waveIdx + (idx*50));
size = removeParity(BitStream, idx+8, 8, 1, 120);
if (size != 105){
if (g_debugMode) {
if ( size == 0)
PrintAndLog("DEBUG: Error - Pyramid: parity check failed - IDX: %d, hi3: %08X", idx, rawHi3);
else
PrintAndLog("DEBUG: Error - Pyramid: at parity check - tag size does not match Pyramid format, SIZE: %d, IDX: %d, hi3: %08X", size, idx, rawHi3);
}
return 0;
}
// ok valid card found!
// Index map
// 0 10 20 30 40 50 60 70
// | | | | | | | |
// 01234567890123456789012345678901234567890123456789012345678901234567890
// -----------------------------------------------------------------------
// 00000000000000000000000000000000000000000000000000000000000000000000000
// xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// 71 80 90 100
// | | | |
// 1 2 34567890 1234567890123456 7 8901234
// ---------------------------------------
// 1 1 01110011 0000000001000110 0 1001010
// s w ffffffff cccccccccccccccc w ppppppp
// |--115-| |------71------|
// s = format start bit, o = odd parity of last 7 bits
// f = facility code, c = card number
// w = wiegand parity, x = extra space for other formats
// p = CRC8-Maxim checksum
// (26 bit format shown)
//find start bit to get fmtLen
int j;
for (j=0; j < size; ++j){
if(BitStream[j]) break;
}
uint8_t fmtLen = size-j-8;
uint32_t fc = 0;
uint32_t cardnum = 0;
uint32_t code1 = 0;
if ( fmtLen == 26 ){
fc = bytebits_to_byte(BitStream+73, 8);
cardnum = bytebits_to_byte(BitStream+81, 16);
code1 = bytebits_to_byte(BitStream+72,fmtLen);
PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi3, rawHi2, rawHi, rawLo);
} else if (fmtLen == 45) {
fmtLen = 42; //end = 10 bits not 7 like 26 bit fmt
fc = bytebits_to_byte(BitStream+53, 10);
cardnum = bytebits_to_byte(BitStream+63, 32);
PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Raw: %08x%08x%08x%08x", fmtLen, fc, cardnum, rawHi3, rawHi2, rawHi, rawLo);
} else {
cardnum = bytebits_to_byte(BitStream+81, 16);
if (fmtLen>32){
//code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen-32);
//code2 = bytebits_to_byte(BitStream+(size-32),32);
PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo);
} else{
//code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen);
PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo);
}
}
if (checksum == checkCS)
PrintAndLog("Checksum %02x passed", checksum);
else
PrintAndLog("Checksum %02x failed - should have been %02x", checksum, checkCS);
if (g_debugMode){
PrintAndLog("DEBUG: Pyramid: idx: %d, Len: %d, Printing Demod Buffer:", idx, 128);
printDemodBuff();
}
return 1;
}
int CmdPyramidRead(const char *Cmd) {
CmdLFRead("s");
getSamples("12000", true);
return CmdFSKdemodPyramid("");
lf_read(true, 15000);
return CmdPyramidDemod(Cmd);
}
int CmdPyramidClone(const char *Cmd) {
@ -171,9 +335,10 @@ int CmdPyramidSim(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"read", CmdPyramidRead, 0, "Attempt to read and extract tag data"},
{"clone", CmdPyramidClone, 0, "<Facility-Code> <Card Number> clone pyramid tag"},
{"sim", CmdPyramidSim, 0, "<Facility-Code> <Card Number> simulate pyramid tag"},
{"demod", CmdPyramidDemod,0, "Demodulate a Pyramid FSK tag from the GraphBuffer"},
{"read", CmdPyramidRead, 0, "Attempt to read and extract tag data"},
{"clone", CmdPyramidClone,0, "<Facility-Code> <Card Number> clone pyramid tag"},
{"sim", CmdPyramidSim, 0, "<Facility-Code> <Card Number> simulate pyramid tag"},
{NULL, NULL, 0, NULL}
};

View file

@ -8,6 +8,8 @@
//-----------------------------------------------------------------------------
#ifndef CMDLFPYRAMID_H__
#define CMDLFPYRAMID_H__
#include <string.h>
#include <inttypes.h>
#include "proxmark3.h"
#include "ui.h"
#include "util.h"
@ -20,11 +22,15 @@
#include "lfdemod.h" // parityTest
#include "crc.h"
int CmdLFPyramid(const char *Cmd);
int CmdPyramidClone(const char *Cmd);
int CmdPyramidSim(const char *Cmd);
extern int CmdLFPyramid(const char *Cmd);
extern int CmdPyramidDemod(const char *Cmd);
extern int CmdPyramidRead(const char *Cmd);
extern int CmdPyramidClone(const char *Cmd);
extern int CmdPyramidSim(const char *Cmd);
int usage_lf_pyramid_clone(void);
int usage_lf_pyramid_sim(void);
extern int detectPyramid(uint8_t *dest, size_t *size, int *waveStartIdx);
extern int usage_lf_pyramid_clone(void);
extern int usage_lf_pyramid_sim(void);
#endif

View file

@ -8,26 +8,12 @@
// ASK/Manchester, RF/40, 96 bits long (unknown cs)
//-----------------------------------------------------------------------------
#include "cmdlfsecurakey.h"
#include <string.h>
#include <inttypes.h>
#include <math.h>
#include "proxmark3.h"
#include "ui.h"
#include "util.h"
#include "graph.h"
#include "cmdparser.h"
#include "cmddata.h"
#include "cmdmain.h"
#include "cmdlf.h"
#include "protocols.h" // for T55xx config register definitions
#include "lfdemod.h" // preamble test
#include "parity.h" // for wiegand parity test
static int CmdHelp(const char *Cmd);
// by marshmellow
// find Securakey preamble in already demoded data
int SecurakeyFind(uint8_t *dest, size_t *size) {
int detectSecurakey(uint8_t *dest, size_t *size) {
if (*size < 96) return -1; //make sure buffer has data
size_t startIdx = 0;
uint8_t preamble[] = {0,1,1,1,1,1,1,1,1,1,0,0,1};
@ -49,7 +35,7 @@ int CmdSecurakeyDemod(const char *Cmd) {
}
if (st) return 0;
size_t size = DemodBufferLen;
int ans = SecurakeyFind(DemodBuffer, &size);
int ans = detectSecurakey(DemodBuffer, &size);
if (ans < 0) {
if (g_debugMode) {
if (ans == -1)
@ -64,7 +50,7 @@ int CmdSecurakeyDemod(const char *Cmd) {
return 0;
}
setDemodBuf(DemodBuffer, 96, ans);
//setClockGrid(g_DemodClock, g_DemodStartIdx + (ans*g_DemodClock));
setClockGrid(g_DemodClock, g_DemodStartIdx + (ans*g_DemodClock));
//got a good demod
uint32_t raw1 = bytebits_to_byte(DemodBuffer , 32);
@ -123,15 +109,13 @@ int CmdSecurakeyDemod(const char *Cmd) {
}
int CmdSecurakeyRead(const char *Cmd) {
//lf_read(true, 8000);
CmdLFRead("s");
getSamples("8000",true);
lf_read(true, 8000);
return CmdSecurakeyDemod(Cmd);
}
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"demod", CmdSecurakeyDemod,1, "Attempt to read and extract tag data from the GraphBuffer"},
{"demod", CmdSecurakeyDemod,1, "Demodulate an Securakey tag from the GraphBuffer"},
{"read", CmdSecurakeyRead, 0, "Attempt to read and extract tag data from the antenna"},
{NULL, NULL, 0, NULL}
};

View file

@ -9,9 +9,24 @@
#ifndef CMDLFSECURAKEY_H__
#define CMDLFSECURAKEY_H__
#include <string.h>
#include <inttypes.h>
#include <math.h>
#include "proxmark3.h"
#include "ui.h"
#include "util.h"
#include "graph.h"
#include "cmdparser.h"
#include "cmddata.h"
#include "cmdmain.h"
#include "cmdlf.h"
#include "protocols.h" // for T55xx config register definitions
#include "lfdemod.h" // preamble test
#include "parity.h" // for wiegand parity test
extern int CmdLFSecurakey(const char *Cmd);
extern int CmdSecurakeyClone(const char *Cmd);
extern int CmdSecurakeySim(const char *Cmd);
//extern int CmdSecurakeyClone(const char *Cmd);
//extern int CmdSecurakeySim(const char *Cmd);
extern int CmdSecurakeyRead(const char *Cmd);
extern int CmdSecurakeyDemod(const char *Cmd);

View file

@ -55,12 +55,13 @@ int usage_t55xx_read(){
return 0;
}
int usage_t55xx_write(){
PrintAndLog("Usage: lf t55xx write [b <block>] [d <data>] [p <password>] [1]");
PrintAndLog("Usage: lf t55xx write [b <block>] [d <data>] [p <password>] [1] [t]");
PrintAndLog("Options:");
PrintAndLog(" b <block> - block number to write. Between 0-7");
PrintAndLog(" d <data> - 4 bytes of data to write (8 hex characters)");
PrintAndLog(" p <password> - OPTIONAL password 4bytes (8 hex characters)");
PrintAndLog(" 1 - OPTIONAL write Page 1 instead of Page 0");
PrintAndLog(" t - OPTIONAL test mode write - ****DANGER****");
PrintAndLog("");
PrintAndLog("Examples:");
PrintAndLog(" lf t55xx write b 3 d 11223344 - write 11223344 to block 3");
@ -115,6 +116,20 @@ int usage_t55xx_detect(){
PrintAndLog("");
return 0;
}
int usage_t55xx_detectP1(){
PrintAndLog("Command: Detect Page 1 of a t55xx chip");
PrintAndLog("Usage: lf t55xx p1detect [1] [p <password>]");
PrintAndLog("Options:");
PrintAndLog(" 1 - if set, use Graphbuffer otherwise read data from tag.");
PrintAndLog(" p <password> - OPTIONAL password (8 hex characters)");
PrintAndLog("");
PrintAndLog("Examples:");
PrintAndLog(" lf t55xx p1detect");
PrintAndLog(" lf t55xx p1detect 1");
PrintAndLog(" lf t55xx p1detect p 11223344");
PrintAndLog("");
return 0;
}
int usage_t55xx_wakup(){
PrintAndLog("Usage: lf t55xx wakeup [h] p <password>");
PrintAndLog("This commands send the Answer-On-Request command and leaves the readerfield ON afterwards.");
@ -395,23 +410,23 @@ bool DecodeT55xxBlock(){
break;
case DEMOD_PSK1:
// skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)
save_restoreGB(1);
save_restoreGB(GRAPH_SAVE);
CmdLtrim("160");
snprintf(cmdStr, sizeof(buf),"%d %d 6", bitRate[config.bitrate], config.inverted );
ans = PSKDemod(cmdStr, false);
//undo trim samples
save_restoreGB(0);
save_restoreGB(GRAPH_RESTORE);
break;
case DEMOD_PSK2: //inverted won't affect this
case DEMOD_PSK3: //not fully implemented
// skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)
save_restoreGB(1);
save_restoreGB(GRAPH_SAVE);
CmdLtrim("160");
snprintf(cmdStr, sizeof(buf),"%d 0 6", bitRate[config.bitrate] );
ans = PSKDemod(cmdStr, false);
psk1TOpsk2(DemodBuffer, DemodBufferLen);
//undo trim samples
save_restoreGB(0);
save_restoreGB(GRAPH_RESTORE);
break;
case DEMOD_NRZ:
snprintf(cmdStr, sizeof(buf),"%d %d 1", bitRate[config.bitrate], config.inverted );
@ -494,10 +509,10 @@ bool tryDetectModulation(){
uint8_t hits = 0;
t55xx_conf_block_t tests[15];
int bitRate=0;
uint8_t fc1 = 0, fc2 = 0, clk=0;
if (GetFskClock("", false, false)){
fskClocks(&fc1, &fc2, &clk, false);
uint8_t fc1 = 0, fc2 = 0, ans = 0;
int clk = 0, firstClockEdge = 0;
ans = fskClocks(&fc1, &fc2, (uint8_t *)&clk, false, &firstClockEdge);
if (ans && ((fc1==10 && fc2==8) || (fc1==8 && fc2==5))) {
if ( FSKrawDemod("0 0", false) && test(DEMOD_FSK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)){
tests[hits].modulation = DEMOD_FSK;
if (fc1==8 && fc2 == 5)
@ -568,10 +583,8 @@ bool tryDetectModulation(){
++hits;
}
}
//undo trim from ask
//save_restoreGB(0);
clk = GetNrzClock("", false, false);
if (clk>0) {
if (clk>8) { //clock of rf/8 is likely a false positive, so don't use it.
if ( NRZrawDemod("0 0 1", false) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
tests[hits].modulation = DEMOD_NRZ;
tests[hits].bitrate = bitRate;
@ -591,12 +604,12 @@ bool tryDetectModulation(){
}
}
// allow undo
// skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)
save_restoreGB(1);
CmdLtrim("160");
clk = GetPskClock("", false, false);
if (clk>0) {
// allow undo
save_restoreGB(GRAPH_SAVE);
// skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)
CmdLtrim("160");
if ( PSKDemod("0 0 6", false) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
tests[hits].modulation = DEMOD_PSK1;
tests[hits].bitrate = bitRate;
@ -638,9 +651,9 @@ bool tryDetectModulation(){
++hits;
}
} // inverse waves does not affect this demod
}
//undo trim samples
save_restoreGB(0);
save_restoreGB(GRAPH_RESTORE);
}
}
if ( hits == 1) {
config.modulation = tests[0].modulation;
@ -829,9 +842,7 @@ bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5)
// moved test to here, since this gets most faults first.
if ( resv > 0x00) continue;
uint8_t xtRate = PackBits(si, 3, DemodBuffer); si += 3; //extended mode part of rate
int bitRate = PackBits(si, 3, DemodBuffer); si += 3; //bit rate
if (bitRate > 7) continue;
int bitRate = PackBits(si, 6, DemodBuffer); si += 6; //bit rate (includes extended mode part of rate)
uint8_t extend = PackBits(si, 1, DemodBuffer); si += 1; //bit 15 extended mode
uint8_t modread = PackBits(si, 5, DemodBuffer); si += 5+2+1;
//uint8_t pskcr = PackBits(si, 2, DemodBuffer); si += 2+1; //could check psk cr
@ -842,11 +853,14 @@ bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5)
bool extMode =( (safer == 0x6 || safer == 0x9) && extend) ? true : false;
if (!extMode){
if (xtRate) continue; //nml01 || nml02 || caused issues on noralys tags
if (bitRate > 7) continue;
if (!testBitRate(bitRate, clk)) continue;
} else { //extended mode bitrate = same function to calc bitrate as em4x05
if (EM4x05_GET_BITRATE(bitRate) != clk) continue;
}
//test modulation
if (!testModulation(mode, modread)) continue;
if (!testBitRate(bitRate, clk)) continue;
*fndBitRate = bitRate;
*offset = idx;
*Q5 = false;
@ -905,7 +919,7 @@ int special(const char *Cmd) {
int printConfiguration( t55xx_conf_block_t b){
PrintAndLog("Chip Type : %s", (b.Q5) ? "T5555(Q5)" : "T55x7");
PrintAndLog("Modulation : %s", GetSelectedModulationStr(b.modulation) );
PrintAndLog("Bit Rate : %s", GetBitRateStr(b.bitrate) );
PrintAndLog("Bit Rate : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE && (b.block0>>28==6 || b.block0>>28==9))) );
PrintAndLog("Inverted : %s", (b.inverted) ? "Yes" : "No" );
PrintAndLog("Offset : %d", b.offset);
PrintAndLog("Seq. Term. : %s", (b.ST) ? "Yes" : "No" );
@ -951,6 +965,7 @@ int CmdT55xxWriteBlock(const char *Cmd) {
bool usepwd = false;
bool page1 = false;
bool gotdata = false;
bool testMode = false;
bool errors = false;
uint8_t cmdp = 0;
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
@ -975,6 +990,11 @@ int CmdT55xxWriteBlock(const char *Cmd) {
usepwd = true;
cmdp += 2;
break;
case 't':
case 'T':
testMode = true;
cmdp++;
break;
case '1':
page1 = true;
cmdp++;
@ -995,6 +1015,7 @@ int CmdT55xxWriteBlock(const char *Cmd) {
UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}};
UsbCommand resp;
c.d.asBytes[0] = (page1) ? 0x2 : 0;
c.d.asBytes[0] |= (testMode) ? 0x4 : 0;
char pwdStr[16] = {0};
snprintf(pwdStr, sizeof(pwdStr), "pwd: 0x%08X", password);
@ -1227,7 +1248,7 @@ int CmdT55xxInfo(const char *Cmd){
PrintAndLog("-------------------------------------------------------------");
PrintAndLog(" Safer key : %s", GetSaferStr(safer));
PrintAndLog(" reserved : %d", resv);
PrintAndLog(" Data bit rate : %s", GetBitRateStr(dbr));
PrintAndLog(" Data bit rate : %s", GetBitRateStr(dbr, extend));
PrintAndLog(" eXtended mode : %s", (extend) ? "Yes - Warning":"No");
PrintAndLog(" Modulation : %s", GetModulationStr(datamod));
PrintAndLog(" PSK clock frequency : %d", pskcf);
@ -1298,10 +1319,13 @@ int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ){
return 1;
}
char * GetBitRateStr(uint32_t id){
char * GetBitRateStr(uint32_t id, bool xmode) {
static char buf[25];
char *retStr = buf;
if (xmode) { //xmode bitrate calc is same as em4x05 calc
snprintf(retStr,sizeof(buf),"%d - RF/%d", id, EM4x05_GET_BITRATE(id));
} else {
switch (id){
case 0: snprintf(retStr,sizeof(buf),"%d - RF/8",id); break;
case 1: snprintf(retStr,sizeof(buf),"%d - RF/16",id); break;
@ -1313,6 +1337,7 @@ char * GetBitRateStr(uint32_t id){
case 7: snprintf(retStr,sizeof(buf),"%d - RF/128",id); break;
default: snprintf(retStr,sizeof(buf),"%d - (Unknown)",id); break;
}
}
return buf;
}
@ -1455,8 +1480,7 @@ int CmdT55xxWipe(const char *Cmd) {
bool IsCancelled(void) {
if (ukbhit()) {
int ch = getchar();
(void)ch;
int gc = getchar(); (void)gc;
printf("\naborted via keyboard!\n");
return true;
}
@ -1713,12 +1737,160 @@ int CmdT55xxRecoverPW(const char *Cmd) {
return 0;
}
// note length of data returned is different for different chips.
// some return all page 1 (64 bits) and others return just that block (32 bits)
// unfortunately the 64 bits makes this more likely to get a false positive...
bool tryDetectP1(bool getData) {
uint8_t preamble[] = {1,1,1,0,0,0,0,0,0,0,0,1,0,1,0,1};
size_t startIdx = 0;
uint8_t fc1 = 0, fc2 = 0, ans = 0;
int clk = 0, firstClockEdge = 0;
bool st = true;
if ( getData ) {
if ( !AquireData(T55x7_PAGE1, 1, false, 0) )
return false;
}
// try fsk clock detect. if successful it cannot be any other type of modulation... (in theory...)
ans = fskClocks(&fc1, &fc2, (uint8_t *)&clk, false, &firstClockEdge);
if (ans && ((fc1==10 && fc2==8) || (fc1==8 && fc2==5))) {
if ( FSKrawDemod("0 0", false) &&
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
return true;
}
if ( FSKrawDemod("0 1", false) &&
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
return true;
}
return false;
}
// try psk clock detect. if successful it cannot be any other type of modulation... (in theory...)
clk = GetPskClock("", false, false);
if (clk>0) {
// allow undo
// save_restoreGB(1);
// skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)
//CmdLtrim("160");
if ( PSKDemod("0 0 6", false) &&
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
//save_restoreGB(0);
return true;
}
if ( PSKDemod("0 1 6", false) &&
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
//save_restoreGB(0);
return true;
}
// PSK2 - needs a call to psk1TOpsk2.
if ( PSKDemod("0 0 6", false)) {
psk1TOpsk2(DemodBuffer, DemodBufferLen);
if (preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
//save_restoreGB(0);
return true;
}
} // inverse waves does not affect PSK2 demod
//undo trim samples
//save_restoreGB(0);
// no other modulation clocks = 2 or 4 so quit searching
if (fc1 != 8) return false;
}
// try ask clock detect. it could be another type even if successful.
clk = GetAskClock("", false, false);
if (clk>0) {
if ( ASKDemod_ext("0 0 1", false, false, 1, &st) &&
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
return true;
}
st = true;
if ( ASKDemod_ext("0 1 1", false, false, 1, &st) &&
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
return true;
}
if ( ASKbiphaseDemod("0 0 0 2", false) &&
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
return true;
}
if ( ASKbiphaseDemod("0 0 1 2", false) &&
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
return true;
}
}
// try NRZ clock detect. it could be another type even if successful.
clk = GetNrzClock("", false, false); //has the most false positives :(
if (clk>0) {
if ( NRZrawDemod("0 0 1", false) &&
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
return true;
}
if ( NRZrawDemod("0 1 1", false) &&
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
return true;
}
}
return false;
}
// does this need to be a callable command?
int CmdT55xxDetectPage1(const char *Cmd){
bool errors = false;
bool useGB = false;
bool usepwd = false;
uint32_t password = 0;
uint8_t cmdp = 0;
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch(param_getchar(Cmd, cmdp)) {
case 'h':
case 'H':
return usage_t55xx_detectP1();
case 'p':
case 'P':
password = param_get32ex(Cmd, cmdp+1, 0, 16);
usepwd = true;
cmdp += 2;
break;
case '1':
// use Graphbuffer data
useGB = true;
cmdp++;
break;
default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
if (errors) return usage_t55xx_detectP1();
if ( !useGB ) {
if ( !AquireData(T55x7_PAGE1, 1, usepwd, password) )
return false;
}
bool success = tryDetectP1(false);
if (success) PrintAndLog("T55xx chip found!");
return success;
}
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"bruteforce", CmdT55xxBruteForce,0, "<start password> <end password> [i <*.dic>] Simple bruteforce attack to find password"},
{"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},
{"detect", CmdT55xxDetect, 1, "[1] Try detecting the tag modulation from reading the configuration block."},
{"p1detect", CmdT55xxDetectPage1,1, "[1] Try detecting if this is a t55xx tag by reading page 1"},
{"dump", CmdT55xxDump, 0, "[password] [o] Dump T55xx card block 0-7. Optional [password], [override]"},
{"info", CmdT55xxInfo, 1, "[1] Show T55x7 configuration data (page 0/ blk 0)"},
{"read", CmdT55xxReadBlock, 0, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"},

View file

@ -124,10 +124,12 @@ typedef struct {
bool Q5;
bool ST;
} t55xx_conf_block_t;
t55xx_conf_block_t Get_t55xx_Config();
t55xx_conf_block_t Get_t55xx_Config(void);
void Set_t55xx_Config(t55xx_conf_block_t conf);
extern int CmdLFT55XX(const char *Cmd);
extern int CmdT55xxBruteForce(const char *Cmd);
extern int CmdT55xxSetConfig(const char *Cmd);
extern int CmdT55xxReadBlock(const char *Cmd);
extern int CmdT55xxWriteBlock(const char *Cmd);
@ -136,9 +138,8 @@ extern int CmdT55xxInfo(const char *Cmd);
extern int CmdT55xxDetect(const char *Cmd);
extern int CmdResetRead(const char *Cmd);
extern int CmdT55xxWipe(const char *Cmd);
extern int CmdT55xxBruteForce(const char *Cmd);
char * GetBitRateStr(uint32_t id);
char * GetBitRateStr(uint32_t id, bool xmode);
char * GetSaferStr(uint32_t id);
char * GetModulationStr( uint32_t id);
char * GetModelStrFromCID(uint32_t cid);
@ -151,6 +152,7 @@ int printConfiguration( t55xx_conf_block_t b);
bool DecodeT55xxBlock(void);
bool tryDetectModulation(void);
bool testKnownConfigBlock(uint32_t block0);
extern bool tryDetectP1(bool getData);
bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5);
int special(const char *Cmd);
int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password );

View file

@ -295,7 +295,7 @@ int CmdTIWrite(const char *Cmd)
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"demod", CmdTIDemod, 1, "Demodulate raw bits for TI-type LF tag"},
{"demod", CmdTIDemod, 1, "Demodulate raw bits for TI-type LF tag from the GraphBuffer"},
{"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}

View file

@ -7,22 +7,11 @@
// Low frequency Viking tag commands (AKA FDI Matalec Transit)
// ASK/Manchester, RF/32, 64 bits (complete)
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "proxmark3.h"
#include "ui.h"
#include "util.h"
#include "graph.h"
#include "cmdparser.h"
#include "cmddata.h"
#include "cmdmain.h"
#include "cmdlf.h"
#include "cmdlfviking.h"
#include "lfdemod.h"
static int CmdHelp(const char *Cmd);
int usage_lf_viking_clone(void){
int usage_lf_viking_clone(void) {
PrintAndLog("clone a Viking AM tag to a T55x7 tag.");
PrintAndLog("Usage: lf viking clone <Card ID - 8 hex digits> <Q5>");
PrintAndLog("Options :");
@ -54,15 +43,60 @@ uint64_t getVikingBits(uint32_t id) {
ret |= checksum;
return ret;
}
// by marshmellow
// find viking preamble 0xF200 in already demoded data
int detectViking(uint8_t *dest, size_t *size) {
//make sure buffer has data
if (*size < 64*2) return -2;
size_t startIdx = 0;
uint8_t preamble[] = {1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx))
return -4; //preamble not found
uint32_t checkCalc = bytebits_to_byte(dest+startIdx,8) ^
bytebits_to_byte(dest+startIdx+8,8) ^
bytebits_to_byte(dest+startIdx+16,8) ^
bytebits_to_byte(dest+startIdx+24,8) ^
bytebits_to_byte(dest+startIdx+32,8) ^
bytebits_to_byte(dest+startIdx+40,8) ^
bytebits_to_byte(dest+startIdx+48,8) ^
bytebits_to_byte(dest+startIdx+56,8);
if ( checkCalc != 0xA8 ) return -5;
if (*size != 64) return -6;
//return start position
return (int)startIdx;
}
//by marshmellow
//see ASKDemod for what args are accepted
int CmdVikingDemod(const char *Cmd) {
if (!ASKDemod(Cmd, false, false, 1)) {
if (g_debugMode) PrintAndLog("DEBUG: Error - Viking ASKDemod failed");
return 0;
}
size_t size = DemodBufferLen;
int ans = detectViking(DemodBuffer, &size);
if (ans < 0) {
if (g_debugMode) PrintAndLog("DEBUG: Error - Viking Demod %d %s", ans, (ans == -5)?"[chksum error]":"");
return 0;
}
//got a good demod
uint32_t raw1 = bytebits_to_byte(DemodBuffer+ans, 32);
uint32_t raw2 = bytebits_to_byte(DemodBuffer+ans+32, 32);
uint32_t cardid = bytebits_to_byte(DemodBuffer+ans+24, 32);
uint8_t checksum = bytebits_to_byte(DemodBuffer+ans+32+24, 8);
PrintAndLog("Viking Tag Found: Card ID %08X, Checksum: %02X", cardid, checksum);
PrintAndLog("Raw: %08X%08X", raw1,raw2);
setDemodBuf(DemodBuffer, 64, ans);
setClockGrid(g_DemodClock, g_DemodStartIdx + (ans*g_DemodClock));
return 1;
}
//by marshmellow
//see ASKDemod for what args are accepted
int CmdVikingRead(const char *Cmd) {
// read lf silently
CmdLFRead("s");
// get samples silently
getSamples("12000", true);
// demod and output viking ID
lf_read(true, 10000);
return CmdVikingDemod(Cmd);
}
@ -120,7 +154,8 @@ int CmdVikingSim(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"read", CmdVikingRead, 0, "Attempt to read and Extract tag data"},
{"demod", CmdVikingDemod, 1, "Demodulate a Viking tag from the GraphBuffer"},
{"read", CmdVikingRead, 0, "Attempt to read and Extract tag data from the antenna"},
{"clone", CmdVikingClone, 0, "<8 digit ID number> clone viking tag"},
{"sim", CmdVikingSim, 0, "<8 digit ID number> simulate viking tag"},
{NULL, NULL, 0, NULL}

View file

@ -8,9 +8,29 @@
//-----------------------------------------------------------------------------
#ifndef CMDLFVIKING_H__
#define CMDLFVIKING_H__
int CmdLFViking(const char *Cmd);
int CmdVikingRead(const char *Cmd);
int CmdVikingClone(const char *Cmd);
int CmdVikingSim(const char *Cmd);
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "proxmark3.h"
#include "ui.h"
#include "util.h"
#include "graph.h"
#include "cmdparser.h"
#include "cmddata.h"
#include "cmdmain.h"
#include "cmdlf.h"
#include "lfdemod.h"
extern int CmdLFViking(const char *Cmd);
extern int CmdVikingDemod(const char *Cmd);
extern int CmdVikingRead(const char *Cmd);
extern int CmdVikingClone(const char *Cmd);
extern int CmdVikingSim(const char *Cmd);
extern int detectViking(uint8_t *dest, size_t *size);
extern int usage_lf_viking_clone(void);
extern int usage_lf_viking_sim(void);
#endif

View file

@ -67,6 +67,18 @@ static uint8_t visa_parity( uint32_t id) {
return par;
}
// by iceman
// find Visa2000 preamble in already demoded data
int detectVisa2k(uint8_t *dest, size_t *size) {
if (*size < 96) return -1; //make sure buffer has data
size_t startIdx = 0;
uint8_t preamble[] = {0,1,0,1,0,1,1,0,0,1,0,0,1,0,0,1,0,1,0,1,0,0,1,1,0,0,1,1,0,0,1,0};
if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx))
return -2; //preamble not found
if (*size != 96) return -3; //wrong demoded size
//return start position
return (int)startIdx;
}
/**
*
@ -95,7 +107,7 @@ int CmdVisa2kDemod(const char *Cmd) {
return 0;
}
size_t size = DemodBufferLen;
int ans = Visa2kDemod_AM(DemodBuffer, &size);
int ans = detectVisa2k(DemodBuffer, &size);
if (ans < 0){
if (g_debugMode){
if (ans == -1)
@ -111,7 +123,7 @@ int CmdVisa2kDemod(const char *Cmd) {
return 0;
}
setDemodBuf(DemodBuffer, 96, ans);
setGrid_Clock(64);
setClockGrid(g_DemodClock, g_DemodStartIdx + (ans*g_DemodClock));
//got a good demod
uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32);
@ -143,8 +155,7 @@ int CmdVisa2kDemod(const char *Cmd) {
// 64*96*2=12288 samples just in case we just missed the first preamble we can still catch 2 of them
int CmdVisa2kRead(const char *Cmd) {
CmdLFRead("s");
getSamples("12500",true);
lf_read(true, 12500);
return CmdVisa2kDemod(Cmd);
}
@ -219,10 +230,10 @@ int CmdVisa2kSim(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
{"demod", CmdVisa2kDemod, 1, "Attempt to demod from GraphBuffer"},
{"read", CmdVisa2kRead, 0, "Attempt to read and extract tag data"},
{"clone", CmdVisa2kClone, 0, "clone Visa2000 tag"},
{"sim", CmdVisa2kSim, 0, "simulate Visa2000 tag"},
{"demod", CmdVisa2kDemod, 1, "Demodulate an VISA2000 tag from the GraphBuffer"},
{"read", CmdVisa2kRead, 0, "Attempt to read and extract tag data from the antenna"},
{"sim", CmdVisa2kSim, 0, "Visa2000 tag simulator"},
{"clone", CmdVisa2kClone, 0, "clone Visa2000 to t55x7"},
{NULL, NULL, 0, NULL}
};

View file

@ -22,16 +22,18 @@
#include "protocols.h" // for T55xx config register definitions
#include "lfdemod.h" // parityTest
extern int CmdLFVisa2k(const char *Cmd);
extern int CmdVisa2kDemod(const char *Cmd);
extern int CmdVisa2kRead(const char *Cmd);
extern int CmdVisa2kClone(const char *Cmd);
extern int CmdVisa2kSim(const char *Cmd);
extern int CmdVisa2kRead(const char *Cmd);
extern int CmdVisa2kDemod(const char *Cmd);
int getvisa2kBits(uint64_t fullcode, uint8_t *bits);
extern int detectVisa2k(uint8_t *dest, size_t *size);
int usage_lf_visa2k_clone(void);
int usage_lf_visa2k_sim(void);
int usage_lf_visa2k_read(void);
int usage_lf_visa2k_demod(void);
extern int usage_lf_visa2k_clone(void);
extern int usage_lf_visa2k_sim(void);
//extern int usage_lf_visa2k_read(void);
//extern int usage_lf_visa2k_demod(void);
#endif

View file

@ -12,7 +12,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "sleep.h"
#include "util_posix.h"
#include "cmdparser.h"
#include "proxmark3.h"
#include "data.h"

View file

@ -23,10 +23,20 @@ void GetFromBigBuf(uint8_t *dest, int bytes, int start_index) {
clearCommandBuffer();
SendCommand(&c);
}
void GetEMLFromBigBuf(uint8_t *dest, uint32_t bytes, uint32_t start_index) {
// this will download the EMULATOR memory part from device,
// inside the BigBuf EML zon.
bool GetEMLFromBigBuf(uint8_t *dest, uint32_t bytes, uint32_t start_index) {
sample_buf = dest;
UsbCommand c = {CMD_DOWNLOAD_EML_BIGBUF, {start_index, bytes, 0}};
clearCommandBuffer();
SendCommand(&c);
// the download will be done inside cmdmain.c function UsbCommandReceived(UsbCommand *UC)
// we are waiting for the ACK
if ( !WaitForResponseTimeout(CMD_ACK, NULL, 2500))
return false;
return true;
}

View file

@ -11,8 +11,12 @@
#ifndef DATA_H__
#define DATA_H__
#include <stdint.h>
#include <stdbool.h>
#include "util.h"
#define FILE_PATH_SIZE 1000
extern uint8_t* sample_buf;
void GetFromBigBuf(uint8_t *dest, int bytes, int start_index);
void GetEMLFromBigBuf(uint8_t *dest, uint32_t bytes, uint32_t start_index);
extern void GetFromBigBuf(uint8_t *dest, int bytes, int start_index);
extern bool GetEMLFromBigBuf(uint8_t *dest, uint32_t bytes, uint32_t start_index);
#endif

View file

@ -8,17 +8,7 @@
// ELF file flasher
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include "proxmark3.h"
#include "sleep.h"
#include "flash.h"
#include "elf.h"
#include "proxendian.h"
#include "usb_cmd.h"
#include "at91sam7s512.h"
void SendCommand(UsbCommand* txcmd);
void ReceiveCommand(UsbCommand* rxcmd);

View file

@ -10,7 +10,17 @@
#define __FLASH_H__
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include "proxmark3.h"
#include "elf.h"
#include "proxendian.h"
#include "usb_cmd.h"
#include "at91sam7s512.h"
#include "util_posix.h"
typedef struct {
void *data;

View file

@ -10,7 +10,7 @@
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include "sleep.h"
#include "util_posix.h"
#include "proxmark3.h"
#include "flash.h"
#include "uart.h"

View file

@ -38,7 +38,8 @@
#define COMPRESS_MAX_CHAIN 8192
#define FPGA_INTERLEAVE_SIZE 288 // (the FPGA's internal config frame size is 288 bits. Interleaving with 288 bytes should give best compression)
#define FPGA_CONFIG_SIZE 42336 // our current fpga_[lh]f.bit files are 42175 bytes. Rounded up to next multiple of FPGA_INTERLEAVE_SIZE
#define FPGA_CONFIG_SIZE 42336L // our current fpga_[lh]f.bit files are 42175 bytes. Rounded up to next multiple of FPGA_INTERLEAVE_SIZE
#define HARDNESTED_TABLE_SIZE (sizeof(uint32_t) * ((1L<<19)+1))
static void usage(void)
{
@ -46,6 +47,8 @@ static void usage(void)
fprintf(stderr, " Combine n FPGA bitstream files and compress them into one.\n\n");
fprintf(stderr, " fpga_compress -d <infile> <outfile>");
fprintf(stderr, " Decompress <infile>. Write result to <outfile>");
fprintf(stderr, " fpga_compress -t <infile> <outfile>");
fprintf(stderr, " Compress hardnested table <infile>. Write result to <outfile>");
}
@ -72,22 +75,29 @@ static bool all_feof(FILE *infile[], uint8_t num_infiles)
}
int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile)
int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile, bool hardnested_mode)
{
uint8_t *fpga_config;
uint32_t i;
int ret;
int c;
int32_t ret;
uint8_t c;
z_stream compressed_fpga_stream;
if (hardnested_mode) {
fpga_config = malloc(num_infiles * HARDNESTED_TABLE_SIZE);
} else {
fpga_config = malloc(num_infiles * FPGA_CONFIG_SIZE);
}
// read the input files. Interleave them into fpga_config[]
i = 0;
do {
if (i >= num_infiles * FPGA_CONFIG_SIZE) {
fprintf(stderr, "Input files too big (total > %d bytes). These are probably not PM3 FPGA config files.\n", num_infiles * FPGA_CONFIG_SIZE);
if (i >= num_infiles * (hardnested_mode?HARDNESTED_TABLE_SIZE:FPGA_CONFIG_SIZE)) {
if (hardnested_mode) {
fprintf(stderr, "Input file too big (> %lu bytes). This is probably not a hardnested bitflip state table.\n", HARDNESTED_TABLE_SIZE);
} else {
fprintf(stderr, "Input files too big (total > %lu bytes). These are probably not PM3 FPGA config files.\n", num_infiles*FPGA_CONFIG_SIZE);
}
for(uint16_t j = 0; j < num_infiles; j++) {
fclose(infile[j]);
}
@ -99,7 +109,7 @@ int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile)
for(uint16_t k = 0; k < FPGA_INTERLEAVE_SIZE; k++) {
c = fgetc(infile[j]);
if (!feof(infile[j])) {
fpga_config[i++] = c &0xFF;
fpga_config[i++] = c;
} else if (num_infiles > 1) {
fpga_config[i++] = '\0';
}
@ -123,7 +133,7 @@ int zlib_compress(FILE *infile[], uint8_t num_infiles, FILE *outfile)
COMPRESS_STRATEGY);
// estimate the size of the compressed output
unsigned int outsize_max = deflateBound(&compressed_fpga_stream, compressed_fpga_stream.avail_in);
uint32_t outsize_max = deflateBound(&compressed_fpga_stream, compressed_fpga_stream.avail_in);
uint8_t *outbuf = malloc(outsize_max);
compressed_fpga_stream.next_out = outbuf;
compressed_fpga_stream.avail_out = outsize_max;
@ -178,7 +188,7 @@ int zlib_decompress(FILE *infile, FILE *outfile)
#define DECOMPRESS_BUF_SIZE 1024
uint8_t outbuf[DECOMPRESS_BUF_SIZE];
uint8_t inbuf[DECOMPRESS_BUF_SIZE];
int ret;
int32_t ret;
z_stream compressed_fpga_stream;
@ -198,9 +208,9 @@ int zlib_decompress(FILE *infile, FILE *outfile)
compressed_fpga_stream.next_in = inbuf;
uint16_t i = 0;
do {
int c = fgetc(infile);
int32_t c = fgetc(infile);
if (!feof(infile)) {
inbuf[i++] = c;
inbuf[i++] = c & 0xFF;
compressed_fpga_stream.avail_in++;
} else {
break;
@ -272,11 +282,23 @@ int main(int argc, char **argv)
} else { // Compress
infiles = calloc(argc-2, sizeof(FILE*));
for (uint16_t i = 0; i < argc-2; i++) {
infiles[i] = fopen(argv[i+1], "rb");
bool hardnested_mode = false;
int num_input_files = 0;
if (!strcmp(argv[1], "-t")) { // hardnested table
if (argc != 4) {
usage();
return(EXIT_FAILURE);
}
hardnested_mode = true;
num_input_files = 1;
} else {
num_input_files = argc-2;
}
infiles = calloc(num_input_files, sizeof(FILE*));
for (uint16_t i = 0; i < num_input_files; i++) {
infiles[i] = fopen(argv[i+hardnested_mode?2:1], "rb");
if (infiles[i] == NULL) {
fprintf(stderr, "Error. Cannot open input file %s", argv[i+1]);
fprintf(stderr, "Error. Cannot open input file %s", argv[i+hardnested_mode?2:1]);
return(EXIT_FAILURE);
}
}
@ -285,6 +307,6 @@ int main(int argc, char **argv)
fprintf(stderr, "Error. Cannot open output file %s", argv[argc-1]);
return(EXIT_FAILURE);
}
return zlib_compress(infiles, argc-2, outfile);
return zlib_compress(infiles, num_input_files, outfile, hardnested_mode);
}
}

View file

@ -147,13 +147,18 @@ int GetAskClock(const char str[], bool printAns, bool verbose)
PrintAndLog("Failed to copy from graphbuffer");
return -1;
}
bool st = DetectST(grph, &size, &clock);
int start = 0;
if (st == false)
//, size_t *ststart, size_t *stend
size_t ststart = 0, stend = 0;
bool st = DetectST(grph, &size, &clock, &ststart, &stend);
int start = stend;
if (st == false) {
start = DetectASKClock(grph, size, &clock, 20);
if (printAns)
}
setClockGrid(clock, start);
// Only print this message if we're not looping something
if (printAns || g_debugMode) {
PrintAndLog("Auto-detected clock rate: %d, Best Starting Position: %d", clock, start);
}
return clock;
}
@ -167,11 +172,13 @@ uint8_t GetPskCarrier(const char str[], bool printAns, bool verbose)
PrintAndLog("Failed to copy from graphbuffer");
return 0;
}
carrier = countFC(grph, size, 0);
uint16_t fc = countFC(grph, size, 0);
carrier = fc & 0xFF;
if (carrier != 2 && carrier != 4 && carrier != 8) return 0;
if (( fc >> 8) == 10 && carrier == 8) return 0;
// Only print this message if we're not looping something
if (printAns)
PrintAndLog("Auto-detected PSK carrier rate: %d", carrier);
return carrier;
}
@ -190,12 +197,14 @@ int GetPskClock(const char str[], bool printAns, bool verbose)
if (verbose) PrintAndLog("Failed to copy from graphbuffer");
return -1;
}
int start = 0;
clock = DetectPSKClock_ext(grph, size, 0, &start);
if (printAns)
PrintAndLog("Auto-detected clock rate: %d, Best Starting Position: %d", clock, start);
size_t firstPhaseShiftLoc = 0;
uint8_t curPhase = 0, fc = 0;
clock = DetectPSKClock(grph, size, 0, &firstPhaseShiftLoc, &curPhase, &fc);
setClockGrid(clock, firstPhaseShiftLoc);
// Only print this message if we're not looping something
if (printAns){
PrintAndLog("Auto-detected clock rate: %d", clock);
}
return clock;
}
@ -216,12 +225,13 @@ uint8_t GetNrzClock(const char str[], bool printAns, bool verbose)
PrintAndLog("Failed to copy from graphbuffer");
return -1;
}
int start = 0;
clock = DetectNRZClock_ext(grph, size, 0, &start);
size_t clkStartIdx = 0;
clock = DetectNRZClock(grph, size, 0, &clkStartIdx);
setClockGrid(clock, clkStartIdx);
// Only print this message if we're not looping something
if (printAns)
PrintAndLog("Auto-detected clock rate: %d, Best Starting Position: %d", clock, start);
if (printAns){
PrintAndLog("Auto-detected clock rate: %d", clock);
}
return clock;
}
//by marshmellow
@ -236,10 +246,12 @@ uint8_t GetFskClock(const char str[], bool printAns, bool verbose)
uint8_t fc1=0, fc2=0, rf1=0;
uint8_t ans = fskClocks(&fc1, &fc2, &rf1, verbose);
int firstClockEdge = 0;
uint8_t ans = fskClocks(&fc1, &fc2, &rf1, verbose, &firstClockEdge);
if (ans == 0) return 0;
if ((fc1==10 && fc2==8) || (fc1==8 && fc2==5)){
if (printAns) PrintAndLog("Detected Field Clocks: FC/%d, FC/%d - Bit Clock: RF/%d", fc1, fc2, rf1);
setClockGrid(rf1, firstClockEdge);
return rf1;
}
if (verbose){
@ -248,7 +260,7 @@ uint8_t GetFskClock(const char str[], bool printAns, bool verbose)
}
return 0;
}
uint8_t fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, bool verbose)
uint8_t fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, bool verbose, int *firstClockEdge)
{
uint8_t BitStream[MAX_GRAPH_TRACE_LEN] = {0};
size_t size = getFromGraphBuf(BitStream);
@ -260,9 +272,8 @@ uint8_t fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, bool verbose)
}
*fc1 = (ans >> 8) & 0xFF;
*fc2 = ans & 0xFF;
int start = 0;
*rf1 = detectFSKClk_ext(BitStream, size, *fc1, *fc2, &start);
//int firstClockEdge = 0;
*rf1 = detectFSKClk(BitStream, size, *fc1, *fc2, firstClockEdge);
if (*rf1 == 0) {
if (verbose || g_debugMode) PrintAndLog("DEBUG: Clock detect error");
return 0;
@ -271,13 +282,13 @@ uint8_t fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, bool verbose)
}
// test samples are not just noise
bool graphJustNoise(int *BitStream, int size)
bool graphJustNoise(int *bits, int size)
{
//might not be high enough for noisy environments
#define THRESHOLD 15;
bool isNoise = true;
for(int i=0; i < size && isNoise; i++){
isNoise = BitStream[i] < THRESHOLD;
isNoise = bits[i] < THRESHOLD;
}
return isNoise;
}

View file

@ -21,7 +21,8 @@ int GetPskClock(const char str[], bool printAns, bool verbose);
uint8_t GetPskCarrier(const char str[], bool printAns, bool verbose);
uint8_t GetNrzClock(const char str[], bool printAns, bool verbose);
uint8_t GetFskClock(const char str[], bool printAns, bool verbose);
uint8_t fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, bool verbose);
uint8_t fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, bool verbose, int *firstClockEdge);
//uint8_t fskClocks(uint8_t *fc1, uint8_t *fc2, uint8_t *rf1, bool verbose);
bool graphJustNoise(int *BitStream, int size);
void setGraphBuf(uint8_t *buff, size_t size);
void save_restoreGB(uint8_t saveOpt);

View file

@ -87,9 +87,9 @@ static uint32_t bucket_count = 0;
static statelist_t* buckets[128];
static uint32_t keys_found = 0;
static uint64_t num_keys_tested;
static uint64_t found_bs_key = 0;
uint8_t trailing_zeros(uint8_t byte)
inline uint8_t trailing_zeros(uint8_t byte)
{
static const uint8_t trailing_zeros_LUT[256] = {
8, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
@ -163,10 +163,12 @@ static void* crack_states_thread(void* x){
#endif
const uint64_t key = crack_states_bitsliced(thread_arg->cuid, thread_arg->best_first_bytes, bucket, &keys_found, &num_keys_tested, nonces_to_bruteforce, bf_test_nonce_2nd_byte, thread_arg->nonces);
if(key != -1){
__sync_fetch_and_add(&keys_found, 1);
__atomic_fetch_add(&keys_found, 1, __ATOMIC_SEQ_CST);
__atomic_fetch_add(&found_bs_key, key, __ATOMIC_SEQ_CST);
char progress_text[80];
sprintf(progress_text, "Brute force phase completed. Key found: %012" PRIx64, key);
hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, 0.0, 0);
hardnested_print_progress(thread_arg->num_acquired_nonces, progress_text, 0.0, 0);
break;
} else if(keys_found){
break;
@ -282,21 +284,17 @@ static void write_benchfile(statelist_t *candidates) {
#endif
bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint32_t num_acquired_nonces, uint64_t maximum_states, noncelist_t *nonces, uint8_t *best_first_bytes)
bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint32_t num_acquired_nonces, uint64_t maximum_states, noncelist_t *nonces, uint8_t *best_first_bytes, uint64_t *foundkey)
{
#if defined (WRITE_BENCH_FILE)
write_benchfile(candidates);
#endif
bool silent = (bf_rate != NULL);
// if (!silent) {
// PrintAndLog("Brute force phase starting.");
// PrintAndLog("Using %u-bit bitslices", MAX_BITSLICES);
// }
keys_found = 0;
num_keys_tested = 0;
found_bs_key = 0;
bitslice_test_nonces(nonces_to_bruteforce, bf_test_nonce, bf_test_nonce_par);
// count number of states to go
@ -309,14 +307,6 @@ bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint
}
uint64_t start_time = msclock();
// enumerate states using all hardware threads, each thread handles one bucket
// if (!silent) {
// PrintAndLog("Starting %u cracking threads to search %u buckets containing a total of %" PRIu64" states...\n", NUM_BRUTE_FORCE_THREADS, bucket_count, maximum_states);
// printf("Common bits of first 4 2nd nonce bytes: %u %u %u\n",
// trailing_zeros(bf_test_nonce_2nd_byte[1] ^ bf_test_nonce_2nd_byte[0]),
// trailing_zeros(bf_test_nonce_2nd_byte[2] ^ bf_test_nonce_2nd_byte[1]),
// trailing_zeros(bf_test_nonce_2nd_byte[3] ^ bf_test_nonce_2nd_byte[2]));
// }
pthread_t threads[NUM_BRUTE_FORCE_THREADS];
struct args {
@ -345,18 +335,11 @@ bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint
uint64_t elapsed_time = msclock() - start_time;
// if (!silent) {
// printf("Brute force completed after testing %" PRIu64" (2^%1.1f) keys in %1.1f seconds at a rate of %1.0f (2^%1.1f) keys per second.\n",
// num_keys_tested,
// log(num_keys_tested) / log(2.0),
// (float)elapsed_time/1000.0,
// (float)num_keys_tested / ((float)elapsed_time / 1000.0),
// log((float)num_keys_tested / ((float)elapsed_time/1000.0)) / log(2.0));
// }
if (bf_rate != NULL) {
if (bf_rate != NULL)
*bf_rate = (float)num_keys_tested / ((float)elapsed_time / 1000.0);
}
if ( keys_found > 0)
*foundkey = found_bs_key;
return (keys_found != 0);
}
@ -433,8 +416,7 @@ static bool read_bench_data(statelist_t *test_candidates) {
}
float brute_force_benchmark()
{
float brute_force_benchmark() {
statelist_t test_candidates[NUM_BRUTE_FORCE_THREADS];
test_candidates[0].states[ODD_STATE] = malloc((TEST_BENCH_SIZE+1) * sizeof(uint32_t));
@ -461,7 +443,8 @@ float brute_force_benchmark()
uint64_t maximum_states = TEST_BENCH_SIZE*TEST_BENCH_SIZE*(uint64_t)NUM_BRUTE_FORCE_THREADS;
float bf_rate;
brute_force_bs(&bf_rate, test_candidates, 0, 0, maximum_states, NULL, 0);
uint64_t found_key = 0;
brute_force_bs(&bf_rate, test_candidates, 0, 0, maximum_states, NULL, 0, &found_key);
free(test_candidates[0].states[ODD_STATE]);
free(test_candidates[0].states[EVEN_STATE]);

View file

@ -28,7 +28,7 @@ typedef struct {
} statelist_t;
extern void prepare_bf_test_nonces(noncelist_t *nonces, uint8_t best_first_byte);
extern bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint32_t num_acquired_nonces, uint64_t maximum_states, noncelist_t *nonces, uint8_t *best_first_bytes);
extern bool brute_force_bs(float *bf_rate, statelist_t *candidates, uint32_t cuid, uint32_t num_acquired_nonces, uint64_t maximum_states, noncelist_t *nonces, uint8_t *best_first_bytes, uint64_t *found_key);
extern float brute_force_benchmark();
extern uint8_t trailing_zeros(uint8_t byte);
extern bool verify_key(uint32_t cuid, noncelist_t *nonces, uint8_t *best_first_bytes, uint32_t odd, uint32_t even);

View file

@ -11,7 +11,7 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "sleep.h"
#include "util_posix.h"
#include "proxusb.h"
#include "flash.h"
#include "elf.h"

View file

@ -9,7 +9,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sleep.h"
#include "util_posix.h"
#include "proxusb.h"
#include "flash.h"

View file

@ -8,20 +8,7 @@
//-----------------------------------------------------------------------------
// USB utilities
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <unistd.h>
#include <usb.h>
#include <strings.h>
#include <errno.h>
#include "sleep.h"
#include "proxusb.h"
#include "proxmark3.h"
#include "usb_cmd.h"
// It seems to be missing for mingw
#ifndef ETIMEDOUT

View file

@ -13,8 +13,16 @@
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <usb.h>
#include <strings.h>
#include <errno.h>
#include "proxmark3.h"
#include "usb_cmd.h"
#include "util_posix.h"
extern unsigned char return_on_error;
extern unsigned char error_occured;

View file

@ -24,7 +24,6 @@ Command = {
self.__index = self
o.cmd = o.cmd or _commands.CMD_UNKNOWN
--o.arg1 = "test"
o.arg1 = o.arg1 or 0
o.arg2 = o.arg2 or 0
o.arg3 = o.arg3 or 0
@ -47,13 +46,13 @@ Command = {
print(("WARNING; data was NOT a (hex-) string, but was %s"):format(type(data)))
end
o.data = data
return o
end,
parse = function (packet)
local count,cmd,arg1,arg2,arg3,data = bin.unpack('LLLLH512',packet)
local count, cmd, arg1, arg2, arg3, data = bin.unpack('LLLLH511', packet)
return Command:new{cmd = cmd, arg1 = arg1, arg2 = arg2, arg3 = arg3, data = data}
end,
end
}
function Command:__tostring()
local output = ("%s\r\nargs : (%s, %s, %s)\r\ndata:\r\n%s\r\n"):format(

View file

@ -92,14 +92,14 @@ local function getopt(args, ostr)
else
table.remove(args, 1);
if #args == 0 then -- an option requiring argument is the last one
place = 0;
if ostr:sub(1, 1) == ':' then return ':' end
place = 0;
if ostr:sub(1, 1) == ':' then return ':' end
return '?';
else arg = args[1] end
end
table.remove(args, 1);
place = 0;
end
end
table.remove(args, 1);
place = 0;
end
return optopt, arg;
end
end

View file

@ -109,7 +109,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key)
//flush queue
while (ukbhit()) {
int gc = getchar(); (void) gc;
int gc = getchar(); (void)gc;
}
// wait cycle
@ -117,7 +117,7 @@ int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key)
printf(".");
fflush(stdout);
if (ukbhit()) {
int gc = getchar(); (void) gc;
int gc = getchar(); (void)gc;
return -5;
break;
}

View file

@ -58,9 +58,17 @@ typedef struct {
typedef struct {
uint64_t Key[2];
int foundKey[2];
uint8_t foundKey[2];
} sector_t;
typedef struct {
uint8_t keyA[6];
uint8_t keyB[6];
//uint8_t foundKey[2];
} icesector_t;
extern char logHexFileName[FILE_PATH_SIZE];
extern int mfDarkside(uint8_t blockno, uint8_t key_type, uint64_t *key);

View file

@ -47,15 +47,15 @@ int nonce2key(uint32_t uid, uint32_t nt, uint32_t nr, uint64_t par_info, uint64_
}
PrintAndLog("+----+--------+---+-----+---------------+");
clock_t t1 = clock();
uint64_t t1 = msclock();
state = lfsr_common_prefix(nr, rr, ks3x, par);
lfsr_rollback_word(state, uid ^ nt, 0);
crypto1_get_lfsr(state, key);
crypto1_destroy(state);
t1 = clock() - t1;
if ( t1 > 0 ) PrintAndLog("Time in nonce2key: %.0f ticks", (float)t1);
t1 = msclock() - t1;
PrintAndLog("Time in nonce2key: %.0f ticks", (float)t1/1000.0);
return 0;
}
@ -182,7 +182,7 @@ out:
return retval;
}
// 32 bit recover key from 2 nonces
// 32 bit recover key from 2 nonces, with same nonce
bool tryMfk32(nonces_t data, uint64_t *outputkey, bool verbose) {
struct Crypto1State *s,*t;
uint64_t outkey = 0;
@ -193,7 +193,7 @@ bool tryMfk32(nonces_t data, uint64_t *outputkey, bool verbose) {
uint32_t ar0_enc = data.ar; // first encrypted reader response
uint32_t nr1_enc = data.nr2; // second encrypted reader challenge
uint32_t ar1_enc = data.ar2; // second encrypted reader response
bool isSuccess = FALSE;
bool isSuccess = false;
uint8_t counter = 0;
clock_t t1 = clock();
@ -248,7 +248,7 @@ bool tryMfk32_moebius(nonces_t data, uint64_t *outputkey, bool verbose) {
uint32_t nt1 = data.nonce2; // second tag challenge (nonce)
uint32_t nr1_enc = data.nr2; // second encrypted reader challenge
uint32_t ar1_enc = data.ar2; // second encrypted reader response
bool isSuccess = FALSE;
bool isSuccess = false;
int counter = 0;
clock_t t1 = clock();
@ -296,6 +296,7 @@ bool tryMfk32_moebius(nonces_t data, uint64_t *outputkey, bool verbose) {
return isSuccess;
}
// 64 bit recover key from a full authentication. (sniffed)
int tryMfk64_ex(uint8_t *data, uint64_t *outputkey){
uint32_t uid = LE32TOH(data);
uint32_t nt = LE32TOH(data+4); // tag challenge

View file

@ -97,10 +97,7 @@ void ProxGuiQT::MainLoop()
plotapp->exec();
}
ProxGuiQT::ProxGuiQT(int argc, char **argv) : plotapp(NULL), plotwidget(NULL),
argc(argc), argv(argv)
{
}
ProxGuiQT::ProxGuiQT(int argc, char **argv) : plotapp(NULL), plotwidget(NULL), argc(argc), argv(argv) {}
ProxGuiQT::~ProxGuiQT(void)
{

View file

@ -128,7 +128,7 @@ public:
void run();
private:
char *script_cmds_file = NULL;
bool usb_present;
bool usb_present = false;
};
#endif // PROXGUI_QT

View file

@ -68,7 +68,7 @@ byte_t* prx = rx;
// printf("██████╔╝██╔████╔██║ ████╔╝\n");
// printf("██╔═══╝ ██║╚██╔╝██║ ══█║ iceman@icesql.net\n");
// printf("██║ ██║ ╚═╝ ██║ ████╔╝ https://github.com/iceman1001/proxmark3\n");
// printf("╚═╝ ╚═╝ ╚═╝ ╚═══╝v1.7.2\n");
// printf("╚═╝ ╚═╝ ╚═╝ ╚═══╝v3.0.2n");
// }

View file

@ -47,6 +47,49 @@ static int l_SendCommand(lua_State *L){
SendCommand((UsbCommand* )data);
return 0; // no return values
}
/**
* @brief The following params expected:
* uint8_t *dest
* int bytes
* int start_index
* @param L
* @return
*/
static int l_GetFromBigBuf(lua_State *L){
int len = 0;
int startindex = 0;
//Check number of arguments
int n = lua_gettop(L);
if(n == 0) {
//signal error by returning Nil, errorstring
lua_pushnil(L);
lua_pushstring(L,"You need to supply number of len and startindex");
return 2; // two return values
}
if(n >= 2) {
len = luaL_checknumber(L, 1);
startindex = luaL_checknumber(L, 2);
}
uint8_t *data = malloc(len);
if ( data == NULL ) {
//signal error by returning Nil, errorstring
lua_pushnil(L);
lua_pushstring(L,"Allocating memory failed");
return 2; // two return values
}
GetFromBigBuf(data, len, startindex);
WaitForResponse(CMD_ACK, NULL);
//Push it as a string
lua_pushlstring(L,(const char *)data, len);
if (data)
free(data);
return 1;// return 1 to signal one return value
}
/**
* @brief The following params expected:
* uint32_t cmd
@ -369,6 +412,33 @@ static int l_crc64(lua_State *L)
return 1;
}
static int l_crc64_ecma182(lua_State *L)
{
//size_t size;
uint64_t crc = 0;
unsigned char outdata[8] = {0x00};
//const char *p_str = luaL_checklstring(L, 1, &size);
//init
//crc64_ecma182(NULL, 0, &crc);
crc = 0x338103260CC4;
// calc hash
//crc64_ecma182((uint8_t*) p_str, size, &crc);
outdata[0] = (uint8_t)(crc >> 56) & 0xff;
outdata[1] = (uint8_t)(crc >> 48) & 0xff;
outdata[2] = (uint8_t)(crc >> 40) & 0xff;
outdata[3] = (uint8_t)(crc >> 32) & 0xff;
outdata[4] = (uint8_t)(crc >> 24) & 0xff;
outdata[5] = (uint8_t)(crc >> 16) & 0xff;
outdata[6] = (uint8_t)(crc >> 8) & 0xff;
outdata[7] = crc & 0xff;
lua_pushlstring(L,(const char *)&outdata, sizeof(outdata));
return 1;
}
static int l_sha1(lua_State *L)
{
size_t size;
@ -496,8 +566,7 @@ static int l_hardnested(lua_State *L){
}
uint64_t foundkey = 0;
// int retval = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, haveTarget ? trgkey : NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey);
int retval = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, haveTarget ? trgkey : NULL, nonce_file_read, nonce_file_write, slow, tests);
int retval = mfnestedhard(blockNo, keyType, key, trgBlockNo, trgKeyType, haveTarget ? trgkey : NULL, nonce_file_read, nonce_file_write, slow, tests, &foundkey);
//Push the retval on the stack
lua_pushinteger(L,retval);
@ -511,6 +580,18 @@ static int l_hardnested(lua_State *L){
return 2; //Two return values
}
/**
* @brief l_validate_prng is a function to test is a nonce is using the weak PRNG
* @param L
* @return
*/
static int l_detect_prng(lua_State *L) {
bool valid = detect_classic_prng();
//Push the retval on the stack
lua_pushinteger(L, valid);
return 1;
}
/**
* @brief Sets the lua path to include "./lualibs/?.lua", in order for a script to be
* able to do "require('foobar')" if foobar.lua is within lualibs folder.
@ -537,6 +618,7 @@ int setLuaPath( lua_State* L, const char* path ) {
int set_pm3_libraries(lua_State *L) {
static const luaL_Reg libs[] = {
{"SendCommand", l_SendCommand},
{"GetFromBigBuf", l_GetFromBigBuf},
{"WaitForResponseTimeout", l_WaitForResponseTimeout},
{"mfDarkside", l_mfDarkside},
//{"PrintAndLog", l_PrintAndLog},
@ -553,10 +635,12 @@ int set_pm3_libraries(lua_State *L) {
{"crc8legic", l_crc8legic},
{"crc16", l_crc16},
{"crc64", l_crc64},
{"crc64_ecma182", l_crc64_ecma182},
{"sha1", l_sha1},
{"reveng_models", l_reveng_models},
{"reveng_runmodel", l_reveng_RunModel},
{"hardnested", l_hardnested},
{"detect_prng", l_detect_prng},
{NULL, NULL}
};

View file

@ -17,7 +17,7 @@ Examples :
local numBlocks = 64
local numSectors = 16
local DEBUG = TRUE
local DEBUG = true
---
-- A debug printout-function
function dbg(args)

View file

@ -317,8 +317,10 @@ end
---
-- put a string into a bytes-table
function str2bytes(s)
if (string.len(s)%2~=0) then
return print("stamp should be a even hexstring e.g.: deadbeef or 0badc0de")
end
local res={}
if (string.len(s)%2~=0) then return print("stamp should be a even hexstring e.g.: deadbeef or 0badc0de") end
for i=1, string.len(s), 2 do
table.insert(res, string.sub(s,i,(i+1)))
end
@ -384,7 +386,10 @@ end
---
-- put bytes into tag-table
function bytesToTag(bytes, tag)
if(istable(tag)) then
if ~istable(tag) then
return oops("tag is no table in: bytesToTag ("..type(tag)..")")
end
tag.MCD =bytes[1];
tag.MSN0=bytes[2];
tag.MSN1=bytes[3];
@ -425,8 +430,7 @@ function bytesToTag(bytes, tag)
end
print(accyan..#bytes.." bytes for Tag processed"..acoff)
return tag
end
return oops("tag is no table in: bytesToTag ("..type(tag)..")")
end
---
@ -452,7 +456,10 @@ end
---
-- read Tag-Table in bytes-table
function tagToBytes(tag)
if (istable(tag)) then
if ~istable(tag) then
return oops("tag is no table in tagToBytes ("..type(tag)..")")
end
local bytes = {}
local i, i2
-- main token-data
@ -497,8 +504,6 @@ function tagToBytes(tag)
end
return bytes
end
return oops("tag is no table in tagToBytes ("..type(tag)..")")
end
--- PM3 I/O ---
---
@ -573,12 +578,12 @@ function writeToTag(tag)
-- write pm3-buffer to Tag
for i=0, WriteBytes do
if ( i<5 or i>6) then
cmd = ('hf legic write 0x%02x 0x01'):format(i)
cmd = ('hf legic write o 0x%02x d 0x01'):format(i)
core.console(cmd)
--print(cmd)
elseif (i == 6) then
-- write DCF in reverse order (requires 'mosci-patch')
cmd = 'hf legic write 0x05 0x02'
cmd = 'hf legic write o 0x05 d 0x02'
print(acgreen..cmd..acoff)
core.console(cmd)
--print(cmd)
@ -597,12 +602,12 @@ function readFile(filename)
print(accyan)
local bytes = {}
local tag = {}
if (file_check(filename)==false) then
return oops("input file: "..filename.." not found")
else
if ~file_check(filename) then return oops("input file: "..filename.." not found") end
bytes = getInputBytes(filename)
if (bytes == false) then return oops('couldnt get input bytes')
else
if ~bytes then return oops('couldnt get input bytes') end
-- make plain bytes
bytes = xorBytes(bytes,bytes[5])
print("create virtual tag from ".. #bytes .. " bytes")
@ -611,8 +616,7 @@ function readFile(filename)
-- load plain bytes to tag-table
print(acoff)
tag=bytesToTag(bytes, tag)
end
end
return tag
end
@ -705,8 +709,11 @@ end
---
-- toggle higligh
function toggleHighlight(tbl)
if (tbl['highlight']) then tbl['highlight']=false
else tbl['highlight']=true end
if (tbl['highlight']) then
tbl['highlight'] = false
else
tbl['highlight'] = true
end
return tbl
end
@ -1300,8 +1307,11 @@ function dumpTable(tab, header, tstart, tend)
for i=tstart, tend do
res=res..tab[i].." "
end
if (string.len(header)==0) then return res
else return (header.." #"..(tend-tstart+1).."\n"..res) end
if (#header == 0) then
return res
else
return (header.." #"..(tend-tstart+1).."\n"..res)
end
end
---
@ -1346,7 +1356,9 @@ end
---
-- dump Legic-Cash data
function dumpLegicCash(tag, x)
if (istable(tag.SEG[x])) then
if ~istable(tag.SEG[x]) then return end
io.write("in Segment "..tag.SEG[x].index.." :\n")
print("--------------------------------\n\tLegic-Cash Values\n--------------------------------")
local limit, curr, balance, rid, tcv
@ -1366,12 +1378,13 @@ function dumpLegicCash(tag, x)
print("Transaction Counter:\t "..tcv)
print("Reader-ID:\t\t "..rid.."\n--------------------------------\n")
end
end
---
-- raw 3rd-party
function print3rdPartyCash1(tag, x)
if (istable(tag.SEG[x])) then
if ~istable(tag.SEG[x]) then return end
local uid=tag.MCD..tag.MSN0..tag.MSN1..tag.MSN2
print("\n\t\tStamp : "..dumpTable(tag.SEG[x].data, "", 0 , 2))
print("\t\tBlock 0: "..dumpTable(tag.SEG[x].data, "", 3 , 18))
@ -1408,7 +1421,6 @@ function print3rdPartyCash1(tag, x)
print()
print("\t\tBlock 8: "..dumpTable(tag.SEG[x].data, "", 90, 94))
end
end
--- Token related --
---
@ -1687,17 +1699,20 @@ end
---
-- edit Segment Data
function editSegmentData(data)
local lc=check4LegicCash(data)
io.write("\n")
if (istable(data)) then
if ~istable(data) then
print("no Segment-Data found")
end
local lc = check4LegicCash(data)
for i=0, #data-1 do
data[i]=input(accyan.."Data"..i..acoff..": ", data[i])
end
if (lc) then data=fixLegicCash(data) end
return data
else
print("no Segment-Data found")
if (lc) then
data = fixLegicCash(data)
end
return data
end
---
@ -2140,7 +2155,7 @@ function calcKghCrc(tag, segid)
end
---
-- check all segmnet-crc
-- check all segment-crc
function checkAllSegCrc(tag)
if (istable(tag.SEG[0])) then
for i=0, #tag.SEG do
@ -2266,8 +2281,11 @@ function modifyMode()
-- load file into mainTAG
["lf"] = function(x)
if (type(x)=='string' and file_check(x)) then filename=x
else filename=input("enter filename: ", "legic.temp") end
if (type(x)=='string' and file_check(x)) then
filename = x
else
filename = input("enter filename: ", "legic.temp")
end
inTAG=readFile(filename)
-- check for existing tagMap
if (file_check(filename..".map")) then
@ -2369,8 +2387,11 @@ function modifyMode()
---
-- dump single segment
["ds"] = function(x)
if (type(x)=="string" and string.len(x)>0) then sel=tonumber(x,10)
else sel=selectSegment(inTAG) end
if (type(x)=="string" and string.len(x)>0) then
sel = tonumber(x,10)
else
sel = selectSegment(inTAG)
end
if (sel) then print("\n"..(dumpSegment(inTAG, sel) or acred.."no Segments available") ..acoff.."\n") end
end,
---
@ -2382,7 +2403,9 @@ function modifyMode()
if(istable(inTAG.SEG[0])) then
inTAG=editSegment(inTAG, sel)
inTAG.SEG[sel]=regenSegmentHeader(inTAG.SEG[sel])
else print(acyellow.."no Segments in Tag"..acoff) end
else
print(acyellow.."no Segments in Tag"..acoff)
end
end
end,
---
@ -2437,10 +2460,16 @@ function modifyMode()
-- toggle kgh-crc-flag on a single segment
["tk"] = function(x)
if (istable(inTAG) and istable(inTAG.SEG[0])) then
if (type(x)=="string" and string.len(x)>0) then sel=tonumber(x,10)
else sel=selectSegment(inTAG) end
if(inTAG.SEG[sel].kgh) then inTAG.SEG[sel].kgh=false
else inTAG.SEG[sel].kgh=true end
if (type(x)=="string" and string.len(x)>0) then
sel = tonumber(x,10)
else
sel = selectSegment(inTAG)
end
if(inTAG.SEG[sel].kgh) then
inTAG.SEG[sel].kgh = false
else
inTAG.SEG[sel].kgh = true
end
end
end,
---
@ -2458,16 +2487,22 @@ function modifyMode()
-- print string for LegicCrc8-calculation about single segment
["xc"] = function(x)
if (istable(inTAG) and istable(inTAG.SEG[0])) then
if (type(x)=="string" and string.len(x)>0) then sel=tonumber(x,10)
else sel=selectSegment(inTAG) end
if (type(x)=="string" and string.len(x)>0) then
sel = tonumber(x,10)
else
sel = selectSegment(inTAG)
end
print("k "..kghCrcCredentials(inTAG, sel))
end
end,
---
-- fix legic-cash checksums
["flc"] = function(x)
if (type(x)=="string" and string.len(x)>0) then x=tonumber(x,10)
else x=selectSegment(inTAG) end
if (type(x)=="string" and string.len(x)>0) then
x = tonumber(x,10)
else
x = selectSegment(inTAG)
end
inTAG.SEG[x].data=fixLegicCash(inTAG.SEG[x].data)
end,
---
@ -2483,8 +2518,10 @@ function modifyMode()
if (type(x)=="string" and string.len(x)>0) then
x=tonumber(x,10)
print(string.format("User-Selected Index %02d", x))
else
-- or try to find match
else x=autoSelectSegment(inTAG, "legiccash") end
x = autoSelectSegment(inTAG, "legiccash")
end
-- dump it
dumpLegicCash(inTAG, x)
end,
@ -2496,8 +2533,10 @@ function modifyMode()
if (type(x)=="string" and string.len(x)>0) then
x=tonumber(x,10)
print(string.format("User-Selected Index %02d", x))
else
-- or try to find match
else x=autoSelectSegment(inTAG, "3rdparty") end
x = autoSelectSegment(inTAG, "3rdparty")
end
if (istable(inTAG) and istable(inTAG.SEG[x]) and inTAG.SEG[x].len == 100) then
uid=inTAG.MCD..inTAG.MSN0..inTAG.MSN1..inTAG.MSN2
if (check43rdPartyCash1(uid, inTAG.SEG[x].data)) then
@ -2513,8 +2552,10 @@ function modifyMode()
if (type(x)=="string" and string.len(x)>0) then
x=tonumber(x,10)
print(string.format("User-Selected Index %02d", x))
else
-- or try to find match
else x=autoSelectSegment(inTAG, "3rdparty") end
x = autoSelectSegment(inTAG, "3rdparty")
end
print3rdPartyCash1(inTAG, x)
end,
---
@ -2525,8 +2566,11 @@ function modifyMode()
if (type(x)=="string" and string.len(x)>0) then
x=tonumber(x,10)
print(string.format("User-Selected Index %02d", x))
else
-- or try to find match
else x=autoSelectSegment(inTAG, "3rdparty") end
x = autoSelectSegment(inTAG, "3rdparty")
end
if (istable(inTAG) and istable(inTAG.SEG[x]) and inTAG.SEG[x].len == 100) then
inTAG=edit3rdPartyCash1(inTAG, x)
dump3rdPartyCash1(inTAG, x)
@ -2535,8 +2579,11 @@ function modifyMode()
---
-- force fixing 3rd-party-checksums
["f3p"] = function(x)
if(type(x)=="string" and string.len(x)>=2) then x=tonumber(x, 10)
else x=selectSegment(inTAG) end
if(type(x)=="string" and string.len(x)>=2) then
x = tonumber(x, 10)
else
x = selectSegment(inTAG)
end
if (istable(inTAG.SEG[x])) then
local uid=inTAG.MCD..inTAG.MSN0..inTAG.MSN1..inTAG.MSN2
inTAG.SEG[x].data=fix3rdPartyCash1(uid, inTAG.SEG[x].data)
@ -2545,8 +2592,11 @@ function modifyMode()
---
-- get stamp from single segment
["gs"] = function(x)
if(type(x)=="string" and string.len(x)>=2) then x=tonumber(x, 10)
else x=selectSegment(inTAG) end
if(type(x)=="string" and string.len(x)>=2) then
x = tonumber(x, 10)
else
x = selectSegment(inTAG)
end
local stamp=getSegmentStamp(inTAG.SEG[x])
print("Stamp : "..stamp)
stamp=str2bytes(stamp)
@ -2592,7 +2642,9 @@ function modifyMode()
actions[string.lower(string.sub(ic,0,2))](string.sub(ic,4))
elseif (type(actions[string.lower(string.sub(ic,0,1))])=='function') then
actions[string.lower(string.sub(ic,0,1))](string.sub(ic,3))
else actions.h('') end
else
actions.h('')
end
until (string.sub(ic,0,1)=="q")
end
@ -2617,26 +2669,38 @@ function main(args)
-- dump virtual-Tag
if o == "d" then dfs=true end
-- interacive modifying
if o == "m" then interactive=true; modifyMode() end
if o == "m" then
interactive = true
modifyMode()
end
-- xor (e.g. for clone or plain file)
if o == "c" then cfs=true; crc=a end
if o == "c" then
cfs = true
crc = a
end
-- output file
if o == "o" then outfile=a; ofs=true end
if o == "o" then
outfile = a
ofs = true
end
end
-- file conversion (output to file)
if (ofs) then
if ~ofs then return end
-- dump infile / tag-read
if (dfs) then
print("-----------------------------------------")
print(dumpTag(inTAG))
end
bytes=tagToBytes(inTAG)
if (cfs) then
-- xor willl be done in function writeFile
-- with the value of byte[5]
bytes[5]=crc
end
-- write to outfile
if (bytes) then
writeFile(bytes, outfile)
@ -2650,10 +2714,9 @@ function main(args)
print(dumpTag(inTAG))
end
end
end
end
---
-- script start
main(args)
main(args)

View file

@ -8,9 +8,8 @@
// Snooper binary
//-----------------------------------------------------------------------------
#include "sleep.h"
#include "util_posix.h"
#include "ui.h"
//#include "proxusb.h"
#include "cmdmain.h"
#define HANDLE_ERROR if (error_occured) { \

View file

@ -30,16 +30,16 @@
#include <unistd.h>
int ukbhit(void) {
int cnt = 0;
int error;
static struct termios Otty, Ntty;
int cnt = 0;
int error;
static struct termios Otty, Ntty;
if ( tcgetattr(STDIN_FILENO, &Otty) == -1) return -1;
if ( tcgetattr(STDIN_FILENO, &Otty) == -1) return -1;
Ntty = Otty;
Ntty = Otty;
Ntty.c_iflag = 0x0000; // input mode
Ntty.c_oflag = 0x0000; // output mode
Ntty.c_iflag = 0x0000; // input mode
Ntty.c_oflag = 0x0000; // output mode
Ntty.c_lflag &= ~ICANON; // control mode = raw
Ntty.c_cc[VMIN] = 1; // return if at least 1 character is in the queue
Ntty.c_cc[VTIME] = 0; // no timeout. Wait forever
@ -47,9 +47,8 @@ int ukbhit(void) {
if (0 == (error = tcsetattr(STDIN_FILENO, TCSANOW, &Ntty))) { // set new attributes
error += ioctl(STDIN_FILENO, FIONREAD, &cnt); // get number of characters available
error += tcsetattr(STDIN_FILENO, TCSANOW, &Otty); // reset attributes
}
return ( error == 0 ? cnt : -1 );
}
return ( error == 0 ? cnt : -1 );
}
#else

Some files were not shown because too many files have changed in this diff Show more