mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-14 10:37:23 -07:00
monster merge...
all those changes marshmellow did.. and more...
This commit is contained in:
parent
208550823d
commit
f28da2da6e
107 changed files with 5087 additions and 3777 deletions
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
205
armsrc/lfops.c
205
armsrc/lfops.c
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include "sleep.h"
|
||||
#include "util_posix.h"
|
||||
#include "ui.h"
|
||||
//#include "proxusb.h"
|
||||
#include "cmdmain.h"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
1312
client/cmddata.c
1312
client/cmddata.c
File diff suppressed because it is too large
Load diff
|
@ -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);
|
||||
|
||||
|
|
|
@ -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]"},
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
433
client/cmdlf.c
433
client/cmdlf.c
|
@ -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)"},
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
408
client/cmdlfindala.c
Normal 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
39
client/cmdlfindala.h
Normal 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
|
161
client/cmdlfio.c
161
client/cmdlfio.c
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"},
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
|
|
@ -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
135
client/cmdlfparadox.c
Normal 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
16
client/cmdlfparadox.h
Normal 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
|
|
@ -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."},
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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]"},
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -128,7 +128,7 @@ public:
|
|||
void run();
|
||||
private:
|
||||
char *script_cmds_file = NULL;
|
||||
bool usb_present;
|
||||
bool usb_present = false;
|
||||
};
|
||||
|
||||
#endif // PROXGUI_QT
|
||||
|
|
|
@ -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");
|
||||
// }
|
||||
|
||||
|
||||
|
|
|
@ -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}
|
||||
};
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ Examples :
|
|||
|
||||
local numBlocks = 64
|
||||
local numSectors = 16
|
||||
local DEBUG = TRUE
|
||||
local DEBUG = true
|
||||
---
|
||||
-- A debug printout-function
|
||||
function dbg(args)
|
||||
|
|
|
@ -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)
|
|
@ -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) { \
|
||||
|
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue