mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-21 22:03:19 -07:00
Merge branch 'master' into originality_check
This commit is contained in:
commit
3a159d1df0
36 changed files with 2521 additions and 1928 deletions
|
@ -16,6 +16,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
- `hf 15 sim` now works as expected (piwi)
|
- `hf 15 sim` now works as expected (piwi)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
- Added `hf 15 csetuid` - set UID on ISO-15693 Magic tags (t0m4)
|
||||||
|
- Added `lf config s xxxx` option to allow skipping x samples before capture (marshmellow)
|
||||||
|
- Added `lf em 4x05protect` to support changing protection blocks on em4x05 chips (marshmellow)
|
||||||
- Support Standard Communication Mode in HITAG S
|
- Support Standard Communication Mode in HITAG S
|
||||||
- Added `hf emv scan` - commands for scan EMV card and dump data to json file (Merlok)
|
- Added `hf emv scan` - commands for scan EMV card and dump data to json file (Merlok)
|
||||||
- `hf mfp` group of commands (Merlok)
|
- `hf mfp` group of commands (Merlok)
|
||||||
|
@ -32,6 +35,10 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
- Added `hf mfp ndef` `hf mf ndef` parsing NDEF records (Merlok)
|
- Added `hf mfp ndef` `hf mf ndef` parsing NDEF records (Merlok)
|
||||||
- Added Mifare Mini, Mifare 2K and 4K support to `hf mf sim` (piwi)
|
- Added Mifare Mini, Mifare 2K and 4K support to `hf mf sim` (piwi)
|
||||||
- Added Legic detection to `hf search` (dnet)
|
- Added Legic detection to `hf search` (dnet)
|
||||||
|
- Added Home (Pos1) and End key bindings to the plot GUI (based on @mcd1992)
|
||||||
|
- Added downlink reference mode option r <mode> [ 0 - (or missing) default/fixed bit, 1 - long leading, 2 - leading 0 and 3 - 1 of 4 ] to `lf t55xx detect`, `lf t55xx read`, `lf t55xx write`, and `lf t55xx bruteforce`
|
||||||
|
- Added special option `r 4` to bruteforce, to try all downlink modes (0,1,2 and 3) for each password
|
||||||
|
|
||||||
|
|
||||||
## [v3.1.0][2018-10-10]
|
## [v3.1.0][2018-10-10]
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,10 @@ following locations:
|
||||||
* [RyscCorp](https://proxmark3.com/) (US)
|
* [RyscCorp](https://proxmark3.com/) (US)
|
||||||
* [Hackerwarehouse](https://hackerwarehouse.com/) (US)
|
* [Hackerwarehouse](https://hackerwarehouse.com/) (US)
|
||||||
* [Elechouse](http://www.elechouse.com/) (HK)
|
* [Elechouse](http://www.elechouse.com/) (HK)
|
||||||
* [Lab401](https://lab401.com/) (FR)
|
* [Lab401](https://lab401.com/) (HK)
|
||||||
* [RFxSecure](http://www.rfxsecure.com/) (SG)
|
* [RFxSecure](http://www.rfxsecure.com/) (SG)
|
||||||
* [IceSQL](http://proxmark3.tictail.com/) (SE)
|
* [Sneaktechnology](https://www.sneaktechnology.com/) (ASIA/OCEANIA)
|
||||||
|
|
||||||
|
|
||||||
Most of the ultra-low-volume contract assemblers could put
|
Most of the ultra-low-volume contract assemblers could put
|
||||||
something like this together with a reasonable yield. A run of around
|
something like this together with a reasonable yield. A run of around
|
||||||
|
|
|
@ -1088,6 +1088,9 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
case CMD_EM4X_WRITE_WORD:
|
case CMD_EM4X_WRITE_WORD:
|
||||||
EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2]);
|
EM4xWriteWord(c->arg[0], c->arg[1], c->arg[2]);
|
||||||
break;
|
break;
|
||||||
|
case CMD_EM4X_PROTECT:
|
||||||
|
EM4xProtect(c->arg[0], c->arg[1], c->arg[2]);
|
||||||
|
break;
|
||||||
case CMD_AWID_DEMOD_FSK: // Set realtime AWID demodulation
|
case CMD_AWID_DEMOD_FSK: // Set realtime AWID demodulation
|
||||||
CmdAWIDdemodFSK(c->arg[0], 0, 0, 1);
|
CmdAWIDdemodFSK(c->arg[0], 0, 0, 1);
|
||||||
break;
|
break;
|
||||||
|
@ -1155,9 +1158,14 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
case CMD_READER_ISO_15693:
|
case CMD_READER_ISO_15693:
|
||||||
ReaderIso15693(c->arg[0]);
|
ReaderIso15693(c->arg[0]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_SIMTAG_ISO_15693:
|
case CMD_SIMTAG_ISO_15693:
|
||||||
SimTagIso15693(c->arg[0], c->d.asBytes);
|
SimTagIso15693(c->arg[0], c->d.asBytes);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CMD_CSETUID_ISO_15693:
|
||||||
|
SetTag15693Uid(c->d.asBytes);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_LEGICRF
|
#ifdef WITH_LEGICRF
|
||||||
|
|
|
@ -89,6 +89,7 @@ void TurnReadLFOn();
|
||||||
//void T55xxReadTrace(void);
|
//void T55xxReadTrace(void);
|
||||||
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
|
void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode);
|
||||||
void EM4xWriteWord(uint32_t flag, uint32_t Data, uint32_t Pwd);
|
void EM4xWriteWord(uint32_t flag, uint32_t Data, uint32_t Pwd);
|
||||||
|
void EM4xProtect(uint32_t flag, uint32_t Data, uint32_t Pwd);
|
||||||
void Cotag(uint32_t arg0);
|
void Cotag(uint32_t arg0);
|
||||||
|
|
||||||
/// iso14443.h
|
/// iso14443.h
|
||||||
|
@ -142,8 +143,6 @@ void MifareDES_Auth1(uint8_t arg0,uint8_t arg1,uint8_t arg2, uint8_t *datain);
|
||||||
void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t * datain);
|
void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t * datain);
|
||||||
int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout);
|
int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout);
|
||||||
size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout);
|
size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout);
|
||||||
void OnSuccess();
|
|
||||||
void OnError(uint8_t reason);
|
|
||||||
|
|
||||||
|
|
||||||
/// iclass.h
|
/// iclass.h
|
||||||
|
|
|
@ -1963,7 +1963,10 @@ void iClass_Dump(uint8_t blockno, uint8_t numblks) {
|
||||||
uint8_t *dataout = BigBuf_malloc(255*8);
|
uint8_t *dataout = BigBuf_malloc(255*8);
|
||||||
if (dataout == NULL){
|
if (dataout == NULL){
|
||||||
Dbprintf("out of memory");
|
Dbprintf("out of memory");
|
||||||
OnError(1);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
LED_D_OFF();
|
||||||
|
cmd_send(CMD_ACK,0,1,0,0,0);
|
||||||
|
LED_A_OFF();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memset(dataout,0xFF,255*8);
|
memset(dataout,0xFF,255*8);
|
||||||
|
|
|
@ -1591,6 +1591,85 @@ void DirectTag15693Command(uint32_t datalen, uint32_t speed, uint32_t recv, uint
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Work with "magic Chinese" card.
|
||||||
|
//
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Set the UID to the tag (based on Iceman work).
|
||||||
|
void SetTag15693Uid(uint8_t *uid)
|
||||||
|
{
|
||||||
|
uint8_t cmd[4][9] = {0x00};
|
||||||
|
|
||||||
|
uint16_t crc;
|
||||||
|
|
||||||
|
int recvlen = 0;
|
||||||
|
uint8_t recvbuf[ISO15693_MAX_RESPONSE_LENGTH];
|
||||||
|
|
||||||
|
LED_A_ON();
|
||||||
|
|
||||||
|
// Command 1 : 02213E00000000
|
||||||
|
cmd[0][0] = 0x02;
|
||||||
|
cmd[0][1] = 0x21;
|
||||||
|
cmd[0][2] = 0x3e;
|
||||||
|
cmd[0][3] = 0x00;
|
||||||
|
cmd[0][4] = 0x00;
|
||||||
|
cmd[0][5] = 0x00;
|
||||||
|
cmd[0][6] = 0x00;
|
||||||
|
|
||||||
|
// Command 2 : 02213F69960000
|
||||||
|
cmd[1][0] = 0x02;
|
||||||
|
cmd[1][1] = 0x21;
|
||||||
|
cmd[1][2] = 0x3f;
|
||||||
|
cmd[1][3] = 0x69;
|
||||||
|
cmd[1][4] = 0x96;
|
||||||
|
cmd[1][5] = 0x00;
|
||||||
|
cmd[1][6] = 0x00;
|
||||||
|
|
||||||
|
// Command 3 : 022138u8u7u6u5 (where uX = uid byte X)
|
||||||
|
cmd[2][0] = 0x02;
|
||||||
|
cmd[2][1] = 0x21;
|
||||||
|
cmd[2][2] = 0x38;
|
||||||
|
cmd[2][3] = uid[7];
|
||||||
|
cmd[2][4] = uid[6];
|
||||||
|
cmd[2][5] = uid[5];
|
||||||
|
cmd[2][6] = uid[4];
|
||||||
|
|
||||||
|
// Command 4 : 022139u4u3u2u1 (where uX = uid byte X)
|
||||||
|
cmd[3][0] = 0x02;
|
||||||
|
cmd[3][1] = 0x21;
|
||||||
|
cmd[3][2] = 0x39;
|
||||||
|
cmd[3][3] = uid[3];
|
||||||
|
cmd[3][4] = uid[2];
|
||||||
|
cmd[3][5] = uid[1];
|
||||||
|
cmd[3][6] = uid[0];
|
||||||
|
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
// Add the CRC
|
||||||
|
crc = Crc(cmd[i], 7);
|
||||||
|
cmd[i][7] = crc & 0xff;
|
||||||
|
cmd[i][8] = crc >> 8;
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
Dbprintf("SEND:");
|
||||||
|
Dbhexdump(sizeof(cmd[i]), cmd[i], false);
|
||||||
|
}
|
||||||
|
|
||||||
|
recvlen = SendDataTag(cmd[i], sizeof(cmd[i]), true, 1, recvbuf, sizeof(recvbuf), 0);
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
Dbprintf("RECV:");
|
||||||
|
Dbhexdump(recvlen, recvbuf, false);
|
||||||
|
DbdecodeIso15693Answer(recvlen, recvbuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_send(CMD_ACK, recvlen>ISO15693_MAX_RESPONSE_LENGTH?ISO15693_MAX_RESPONSE_LENGTH:recvlen, 0, 0, recvbuf, ISO15693_MAX_RESPONSE_LENGTH);
|
||||||
|
}
|
||||||
|
|
||||||
|
LED_D_OFF();
|
||||||
|
|
||||||
|
LED_A_OFF();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ void ReaderIso15693(uint32_t parameter);
|
||||||
void SimTagIso15693(uint32_t parameter, uint8_t *uid);
|
void SimTagIso15693(uint32_t parameter, uint8_t *uid);
|
||||||
void BruteforceIso15693Afi(uint32_t speed);
|
void BruteforceIso15693Afi(uint32_t speed);
|
||||||
void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t data[]);
|
void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t data[]);
|
||||||
|
void SetTag15693Uid(uint8_t *uid);
|
||||||
void SetDebugIso15693(uint32_t flag);
|
void SetDebugIso15693(uint32_t flag);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
441
armsrc/lfops.c
441
armsrc/lfops.c
|
@ -1198,12 +1198,79 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
||||||
* and enlarge the gap ones.
|
* and enlarge the gap ones.
|
||||||
* Q5 tags seems to have issues when these values changes.
|
* Q5 tags seems to have issues when these values changes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Original Timings for reference
|
||||||
|
//note startgap must be sent after tag has been powered up for more than 3ms (per T5557 ds)
|
||||||
|
|
||||||
#define START_GAP 31*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (or 15fc)
|
#define START_GAP 31*8 // was 250 // SPEC: 1*8 to 50*8 - typ 15*8 (or 15fc)
|
||||||
#define WRITE_GAP 20*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (or 10fc)
|
#define WRITE_GAP 20*8 // was 160 // SPEC: 1*8 to 20*8 - typ 10*8 (or 10fc)
|
||||||
#define WRITE_0 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc)
|
#define WRITE_0 18*8 // was 144 // SPEC: 16*8 to 32*8 - typ 24*8 (or 24fc)
|
||||||
#define WRITE_1 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (or 56fc) 432 for T55x7; 448 for E5550
|
#define WRITE_1 50*8 // was 400 // SPEC: 48*8 to 64*8 - typ 56*8 (or 56fc) 432 for T55x7; 448 for E5550
|
||||||
#define READ_GAP 15*8
|
#define READ_GAP 15*8
|
||||||
|
|
||||||
|
*/
|
||||||
|
/* Q5 timing datasheet:
|
||||||
|
* Type | MIN | Typical | Max |
|
||||||
|
* Start_Gap | 10*8 | ? | 50*8 |
|
||||||
|
* Write_Gap Normal mode | 8*8 | 14*8 | 20*8 |
|
||||||
|
* Write_Gap Fast Mode | 8*8 | ? | 20*8 |
|
||||||
|
* Write_0 Normal mode | 16*8 | 24*8 | 32*8 |
|
||||||
|
* Write_1 Normal mode | 48*8 | 56*8 | 64*8 |
|
||||||
|
* Write_0 Fast Mode | 8*8 | 12*8 | 16*8 |
|
||||||
|
* Write_1 Fast Mode | 24*8 | 28*8 | 32*8 |
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* T5557 timing datasheet:
|
||||||
|
* Type | MIN | Typical | Max |
|
||||||
|
* Start_Gap | 10*8 | ? | 50*8 |
|
||||||
|
* Write_Gap Normal mode | 8*8 |50-150us | 30*8 |
|
||||||
|
* Write_Gap Fast Mode | 8*8 | ? | 20*8 |
|
||||||
|
* Write_0 Normal mode | 16*8 | 24*8 | 31*8 |
|
||||||
|
* Write_1 Normal mode | 48*8 | 54*8 | 63*8 |
|
||||||
|
* Write_0 Fast Mode | 8*8 | 12*8 | 15*8 |
|
||||||
|
* Write_1 Fast Mode | 24*8 | 28*8 | 31*8 |
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* T5577C timing datasheet for Fixed-Bit-Length protocol (defualt):
|
||||||
|
* Type | MIN | Typical | Max |
|
||||||
|
* Start_Gap | 8*8 | 15*8 | 50*8 |
|
||||||
|
* Write_Gap Normal mode | 8*8 | 10*8 | 20*8 |
|
||||||
|
* Write_Gap Fast Mode | 8*8 | 10*8 | 20*8 |
|
||||||
|
* Write_0 Normal mode | 16*8 | 24*8 | 32*8 |
|
||||||
|
* Write_1 Normal mode | 48*8 | 56*8 | 64*8 |
|
||||||
|
* Write_0 Fast Mode | 8*8 | 12*8 | 16*8 |
|
||||||
|
* Write_1 Fast Mode | 24*8 | 28*8 | 32*8 |
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Structure to hold Timing values. In future will be simplier to add user changable timings.
|
||||||
|
typedef struct {
|
||||||
|
uint16_t START_GAP;
|
||||||
|
uint16_t WRITE_GAP;
|
||||||
|
uint16_t WRITE_0;
|
||||||
|
uint16_t WRITE_1;
|
||||||
|
uint16_t WRITE_2;
|
||||||
|
uint16_t WRITE_3;
|
||||||
|
uint16_t READ_GAP;
|
||||||
|
} T55xx_Timing;
|
||||||
|
|
||||||
|
// Set Initial/Default Values. Note: *8 can occure when used. This should keep things simplier here.
|
||||||
|
T55xx_Timing T55xx_Timing_FixedBit = { 31 * 8 , 20 * 8 , 18 * 8 , 50 * 8 , 0 , 0 , 15 * 8 };
|
||||||
|
T55xx_Timing T55xx_Timing_LLR = { 31 * 8 , 20 * 8 , 18 * 8 , 50 * 8 , 0 , 0 , 15 * 8 };
|
||||||
|
T55xx_Timing T55xx_Timing_Leading0 = { 31 * 8 , 20 * 8 , 18 * 8 , 40 * 8 , 0 , 0 , 15 * 8 };
|
||||||
|
T55xx_Timing T55xx_Timing_1of4 = { 31 * 8 , 20 * 8 , 18 * 8 , 34 * 8 , 50 * 8 , 66 * 8 , 15 * 8 };
|
||||||
|
|
||||||
|
// Some defines for readability
|
||||||
|
#define T55xx_DLMode_Fixed 0 // Default Mode
|
||||||
|
#define T55xx_DLMode_LLR 1 // Long Leading Reference
|
||||||
|
#define T55xx_DLMode_Leading0 2 // Leading Zero
|
||||||
|
#define T55xx_DLMode_1of4 3 // 1 of 4
|
||||||
|
#define T55xx_LongLeadingReference 4 // Value to tell Write Bit to send long reference
|
||||||
|
// Macro for code readability
|
||||||
|
#define BitStream_Byte(X) ((X) >> 3)
|
||||||
|
#define BitStream_Bit(X) ((X) & 7)
|
||||||
|
|
||||||
|
|
||||||
void TurnReadLFOn(int delay) {
|
void TurnReadLFOn(int delay) {
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||||
// Give it a bit of time for the resonant antenna to settle.
|
// Give it a bit of time for the resonant antenna to settle.
|
||||||
|
@ -1211,36 +1278,179 @@ void TurnReadLFOn(int delay) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write one bit to card
|
// Write one bit to card
|
||||||
void T55xxWriteBit(int bit) {
|
void T55xxWriteBit(int bit, T55xx_Timing *Timings) {
|
||||||
if (!bit)
|
|
||||||
TurnReadLFOn(WRITE_0);
|
// If bit = 4 Send Long Leading Reference which is 138 + WRITE_0
|
||||||
else
|
// Dbprintf ("Bits : %d",bit);
|
||||||
TurnReadLFOn(WRITE_1);
|
switch (bit){
|
||||||
|
case 0 : TurnReadLFOn(Timings->WRITE_0); break; // Send bit 0/00
|
||||||
|
case 1 : TurnReadLFOn(Timings->WRITE_1); break; // Send bit 1/01
|
||||||
|
case 2 : TurnReadLFOn(Timings->WRITE_2); break; // Send bits 10
|
||||||
|
case 3 : TurnReadLFOn(Timings->WRITE_3); break; // Send bits 11
|
||||||
|
case 4 : TurnReadLFOn(Timings->WRITE_0 + (136 * 8)); break; // Send Long Leading Reference
|
||||||
|
}
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
WaitUS(WRITE_GAP);
|
WaitUS(Timings->WRITE_GAP);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send T5577 reset command then read stream (see if we can identify the start of the stream)
|
// Function to abstract an Arbitrary length byte array to store bit pattern.
|
||||||
void T55xxResetRead(void) {
|
// bit_array - Array to hold data/bit pattern
|
||||||
LED_A_ON();
|
// start_offset - bit location to start storing new bits.
|
||||||
//clear buffer now so it does not interfere with timing later
|
// data - upto 32 bits of data to store
|
||||||
BigBuf_Clear_keep_EM();
|
// num_bits - how many bits (low x bits of data) Max 32 bits at a time
|
||||||
|
// max_len - how many bytes can the bit_array hold (ensure no buffer overflow)
|
||||||
|
// returns "Next" bit offset / bits stored (for next store)
|
||||||
|
//int T55xx_SetBits (uint8_t *bit_array, int start_offset, uint32_t data , int num_bits, int max_len)
|
||||||
|
int T55xx_SetBits (uint8_t *BitStream, uint8_t start_offset, uint32_t data , uint8_t num_bits, uint8_t max_len)
|
||||||
|
{
|
||||||
|
int8_t offset;
|
||||||
|
int8_t NextOffset = start_offset;
|
||||||
|
|
||||||
|
// Check if data will fit.
|
||||||
|
if ((start_offset + num_bits) <= (max_len*8)) {
|
||||||
|
// Loop through the data and store
|
||||||
|
for (offset = (num_bits-1); offset >= 0; offset--) {
|
||||||
|
|
||||||
|
if ((data >> offset) & 1) BitStream[BitStream_Byte(NextOffset)] |= (1 << BitStream_Bit(NextOffset)); // Set the bit to 1
|
||||||
|
else BitStream[BitStream_Byte(NextOffset)] &= (0xff ^ (1 << BitStream_Bit(NextOffset))); // Set the bit to 0
|
||||||
|
|
||||||
|
NextOffset++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Note: This should never happen unless some code changes cause it.
|
||||||
|
// So short message for coders when testing.
|
||||||
|
Dbprintf ("T55 too many bits");
|
||||||
|
}
|
||||||
|
return NextOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send one downlink command to the card
|
||||||
|
void T55xx_SendCMD (uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
arg bits
|
||||||
|
xxxxxxx1 0x01 PwdMode
|
||||||
|
xxxxxx1x 0x02 Page
|
||||||
|
xxxxx1xx 0x04 testMode
|
||||||
|
xxx11xxx 0x18 downlink mode
|
||||||
|
xx1xxxxx 0x20 !reg_readmode
|
||||||
|
x1xxxxxx 0x40 called for a read, so no data packet
|
||||||
|
1xxxxxxx 0x80 reset
|
||||||
|
|
||||||
|
*/
|
||||||
|
bool PwdMode = ((arg & 0x01) == 0x01);
|
||||||
|
bool Page = (arg & 0x02);
|
||||||
|
bool testMode = ((arg & 0x04) == 0x04);
|
||||||
|
uint8_t downlink_mode = (arg >> 3) & 0x03;
|
||||||
|
bool reg_readmode = ((arg & 0x20) == 0x20);
|
||||||
|
bool read_cmd = ((arg & 0x40) == 0x40);
|
||||||
|
bool reset = (arg & 0x80);
|
||||||
|
|
||||||
|
uint8_t i = 0;
|
||||||
|
uint8_t BitStream[10]; // Max Downlink Command size ~74 bits, so 10 bytes (80 bits)
|
||||||
|
uint8_t BitStreamLen;
|
||||||
|
T55xx_Timing *Timing;
|
||||||
|
uint8_t SendBits;
|
||||||
|
|
||||||
|
// Assigning Downlink Timeing for write
|
||||||
|
switch (downlink_mode)
|
||||||
|
{
|
||||||
|
case T55xx_DLMode_Fixed : Timing = &T55xx_Timing_FixedBit; break;
|
||||||
|
case T55xx_DLMode_LLR : Timing = &T55xx_Timing_LLR; break;
|
||||||
|
case T55xx_DLMode_Leading0 : Timing = &T55xx_Timing_Leading0; break;
|
||||||
|
case T55xx_DLMode_1of4 : Timing = &T55xx_Timing_1of4; break;
|
||||||
|
default:
|
||||||
|
Timing = &T55xx_Timing_FixedBit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build Bit Stream to send.
|
||||||
|
memset (BitStream,0x00,sizeof(BitStream));
|
||||||
|
|
||||||
|
BitStreamLen = 0; // Ensure 0 bit index to start.
|
||||||
|
|
||||||
|
// Add Leading 0 and 1 of 4 reference bit
|
||||||
|
if ((downlink_mode == T55xx_DLMode_Leading0) || (downlink_mode == T55xx_DLMode_1of4))
|
||||||
|
BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 1,sizeof(BitStream));
|
||||||
|
|
||||||
|
// Add extra reference 0 for 1 of 4
|
||||||
|
if (downlink_mode == T55xx_DLMode_1of4)
|
||||||
|
BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 1,sizeof(BitStream));
|
||||||
|
|
||||||
|
// Add Opcode
|
||||||
|
if (reset) {
|
||||||
|
// Reset : r*) 00
|
||||||
|
BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 2,sizeof(BitStream));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (testMode) Dbprintf("TestMODE");
|
||||||
|
BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen,testMode ? 0 : 1 , 1,sizeof(BitStream));
|
||||||
|
BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen,testMode ? 1 : Page , 1,sizeof(BitStream));
|
||||||
|
|
||||||
|
if (PwdMode) {
|
||||||
|
// Leading 0 and 1 of 4 00 fixed bits if passsword used
|
||||||
|
if ((downlink_mode == T55xx_DLMode_Leading0) || (downlink_mode == T55xx_DLMode_1of4)) {
|
||||||
|
BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 2,sizeof(BitStream));
|
||||||
|
}
|
||||||
|
BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, Pwd, 32,sizeof(BitStream));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add Lock bit 0
|
||||||
|
if (!reg_readmode) BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, 0, 1,sizeof(BitStream));
|
||||||
|
|
||||||
|
// Add Data if a write command
|
||||||
|
if (!read_cmd) BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, Data, 32,sizeof(BitStream));
|
||||||
|
|
||||||
|
// Add Address
|
||||||
|
if (!reg_readmode) BitStreamLen = T55xx_SetBits (BitStream, BitStreamLen, Block, 3,sizeof(BitStream));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send Bits to T55xx
|
||||||
// Set up FPGA, 125kHz
|
// Set up FPGA, 125kHz
|
||||||
LFSetupFPGAForADC(95, true);
|
LFSetupFPGAForADC(95, true);
|
||||||
StartTicks();
|
StartTicks();
|
||||||
// make sure tag is fully powered up...
|
// make sure tag is fully powered up...
|
||||||
WaitMS(5);
|
WaitMS(5);
|
||||||
|
|
||||||
// Trigger T55x7 in mode.
|
// Trigger T55x7 in mode.
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
WaitUS(START_GAP);
|
WaitUS(Timing->START_GAP);
|
||||||
|
|
||||||
// reset tag - op code 00
|
// If long leading 0 send long reference pulse
|
||||||
T55xxWriteBit(0);
|
if (downlink_mode == T55xx_DLMode_LLR)
|
||||||
T55xxWriteBit(0);
|
T55xxWriteBit (T55xx_LongLeadingReference,Timing); // Send Long Leading Start Reference
|
||||||
|
|
||||||
TurnReadLFOn(READ_GAP);
|
if ((downlink_mode == T55xx_DLMode_1of4) && (BitStreamLen > 0)) { // 1 of 4 need to send 2 bits at a time
|
||||||
|
for ( i = 0; i < BitStreamLen-1; i+=2 ) {
|
||||||
|
SendBits = (BitStream[BitStream_Byte(i )] >> (BitStream_Bit(i )) & 1) << 1; // Bit i
|
||||||
|
SendBits += (BitStream[BitStream_Byte(i+1)] >> (BitStream_Bit(i+1)) & 1); // Bit i+1;
|
||||||
|
T55xxWriteBit (SendBits & 3,Timing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (i = 0; i < BitStreamLen; i++) {
|
||||||
|
SendBits = (BitStream[BitStream_Byte(i)] >> BitStream_Bit(i));
|
||||||
|
T55xxWriteBit (SendBits & 1,Timing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send T5577 reset command then read stream (see if we can identify the start of the stream)
|
||||||
|
void T55xxResetRead(void) {
|
||||||
|
LED_A_ON();
|
||||||
|
|
||||||
|
// send r* 00
|
||||||
|
uint8_t arg = 0x80; // SendCMD will add correct reference mode based on flags (when added).
|
||||||
|
|
||||||
|
// Add in downlink_mode when ready
|
||||||
|
// arg |= 0x00; // dlmode << 3 (00 default - 08 leading 0 - 10 Fixed - 18 1 of 4 )
|
||||||
|
|
||||||
|
//clear buffer now so it does not interfere with timing later
|
||||||
|
BigBuf_Clear_keep_EM();
|
||||||
|
|
||||||
|
T55xx_SendCMD (0, 0, 0, arg); //, true);
|
||||||
|
|
||||||
|
TurnReadLFOn(T55xx_Timing_FixedBit.READ_GAP);
|
||||||
|
|
||||||
// Acquisition
|
// Acquisition
|
||||||
DoPartialAcquisition(0, true, BigBuf_max_traceLen(), 0);
|
DoPartialAcquisition(0, true, BigBuf_max_traceLen(), 0);
|
||||||
|
@ -1252,42 +1462,23 @@ void T55xxResetRead(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write one card block in page 0, no lock
|
// Write one card block in page 0, no lock
|
||||||
void T55xxWriteBlockExt(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) {
|
void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) {
|
||||||
LED_A_ON();
|
/*
|
||||||
bool PwdMode = arg & 0x1;
|
arg bits
|
||||||
uint8_t Page = (arg & 0x2)>>1;
|
xxxxxxx1 0x01 PwdMode
|
||||||
bool testMode = arg & 0x4;
|
xxxxxx1x 0x02 Page
|
||||||
uint32_t i = 0;
|
xxxxx1xx 0x04 testMode
|
||||||
|
xxx11xxx 0x18 downlink mode
|
||||||
// Set up FPGA, 125kHz
|
xx1xxxxx 0x20 !reg_readmode
|
||||||
LFSetupFPGAForADC(95, true);
|
x1xxxxxx 0x40 called for a read, so no data packet
|
||||||
StartTicks();
|
1xxxxxxx 0x80 reset
|
||||||
// make sure tag is fully powered up...
|
*/
|
||||||
WaitMS(5);
|
|
||||||
// Trigger T55x7 in mode.
|
bool testMode = ((arg & 0x04) == 0x04);
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
arg &= (0xff ^ 0x40); // Called for a write, so ensure it is clear/0
|
||||||
WaitUS(START_GAP);
|
|
||||||
|
LED_A_ON ();
|
||||||
if (testMode) Dbprintf("TestMODE");
|
T55xx_SendCMD (Data, Block, Pwd, arg) ;//, false);
|
||||||
// Std Opcode 10
|
|
||||||
T55xxWriteBit(testMode ? 0 : 1);
|
|
||||||
T55xxWriteBit(testMode ? 1 : Page); //Page 0
|
|
||||||
|
|
||||||
if (PwdMode) {
|
|
||||||
// Send Pwd
|
|
||||||
for (i = 0x80000000; i != 0; i >>= 1)
|
|
||||||
T55xxWriteBit(Pwd & i);
|
|
||||||
}
|
|
||||||
// Send Lock bit
|
|
||||||
T55xxWriteBit(0);
|
|
||||||
|
|
||||||
// Send Data
|
|
||||||
for (i = 0x80000000; i != 0; i >>= 1)
|
|
||||||
T55xxWriteBit(Data & i);
|
|
||||||
|
|
||||||
// Send Block number
|
|
||||||
for (i = 0x04; i != 0; i >>= 1)
|
|
||||||
T55xxWriteBit(Block & i);
|
|
||||||
|
|
||||||
// Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550,
|
// Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550,
|
||||||
// so wait a little more)
|
// so wait a little more)
|
||||||
|
@ -1316,57 +1507,43 @@ void T55xxWriteBlockExt(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg
|
||||||
|
|
||||||
//DoPartialAcquisition(20, true, 12000);
|
//DoPartialAcquisition(20, true, 12000);
|
||||||
}
|
}
|
||||||
|
|
||||||
// turn field off
|
// turn field off
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LED_A_OFF();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write one card block in page 0, no lock
|
|
||||||
void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) {
|
|
||||||
T55xxWriteBlockExt(Data, Block, Pwd, arg);
|
|
||||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||||
|
|
||||||
|
LED_A_OFF ();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read one card block in page [page]
|
// Read one card block in page [page]
|
||||||
void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
|
void T55xxReadBlock (uint16_t arg0, uint8_t Block, uint32_t Pwd) {//, struct T55xx_Timing *Timing) {
|
||||||
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
bool PwdMode = arg0 & 0x1;
|
|
||||||
uint8_t Page = (arg0 & 0x2) >> 1;
|
/*
|
||||||
uint32_t i = 0;
|
arg bits
|
||||||
bool RegReadMode = (Block == 0xFF);//regular read mode
|
xxxxxxx1 0x01 PwdMode
|
||||||
|
xxxxxx1x 0x02 Page
|
||||||
|
xxxxx1xx 0x04 testMode
|
||||||
|
xxx11xxx 0x18 downlink mode
|
||||||
|
xx1xxxxx 0x20 !reg_readmode
|
||||||
|
x1xxxxxx 0x40 called for a read, so no data packet
|
||||||
|
1xxxxxxx 0x80 reset
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Set Read Flag to ensure SendCMD does not add "data" to the packet
|
||||||
|
arg0 |= 0x40;
|
||||||
|
|
||||||
|
// RegRead Mode true of block 0xff
|
||||||
|
if (Block == 0xff) arg0 |= 0x20;
|
||||||
|
|
||||||
|
//make sure block is at max 7
|
||||||
|
Block &= 0x7;
|
||||||
|
|
||||||
//clear buffer now so it does not interfere with timing later
|
//clear buffer now so it does not interfere with timing later
|
||||||
BigBuf_Clear_ext(false);
|
BigBuf_Clear_ext(false);
|
||||||
|
|
||||||
//make sure block is at max 7
|
T55xx_SendCMD (0, Block, Pwd, arg0); //, true);
|
||||||
Block &= 0x7;
|
|
||||||
|
|
||||||
// Set up FPGA, 125kHz to power up the tag
|
|
||||||
LFSetupFPGAForADC(95, true);
|
|
||||||
StartTicks();
|
|
||||||
// make sure tag is fully powered up...
|
|
||||||
WaitMS(5);
|
|
||||||
// Trigger T55x7 Direct Access Mode with start gap
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
|
||||||
WaitUS(START_GAP);
|
|
||||||
|
|
||||||
// Opcode 1[page]
|
|
||||||
T55xxWriteBit(1);
|
|
||||||
T55xxWriteBit(Page); //Page 0
|
|
||||||
|
|
||||||
if (PwdMode){
|
|
||||||
// Send Pwd
|
|
||||||
for (i = 0x80000000; i != 0; i >>= 1)
|
|
||||||
T55xxWriteBit(Pwd & i);
|
|
||||||
}
|
|
||||||
// Send a zero bit separation
|
|
||||||
T55xxWriteBit(0);
|
|
||||||
|
|
||||||
// Send Block number (if direct access mode)
|
|
||||||
if (!RegReadMode)
|
|
||||||
for (i = 0x04; i != 0; i >>= 1)
|
|
||||||
T55xxWriteBit(Block & i);
|
|
||||||
|
|
||||||
// Turn field on to read the response
|
// Turn field on to read the response
|
||||||
// 137*8 seems to get to the start of data pretty well...
|
// 137*8 seems to get to the start of data pretty well...
|
||||||
|
@ -1380,30 +1557,31 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
|
||||||
// Turn the field off
|
// Turn the field off
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
||||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||||
|
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
void T55xxWakeUp(uint32_t Pwd){
|
void T55xxWakeUp(uint32_t Pwd){
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
uint32_t i = 0;
|
/*
|
||||||
|
arg bits
|
||||||
// Set up FPGA, 125kHz
|
xxxxxxx1 0x01 PwdMode
|
||||||
LFSetupFPGAForADC(95, true);
|
xxxxxx1x 0x02 Page
|
||||||
StartTicks();
|
xxxxx1xx 0x04 testMode
|
||||||
// make sure tag is fully powered up...
|
xxx11xxx 0x18 downlink mode
|
||||||
WaitMS(5);
|
xx1xxxxx 0x20 !reg_readmode
|
||||||
|
x1xxxxxx 0x40 called for a read, so no data packet
|
||||||
// Trigger T55x7 Direct Access Mode
|
1xxxxxxx 0x80 reset
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
*/
|
||||||
WaitUS(START_GAP);
|
|
||||||
|
|
||||||
// Opcode 10
|
|
||||||
T55xxWriteBit(1);
|
|
||||||
T55xxWriteBit(0); //Page 0
|
|
||||||
|
|
||||||
// Send Pwd
|
// r* 10 (00) <pwd> r* for llr , L0 and 1/4 - (00) for L0 and 1/4 - All handled in SendCMD
|
||||||
for (i = 0x80000000; i != 0; i >>= 1)
|
// So, default Opcode 10 and pwd.
|
||||||
T55xxWriteBit(Pwd & i);
|
uint8_t arg = 0x01 | 0x40 | 0x20; //Password Read Call no data | reg_read no block
|
||||||
|
|
||||||
|
// Add in downlink_mode when ready
|
||||||
|
// arg |= 0x00; // dlmode << 3 (00 default - 08 leading 0 - 10 Fixed - 18 1 of 4 )
|
||||||
|
|
||||||
|
T55xx_SendCMD (0, 0, Pwd, arg); //, true);
|
||||||
|
|
||||||
// Turn and leave field on to let the begin repeating transmission
|
// Turn and leave field on to let the begin repeating transmission
|
||||||
TurnReadLFOn(20*1000);
|
TurnReadLFOn(20*1000);
|
||||||
|
@ -1414,7 +1592,8 @@ void T55xxWakeUp(uint32_t Pwd){
|
||||||
void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) {
|
void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) {
|
||||||
// write last block first and config block last (if included)
|
// write last block first and config block last (if included)
|
||||||
for (uint8_t i = numblocks+startblock; i > startblock; i--) {
|
for (uint8_t i = numblocks+startblock; i > startblock; i--) {
|
||||||
T55xxWriteBlockExt(blockdata[i-1],i-1,0,0);
|
T55xxWriteBlock(blockdata[i-1],i-1,0,0);//,false); //,&T55xx_Timing_FixedBit);
|
||||||
|
//T55xx_SendCMD (blockdata[i-1],i-1,0,0);//,false); //,&T55xx_Timing_FixedBit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1614,6 +1793,7 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) {
|
||||||
#define FWD_CMD_WRITE 0xA
|
#define FWD_CMD_WRITE 0xA
|
||||||
#define FWD_CMD_READ 0x9
|
#define FWD_CMD_READ 0x9
|
||||||
#define FWD_CMD_DISABLE 0x5
|
#define FWD_CMD_DISABLE 0x5
|
||||||
|
#define FWD_CMD_PROTECT 0x3
|
||||||
|
|
||||||
uint8_t forwardLink_data[64]; //array of forwarded bits
|
uint8_t forwardLink_data[64]; //array of forwarded bits
|
||||||
uint8_t * forward_ptr; //ptr for forward message preparation
|
uint8_t * forward_ptr; //ptr for forward message preparation
|
||||||
|
@ -1727,7 +1907,7 @@ void SendForward(uint8_t fwd_bit_count) {
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
|
||||||
WaitUS(18*8); //18 cycles on (8us each)
|
WaitUS(18*8); //18 cycles on (8us each)
|
||||||
|
|
||||||
// now start writting
|
// now start writting - each bit should be 32*8 total length
|
||||||
while(fwd_bit_sz-- > 0) { //prepare next bit modulation
|
while(fwd_bit_sz-- > 0) { //prepare next bit modulation
|
||||||
if(((*fwd_write_ptr++) & 1) == 1)
|
if(((*fwd_write_ptr++) & 1) == 1)
|
||||||
WaitUS(32*8); //32 cycles at 125Khz (8us each)
|
WaitUS(32*8); //32 cycles at 125Khz (8us each)
|
||||||
|
@ -1736,7 +1916,7 @@ void SendForward(uint8_t fwd_bit_count) {
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
||||||
WaitUS(23*8); //23 cycles off (8us each)
|
WaitUS(23*8); //23 cycles off (8us each)
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);//field on
|
||||||
WaitUS(18*8); //18 cycles on (8us each)
|
WaitUS((32-23)*8); //remaining cycles on (8us each)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1783,7 +1963,7 @@ void EM4xReadWord(uint8_t Address, uint32_t Pwd, uint8_t PwdMode) {
|
||||||
|
|
||||||
void EM4xWriteWord(uint32_t flag, uint32_t Data, uint32_t Pwd) {
|
void EM4xWriteWord(uint32_t flag, uint32_t Data, uint32_t Pwd) {
|
||||||
|
|
||||||
bool PwdMode = (flag & 0xF);
|
bool PwdMode = (flag & 0x1);
|
||||||
uint8_t Address = (flag >> 8) & 0xFF;
|
uint8_t Address = (flag >> 8) & 0xFF;
|
||||||
uint8_t fwd_bit_count;
|
uint8_t fwd_bit_count;
|
||||||
|
|
||||||
|
@ -1813,6 +1993,39 @@ void EM4xWriteWord(uint32_t flag, uint32_t Data, uint32_t Pwd) {
|
||||||
LED_A_OFF();
|
LED_A_OFF();
|
||||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EM4xProtect(uint32_t flag, uint32_t Data, uint32_t Pwd) {
|
||||||
|
|
||||||
|
bool PwdMode = (flag & 0x1);
|
||||||
|
uint8_t fwd_bit_count;
|
||||||
|
|
||||||
|
//clear buffer now so it does not interfere with timing later
|
||||||
|
BigBuf_Clear_ext(false);
|
||||||
|
|
||||||
|
LED_A_ON();
|
||||||
|
StartTicks();
|
||||||
|
//If password mode do login
|
||||||
|
if (PwdMode) EM4xLogin(Pwd);
|
||||||
|
|
||||||
|
forward_ptr = forwardLink_data;
|
||||||
|
fwd_bit_count = Prepare_Cmd( FWD_CMD_PROTECT );
|
||||||
|
|
||||||
|
//unsure if this needs the full packet config...
|
||||||
|
fwd_bit_count += Prepare_Data( Data&0xFFFF, Data>>16 );
|
||||||
|
|
||||||
|
SendForward(fwd_bit_count);
|
||||||
|
|
||||||
|
//Wait for write to complete
|
||||||
|
//SpinDelay(10);
|
||||||
|
|
||||||
|
WaitUS(6500);
|
||||||
|
//Capture response if one exists
|
||||||
|
DoPartialAcquisition(20, true, 6000, 1000);
|
||||||
|
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
||||||
|
LED_A_OFF();
|
||||||
|
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
Reading a COTAG.
|
Reading a COTAG.
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include "usb_cdc.h" // for usb_poll_validate_length
|
#include "usb_cdc.h" // for usb_poll_validate_length
|
||||||
#include "fpgaloader.h"
|
#include "fpgaloader.h"
|
||||||
|
|
||||||
sample_config config = { 1, 8, 1, 95, 0 } ;
|
sample_config config = { 1, 8, 1, 95, 0, 0 } ;
|
||||||
|
|
||||||
void printConfig()
|
void printConfig()
|
||||||
{
|
{
|
||||||
|
@ -24,6 +24,7 @@ void printConfig()
|
||||||
Dbprintf(" [d] decimation: %d ", config.decimation);
|
Dbprintf(" [d] decimation: %d ", config.decimation);
|
||||||
Dbprintf(" [a] averaging: %d ", config.averaging);
|
Dbprintf(" [a] averaging: %d ", config.averaging);
|
||||||
Dbprintf(" [t] trigger threshold: %d ", config.trigger_threshold);
|
Dbprintf(" [t] trigger threshold: %d ", config.trigger_threshold);
|
||||||
|
Dbprintf(" [s] samples to skip: %d ", config.samples_to_skip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ void printConfig()
|
||||||
* Other functions may read samples and ignore the sampling config,
|
* Other functions may read samples and ignore the sampling config,
|
||||||
* such as functions to read the UID from a prox tag or similar.
|
* such as functions to read the UID from a prox tag or similar.
|
||||||
*
|
*
|
||||||
* Values set to '0' implies no change (except for averaging)
|
* Values set to '0' implies no change (except for averaging, threshold, samples_to_skip)
|
||||||
* @brief setSamplingConfig
|
* @brief setSamplingConfig
|
||||||
* @param sc
|
* @param sc
|
||||||
*/
|
*/
|
||||||
|
@ -44,6 +45,7 @@ void setSamplingConfig(sample_config *sc)
|
||||||
if(sc->bits_per_sample!= 0) config.bits_per_sample= sc->bits_per_sample;
|
if(sc->bits_per_sample!= 0) config.bits_per_sample= sc->bits_per_sample;
|
||||||
if(sc->decimation!= 0) config.decimation= sc->decimation;
|
if(sc->decimation!= 0) config.decimation= sc->decimation;
|
||||||
if(sc->trigger_threshold != -1) config.trigger_threshold= sc->trigger_threshold;
|
if(sc->trigger_threshold != -1) config.trigger_threshold= sc->trigger_threshold;
|
||||||
|
if(sc->samples_to_skip != -1) config.samples_to_skip = sc->samples_to_skip;
|
||||||
|
|
||||||
config.averaging= sc->averaging;
|
config.averaging= sc->averaging;
|
||||||
if(config.bits_per_sample > 8) config.bits_per_sample = 8;
|
if(config.bits_per_sample > 8) config.bits_per_sample = 8;
|
||||||
|
@ -119,7 +121,7 @@ void LFSetupFPGAForADC(int divisor, bool lf_field)
|
||||||
* @param silent - is true, now outputs are made. If false, dbprints the status
|
* @param silent - is true, now outputs are made. If false, dbprints the status
|
||||||
* @return the number of bits occupied by the samples.
|
* @return the number of bits occupied by the samples.
|
||||||
*/
|
*/
|
||||||
uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold, bool silent, int bufsize, int cancel_after)
|
uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold, bool silent, int bufsize, int cancel_after, int samples_to_skip)
|
||||||
{
|
{
|
||||||
//.
|
//.
|
||||||
uint8_t *dest = BigBuf_get_addr();
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
|
@ -141,6 +143,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
|
||||||
uint32_t sample_total_numbers =0 ;
|
uint32_t sample_total_numbers =0 ;
|
||||||
uint32_t sample_total_saved =0 ;
|
uint32_t sample_total_saved =0 ;
|
||||||
uint32_t cancel_counter = 0;
|
uint32_t cancel_counter = 0;
|
||||||
|
uint32_t samples_skipped = 0;
|
||||||
|
|
||||||
while(!BUTTON_PRESS() && !usb_poll_validate_length() ) {
|
while(!BUTTON_PRESS() && !usb_poll_validate_length() ) {
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
@ -160,6 +163,10 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
trigger_threshold = 0;
|
trigger_threshold = 0;
|
||||||
|
if (samples_to_skip > samples_skipped) {
|
||||||
|
samples_skipped++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
sample_total_numbers++;
|
sample_total_numbers++;
|
||||||
|
|
||||||
if(averaging)
|
if(averaging)
|
||||||
|
@ -218,7 +225,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
|
||||||
*/
|
*/
|
||||||
uint32_t DoAcquisition_default(int trigger_threshold, bool silent)
|
uint32_t DoAcquisition_default(int trigger_threshold, bool silent)
|
||||||
{
|
{
|
||||||
return DoAcquisition(1,8,0,trigger_threshold,silent,0,0);
|
return DoAcquisition(1,8,0,trigger_threshold,silent,0,0,0);
|
||||||
}
|
}
|
||||||
uint32_t DoAcquisition_config(bool silent, int sample_size)
|
uint32_t DoAcquisition_config(bool silent, int sample_size)
|
||||||
{
|
{
|
||||||
|
@ -228,11 +235,12 @@ uint32_t DoAcquisition_config(bool silent, int sample_size)
|
||||||
,config.trigger_threshold
|
,config.trigger_threshold
|
||||||
,silent
|
,silent
|
||||||
,sample_size
|
,sample_size
|
||||||
,0);
|
,0
|
||||||
|
,config.samples_to_skip);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t DoPartialAcquisition(int trigger_threshold, bool silent, int sample_size, int cancel_after) {
|
uint32_t DoPartialAcquisition(int trigger_threshold, bool silent, int sample_size, int cancel_after) {
|
||||||
return DoAcquisition(1,8,0,trigger_threshold,silent,sample_size,cancel_after);
|
return DoAcquisition(1,8,0,trigger_threshold,silent,sample_size,cancel_after,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ReadLF(bool activeField, bool silent, int sample_size)
|
uint32_t ReadLF(bool activeField, bool silent, int sample_size)
|
||||||
|
|
|
@ -23,24 +23,42 @@
|
||||||
#define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation)
|
#define HARDNESTED_AUTHENTICATION_TIMEOUT 848 // card times out 1ms after wrong authentication (according to NXP documentation)
|
||||||
#define HARDNESTED_PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication
|
#define HARDNESTED_PRE_AUTHENTICATION_LEADTIME 400 // some (non standard) cards need a pause after select before they are ready for first authentication
|
||||||
|
|
||||||
|
/*
|
||||||
// the block number for the ISO14443-4 PCB
|
// the block number for the ISO14443-4 PCB
|
||||||
static uint8_t pcb_blocknum = 0;
|
static uint8_t pcb_blocknum = 0;
|
||||||
// Deselect card by sending a s-block. the crc is precalced for speed
|
// Deselect card by sending a s-block. the crc is precalced for speed
|
||||||
static uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4};
|
static uint8_t deselect_cmd[] = {0xc2,0xe0,0xb4};
|
||||||
|
|
||||||
|
static void OnSuccess(){
|
||||||
|
pcb_blocknum = 0;
|
||||||
|
ReaderTransmit(deselect_cmd, 3 , NULL);
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
LEDsoff();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void OnError(uint8_t reason){
|
||||||
|
// pcb_blocknum = 0;
|
||||||
|
// ReaderTransmit(deselect_cmd, 3 , NULL);
|
||||||
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
LED_D_OFF();
|
||||||
|
cmd_send(CMD_ACK,0,reason,0,0,0);
|
||||||
|
LED_A_OFF();
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Select, Authenticate, Read a MIFARE tag.
|
// Select, Authenticate, Read a MIFARE tag.
|
||||||
// read block
|
// read block
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
{
|
{
|
||||||
// params
|
LED_A_ON();
|
||||||
|
|
||||||
uint8_t blockNo = arg0;
|
uint8_t blockNo = arg0;
|
||||||
uint8_t keyType = arg1;
|
uint8_t keyType = arg1;
|
||||||
uint64_t ui64Key = 0;
|
uint64_t ui64Key = 0;
|
||||||
ui64Key = bytes_to_num(datain, 6);
|
ui64Key = bytes_to_num(datain, 6);
|
||||||
|
|
||||||
// variables
|
|
||||||
byte_t isOK = 0;
|
byte_t isOK = 0;
|
||||||
byte_t dataoutbuf[16];
|
byte_t dataoutbuf[16];
|
||||||
uint8_t uid[10];
|
uint8_t uid[10];
|
||||||
|
@ -53,10 +71,6 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
|
|
||||||
clear_trace();
|
clear_trace();
|
||||||
|
|
||||||
LED_A_ON();
|
|
||||||
LED_B_OFF();
|
|
||||||
LED_C_OFF();
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
|
if(!iso14443a_select_card(uid, NULL, &cuid, true, 0, true)) {
|
||||||
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= 1) Dbprintf("Can't select card");
|
||||||
|
@ -97,21 +111,18 @@ void MifareReadBlock(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
|
|
||||||
void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
|
void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
|
||||||
|
|
||||||
|
LED_A_ON();
|
||||||
bool turnOffField = (arg0 == 1);
|
bool turnOffField = (arg0 == 1);
|
||||||
|
|
||||||
LED_A_ON(); LED_B_OFF(); LED_C_OFF();
|
|
||||||
|
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
clear_trace();
|
if (!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {
|
||||||
|
|
||||||
if(!iso14443a_select_card(NULL, NULL, NULL, true, 0, true)) {
|
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card");
|
||||||
OnError(0);
|
OnError(0);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
if(!mifare_ultra_auth(keybytes)){
|
if (!mifare_ultra_auth(keybytes)){
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Authentication failed");
|
||||||
OnError(1);
|
OnError(1);
|
||||||
return;
|
return;
|
||||||
|
@ -119,9 +130,11 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
|
||||||
|
|
||||||
if (turnOffField) {
|
if (turnOffField) {
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LEDsoff();
|
LED_D_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_send(CMD_ACK,1,0,0,0,0);
|
cmd_send(CMD_ACK,1,0,0,0,0);
|
||||||
|
LED_A_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arg0 = BlockNo,
|
// Arg0 = BlockNo,
|
||||||
|
@ -129,17 +142,15 @@ void MifareUC_Auth(uint8_t arg0, uint8_t *keybytes){
|
||||||
// datain = PWD bytes,
|
// datain = PWD bytes,
|
||||||
void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
|
void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
|
||||||
{
|
{
|
||||||
|
LED_A_ON();
|
||||||
|
|
||||||
uint8_t blockNo = arg0;
|
uint8_t blockNo = arg0;
|
||||||
byte_t dataout[16] = {0x00};
|
byte_t dataout[16] = {0x00};
|
||||||
bool useKey = (arg1 == 1); //UL_C
|
bool useKey = (arg1 == 1); //UL_C
|
||||||
bool usePwd = (arg1 == 2); //UL_EV1/NTAG
|
bool usePwd = (arg1 == 2); //UL_EV1/NTAG
|
||||||
|
|
||||||
LEDsoff();
|
|
||||||
LED_A_ON();
|
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
clear_trace();
|
|
||||||
|
|
||||||
int len = iso14443a_select_card(NULL, NULL, NULL, true, 0, true);
|
int len = iso14443a_select_card(NULL, NULL, NULL, true, 0, true);
|
||||||
if(!len) {
|
if(!len) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len);
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Can't select card (RC:%02X)",len);
|
||||||
|
@ -148,7 +159,7 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UL-C authentication
|
// UL-C authentication
|
||||||
if ( useKey ) {
|
if (useKey) {
|
||||||
uint8_t key[16] = {0x00};
|
uint8_t key[16] = {0x00};
|
||||||
memcpy(key, datain, sizeof(key) );
|
memcpy(key, datain, sizeof(key) );
|
||||||
|
|
||||||
|
@ -159,7 +170,7 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UL-EV1 / NTAG authentication
|
// UL-EV1 / NTAG authentication
|
||||||
if ( usePwd ) {
|
if (usePwd) {
|
||||||
uint8_t pwd[4] = {0x00};
|
uint8_t pwd[4] = {0x00};
|
||||||
memcpy(pwd, datain, 4);
|
memcpy(pwd, datain, 4);
|
||||||
uint8_t pack[4] = {0,0,0,0};
|
uint8_t pack[4] = {0,0,0,0};
|
||||||
|
@ -169,13 +180,13 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( mifare_ultra_readblock(blockNo, dataout) ) {
|
if (mifare_ultra_readblock(blockNo, dataout)) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Read block error");
|
||||||
OnError(2);
|
OnError(2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( mifare_ultra_halt() ) {
|
if (mifare_ultra_halt()) {
|
||||||
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");
|
if (MF_DBGLEVEL >= MF_DBG_ERROR) Dbprintf("Halt error");
|
||||||
OnError(3);
|
OnError(3);
|
||||||
return;
|
return;
|
||||||
|
@ -183,7 +194,8 @@ void MifareUReadBlock(uint8_t arg0, uint8_t arg1, uint8_t *datain)
|
||||||
|
|
||||||
cmd_send(CMD_ACK,1,0,0,dataout,16);
|
cmd_send(CMD_ACK,1,0,0,dataout,16);
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LEDsoff();
|
LED_D_OFF();
|
||||||
|
LED_A_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -259,13 +271,11 @@ void MifareReadSector(uint8_t arg0, uint8_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
// datain = KEY bytes
|
// datain = KEY bytes
|
||||||
void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
|
void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
{
|
{
|
||||||
LEDsoff();
|
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
iso14443a_setup(FPGA_HF_ISO14443A_READER_LISTEN);
|
||||||
|
|
||||||
// free eventually allocated BigBuf memory
|
// free eventually allocated BigBuf memory
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
clear_trace();
|
|
||||||
|
|
||||||
// params
|
// params
|
||||||
uint8_t blockNo = arg0;
|
uint8_t blockNo = arg0;
|
||||||
|
@ -288,7 +298,7 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UL-C authentication
|
// UL-C authentication
|
||||||
if ( useKey ) {
|
if (useKey) {
|
||||||
uint8_t key[16] = {0x00};
|
uint8_t key[16] = {0x00};
|
||||||
memcpy(key, datain, sizeof(key) );
|
memcpy(key, datain, sizeof(key) );
|
||||||
|
|
||||||
|
@ -340,14 +350,14 @@ void MifareUReadCard(uint8_t arg0, uint16_t arg1, uint8_t arg2, uint8_t *datain)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (MF_DBGLEVEL >= MF_DBG_EXTENDED) Dbprintf("Blocks read %d", countblocks);
|
if (MF_DBGLEVEL >= MF_DBG_DEBUG) Dbprintf("Blocks read %d", countblocks);
|
||||||
|
|
||||||
countblocks *= 4;
|
cmd_send(CMD_ACK, 1, countblocks*4, BigBuf_max_traceLen(), 0, 0);
|
||||||
|
|
||||||
cmd_send(CMD_ACK, 1, countblocks, BigBuf_max_traceLen(), 0, 0);
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
LEDsoff();
|
LED_D_OFF();
|
||||||
BigBuf_free();
|
BigBuf_free();
|
||||||
|
LED_A_OFF();
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -1598,17 +1608,3 @@ void Mifare_DES_Auth2(uint32_t arg0, uint8_t *datain){
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnSuccess(){
|
|
||||||
pcb_blocknum = 0;
|
|
||||||
ReaderTransmit(deselect_cmd, 3 , NULL);
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
|
||||||
LEDsoff();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnError(uint8_t reason){
|
|
||||||
pcb_blocknum = 0;
|
|
||||||
ReaderTransmit(deselect_cmd, 3 , NULL);
|
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
|
||||||
cmd_send(CMD_ACK,0,reason,0,0,0);
|
|
||||||
LEDsoff();
|
|
||||||
}
|
|
||||||
|
|
|
@ -542,8 +542,8 @@ void MifareSim(uint8_t flags, uint8_t exitAfterNReads, uint8_t cardsize, uint8_t
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(receivedCmd_dec[0] == ISO14443A_CMD_READBLOCK
|
if(receivedCmd_dec[0] == MIFARE_CMD_READBLOCK
|
||||||
|| receivedCmd_dec[0] == ISO14443A_CMD_WRITEBLOCK
|
|| receivedCmd_dec[0] == MIFARE_CMD_WRITEBLOCK
|
||||||
|| receivedCmd_dec[0] == MIFARE_CMD_INC
|
|| receivedCmd_dec[0] == MIFARE_CMD_INC
|
||||||
|| receivedCmd_dec[0] == MIFARE_CMD_DEC
|
|| receivedCmd_dec[0] == MIFARE_CMD_DEC
|
||||||
|| receivedCmd_dec[0] == MIFARE_CMD_RESTORE
|
|| receivedCmd_dec[0] == MIFARE_CMD_RESTORE
|
||||||
|
@ -562,7 +562,7 @@ void MifareSim(uint8_t flags, uint8_t exitAfterNReads, uint8_t cardsize, uint8_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (receivedCmd_dec[0] == ISO14443A_CMD_READBLOCK) {
|
if (receivedCmd_dec[0] == MIFARE_CMD_READBLOCK) {
|
||||||
uint8_t blockNo = receivedCmd_dec[1];
|
uint8_t blockNo = receivedCmd_dec[1];
|
||||||
emlGetMem(response, blockNo, 1);
|
emlGetMem(response, blockNo, 1);
|
||||||
if (IsSectorTrailer(blockNo)) {
|
if (IsSectorTrailer(blockNo)) {
|
||||||
|
@ -593,7 +593,7 @@ void MifareSim(uint8_t flags, uint8_t exitAfterNReads, uint8_t cardsize, uint8_t
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (receivedCmd_dec[0] == ISO14443A_CMD_WRITEBLOCK) {
|
if (receivedCmd_dec[0] == MIFARE_CMD_WRITEBLOCK) {
|
||||||
uint8_t blockNo = receivedCmd_dec[1];
|
uint8_t blockNo = receivedCmd_dec[1];
|
||||||
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK));
|
EmSend4bit(mf_crypto1_encrypt4bit(pcs, CARD_ACK));
|
||||||
FpgaDisableTracing();
|
FpgaDisableTracing();
|
||||||
|
|
|
@ -451,7 +451,7 @@ int mifare_ultra_readblock(uint8_t blockNo, uint8_t *blockData)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(blockData, receivedAnswer, 14);
|
memcpy(blockData, receivedAnswer, 16);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,11 +25,6 @@
|
||||||
#define AUTH_FIRST 0
|
#define AUTH_FIRST 0
|
||||||
#define AUTH_NESTED 2
|
#define AUTH_NESTED 2
|
||||||
|
|
||||||
// mifare 4bit card answers
|
|
||||||
#define CARD_ACK 0x0A // 1010 - ACK
|
|
||||||
#define CARD_NACK_NA 0x04 // 0100 - NACK, not allowed (command not allowed)
|
|
||||||
#define CARD_NACK_TR 0x05 // 0101 - NACK, transmission error
|
|
||||||
|
|
||||||
// reader voltage field detector
|
// reader voltage field detector
|
||||||
#define MF_MINFIELDV 4000
|
#define MF_MINFIELDV 4000
|
||||||
|
|
||||||
|
|
116
armsrc/pcf7931.c
116
armsrc/pcf7931.c
|
@ -13,11 +13,11 @@ size_t DemodPCF7931(uint8_t **outBlocks) {
|
||||||
uint8_t bits[256] = {0x00};
|
uint8_t bits[256] = {0x00};
|
||||||
uint8_t blocks[8][16];
|
uint8_t blocks[8][16];
|
||||||
uint8_t *dest = BigBuf_get_addr();
|
uint8_t *dest = BigBuf_get_addr();
|
||||||
|
|
||||||
int GraphTraceLen = BigBuf_max_traceLen();
|
int GraphTraceLen = BigBuf_max_traceLen();
|
||||||
if (GraphTraceLen > 18000)
|
if (GraphTraceLen > 18000)
|
||||||
GraphTraceLen = 18000;
|
GraphTraceLen = 18000;
|
||||||
|
|
||||||
int i, j, lastval, bitidx, half_switch;
|
int i, j, lastval, bitidx, half_switch;
|
||||||
int clock = 64;
|
int clock = 64;
|
||||||
int tolerance = clock / 8;
|
int tolerance = clock / 8;
|
||||||
|
@ -107,7 +107,7 @@ size_t DemodPCF7931(uint8_t **outBlocks) {
|
||||||
for(j = 0; j < 16; ++j) {
|
for(j = 0; j < 16; ++j) {
|
||||||
blocks[num_blocks][j] =
|
blocks[num_blocks][j] =
|
||||||
128 * bits[j*8 + 7]+
|
128 * bits[j*8 + 7]+
|
||||||
64 * bits[j*8 + 6] +
|
64 * bits[j*8 + 6] +
|
||||||
32 * bits[j*8 + 5] +
|
32 * bits[j*8 + 5] +
|
||||||
16 * bits[j*8 + 4] +
|
16 * bits[j*8 + 4] +
|
||||||
8 * bits[j*8 + 3] +
|
8 * bits[j*8 + 3] +
|
||||||
|
@ -161,44 +161,44 @@ bool IsBlock1PCF7931(uint8_t *block) {
|
||||||
|
|
||||||
void ReadPCF7931() {
|
void ReadPCF7931() {
|
||||||
int found_blocks = 0; // successfully read blocks
|
int found_blocks = 0; // successfully read blocks
|
||||||
int max_blocks = 8; // readable blocks
|
int max_blocks = 8; // readable blocks
|
||||||
uint8_t memory_blocks[8][17]; // PCF content
|
uint8_t memory_blocks[8][17]; // PCF content
|
||||||
|
|
||||||
uint8_t single_blocks[8][17]; // PFC blocks with unknown position
|
uint8_t single_blocks[8][17]; // PFC blocks with unknown position
|
||||||
int single_blocks_cnt = 0;
|
int single_blocks_cnt = 0;
|
||||||
|
|
||||||
size_t n = 0; // transmitted blocks
|
size_t n = 0; // transmitted blocks
|
||||||
uint8_t tmp_blocks[4][16]; // temporary read buffer
|
uint8_t tmp_blocks[4][16]; // temporary read buffer
|
||||||
|
|
||||||
uint8_t found_0_1 = 0; // flag: blocks 0 and 1 were found
|
uint8_t found_0_1 = 0; // flag: blocks 0 and 1 were found
|
||||||
int errors = 0; // error counter
|
int errors = 0; // error counter
|
||||||
int tries = 0; // tries counter
|
int tries = 0; // tries counter
|
||||||
|
|
||||||
memset(memory_blocks, 0, 8*17*sizeof(uint8_t));
|
memset(memory_blocks, 0, 8*17*sizeof(uint8_t));
|
||||||
memset(single_blocks, 0, 8*17*sizeof(uint8_t));
|
memset(single_blocks, 0, 8*17*sizeof(uint8_t));
|
||||||
|
|
||||||
int i = 0, j = 0;
|
int i = 0, j = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
i = 0;
|
i = 0;
|
||||||
|
|
||||||
memset(tmp_blocks, 0, 4*16*sizeof(uint8_t));
|
memset(tmp_blocks, 0, 4*16*sizeof(uint8_t));
|
||||||
n = DemodPCF7931((uint8_t**)tmp_blocks);
|
n = DemodPCF7931((uint8_t**)tmp_blocks);
|
||||||
if(!n)
|
if(!n)
|
||||||
++errors;
|
++errors;
|
||||||
|
|
||||||
// exit if no block is received
|
// exit if no block is received
|
||||||
if (errors >= 10 && found_blocks == 0 && single_blocks_cnt == 0) {
|
if (errors >= 10 && found_blocks == 0 && single_blocks_cnt == 0) {
|
||||||
Dbprintf("Error, no tag or bad tag");
|
Dbprintf("Error, no tag or bad tag");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// exit if too many errors during reading
|
// exit if too many errors during reading
|
||||||
if (tries > 50 && (2*errors > tries)) {
|
if (tries > 50 && (2*errors > tries)) {
|
||||||
Dbprintf("Error reading the tag");
|
Dbprintf("Error reading the tag");
|
||||||
Dbprintf("Here is the partial content");
|
Dbprintf("Here is the partial content");
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
// our logic breaks if we don't get at least two blocks
|
// our logic breaks if we don't get at least two blocks
|
||||||
if (n < 2) {
|
if (n < 2) {
|
||||||
if (n == 0 || !memcmp(tmp_blocks[0], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16))
|
if (n == 0 || !memcmp(tmp_blocks[0], "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16))
|
||||||
|
@ -219,12 +219,12 @@ void ReadPCF7931() {
|
||||||
}
|
}
|
||||||
++tries;
|
++tries;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors);
|
Dbprintf("(dbg) got %d blocks (%d/%d found) (%d tries, %d errors)", n, found_blocks, (max_blocks == 0 ? found_blocks : max_blocks), tries, errors);
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
if(!found_0_1) {
|
if(!found_0_1) {
|
||||||
while (i < n - 1) {
|
while (i < n - 1) {
|
||||||
if (IsBlock0PCF7931(tmp_blocks[i]) && IsBlock1PCF7931(tmp_blocks[i+1])) {
|
if (IsBlock0PCF7931(tmp_blocks[i]) && IsBlock1PCF7931(tmp_blocks[i+1])) {
|
||||||
found_0_1 = 1;
|
found_0_1 = 1;
|
||||||
|
@ -234,9 +234,9 @@ void ReadPCF7931() {
|
||||||
// block 1 tells how many blocks are going to be sent
|
// block 1 tells how many blocks are going to be sent
|
||||||
max_blocks = MAX((memory_blocks[1][14] & 0x7f), memory_blocks[1][15]) + 1;
|
max_blocks = MAX((memory_blocks[1][14] & 0x7f), memory_blocks[1][15]) + 1;
|
||||||
found_blocks = 2;
|
found_blocks = 2;
|
||||||
|
|
||||||
Dbprintf("Found blocks 0 and 1. PCF is transmitting %d blocks.", max_blocks);
|
Dbprintf("Found blocks 0 and 1. PCF is transmitting %d blocks.", max_blocks);
|
||||||
|
|
||||||
// handle the following blocks
|
// handle the following blocks
|
||||||
for (j = i + 2; j < n; ++j) {
|
for (j = i + 2; j < n; ++j) {
|
||||||
memcpy(memory_blocks[found_blocks], tmp_blocks[j], 16);
|
memcpy(memory_blocks[found_blocks], tmp_blocks[j], 16);
|
||||||
|
@ -297,14 +297,14 @@ void ReadPCF7931() {
|
||||||
Dbprintf("<missing block %d>", i);
|
Dbprintf("<missing block %d>", i);
|
||||||
}
|
}
|
||||||
Dbprintf("-----------------------------------------");
|
Dbprintf("-----------------------------------------");
|
||||||
|
|
||||||
if (found_blocks < max_blocks) {
|
if (found_blocks < max_blocks) {
|
||||||
Dbprintf("-----------------------------------------");
|
Dbprintf("-----------------------------------------");
|
||||||
Dbprintf("Blocks with unknown position:");
|
Dbprintf("Blocks with unknown position:");
|
||||||
Dbprintf("-----------------------------------------");
|
Dbprintf("-----------------------------------------");
|
||||||
for (i = 0; i < single_blocks_cnt; ++i)
|
for (i = 0; i < single_blocks_cnt; ++i)
|
||||||
print_result("Block", single_blocks[i], 16);
|
print_result("Block", single_blocks[i], 16);
|
||||||
|
|
||||||
Dbprintf("-----------------------------------------");
|
Dbprintf("-----------------------------------------");
|
||||||
}
|
}
|
||||||
cmd_send(CMD_ACK,0,0,0,0,0);
|
cmd_send(CMD_ACK,0,0,0,0,0);
|
||||||
|
@ -332,42 +332,42 @@ static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int3
|
||||||
AddBytePCF7931(pass[6], tab, l, p);
|
AddBytePCF7931(pass[6], tab, l, p);
|
||||||
//programming mode (0 or 1)
|
//programming mode (0 or 1)
|
||||||
AddBitPCF7931(0, tab, l, p);
|
AddBitPCF7931(0, tab, l, p);
|
||||||
|
|
||||||
//block adress on 6 bits
|
//block adress on 6 bits
|
||||||
for (u = 0; u < 6; ++u) {
|
for (u = 0; u < 6; ++u) {
|
||||||
if (address & (1 << u)) { // bit 1
|
if (address & (1 << u)) { // bit 1
|
||||||
++parity;
|
++parity;
|
||||||
AddBitPCF7931(1, tab, l, p);
|
AddBitPCF7931(1, tab, l, p);
|
||||||
} else { // bit 0
|
} else { // bit 0
|
||||||
AddBitPCF7931(0, tab, l, p);
|
AddBitPCF7931(0, tab, l, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//byte address on 4 bits
|
//byte address on 4 bits
|
||||||
for (u = 0; u < 4; ++u)
|
for (u = 0; u < 4; ++u)
|
||||||
{
|
{
|
||||||
if (byte & (1 << u)) { // bit 1
|
if (byte & (1 << u)) { // bit 1
|
||||||
parity++;
|
parity++;
|
||||||
AddBitPCF7931(1, tab, l, p);
|
AddBitPCF7931(1, tab, l, p);
|
||||||
}
|
}
|
||||||
else // bit 0
|
else // bit 0
|
||||||
AddBitPCF7931(0, tab, l, p);
|
AddBitPCF7931(0, tab, l, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
//data on 8 bits
|
//data on 8 bits
|
||||||
for (u=0; u<8; u++)
|
for (u=0; u<8; u++)
|
||||||
{
|
{
|
||||||
if (data&(1<<u)) { // bit 1
|
if (data&(1<<u)) { // bit 1
|
||||||
parity++;
|
parity++;
|
||||||
AddBitPCF7931(1, tab, l, p);
|
AddBitPCF7931(1, tab, l, p);
|
||||||
}
|
}
|
||||||
else //bit 0
|
else //bit 0
|
||||||
AddBitPCF7931(0, tab, l, p);
|
AddBitPCF7931(0, tab, l, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
//parity bit
|
//parity bit
|
||||||
if ((parity % 2) == 0)
|
if ((parity % 2) == 0)
|
||||||
AddBitPCF7931(0, tab, l, p); //even parity
|
AddBitPCF7931(0, tab, l, p); //even parity
|
||||||
else
|
else
|
||||||
AddBitPCF7931(1, tab, l, p);//odd parity
|
AddBitPCF7931(1, tab, l, p);//odd parity
|
||||||
|
|
||||||
|
@ -394,20 +394,14 @@ static void RealWritePCF7931(uint8_t *pass, uint16_t init_delay, int32_t l, int3
|
||||||
void BruteForcePCF7931(uint64_t password, uint8_t tries, uint16_t init_delay, int32_t l, int32_t p) {
|
void BruteForcePCF7931(uint64_t password, uint8_t tries, uint16_t init_delay, int32_t l, int32_t p) {
|
||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
uint8_t pass_array[7];
|
uint8_t pass_array[7];
|
||||||
|
|
||||||
while (password < 0x00FFFFFFFFFFFFFF) {
|
while (password < 0x00FFFFFFFFFFFFFF) {
|
||||||
if (BUTTON_PRESS()) {
|
if (BUTTON_PRESS()) {
|
||||||
Dbprintf("Button pressed, stopping bruteforce ...");
|
Dbprintf("Button pressed, stopping bruteforce ...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pass_array[0] = password & 0xFF;
|
num_to_bytes(password, 7, pass_array);
|
||||||
pass_array[1] = (password >> 8) & 0xFF;
|
|
||||||
pass_array[2] = (password >> 16) & 0xFF;
|
|
||||||
pass_array[3] = (password >> 24) & 0xFF;
|
|
||||||
pass_array[4] = (password >> 32) & 0xFF;
|
|
||||||
pass_array[5] = (password >> 40) & 0xFF;
|
|
||||||
pass_array[6] = (password >> 48) & 0xFF;
|
|
||||||
|
|
||||||
Dbprintf("Trying: %02x %02x %02x %02x %02x %02x %02x ...",
|
Dbprintf("Trying: %02x %02x %02x %02x %02x %02x %02x ...",
|
||||||
pass_array[0],
|
pass_array[0],
|
||||||
|
@ -417,7 +411,7 @@ void BruteForcePCF7931(uint64_t password, uint8_t tries, uint16_t init_delay, in
|
||||||
pass_array[4],
|
pass_array[4],
|
||||||
pass_array[5],
|
pass_array[5],
|
||||||
pass_array[6]);
|
pass_array[6]);
|
||||||
|
|
||||||
for (i = 0; i < tries; ++i)
|
for (i = 0; i < tries; ++i)
|
||||||
RealWritePCF7931
|
RealWritePCF7931
|
||||||
(
|
(
|
||||||
|
@ -429,15 +423,15 @@ void BruteForcePCF7931(uint64_t password, uint8_t tries, uint16_t init_delay, in
|
||||||
7,
|
7,
|
||||||
0x01
|
0x01
|
||||||
);
|
);
|
||||||
|
|
||||||
++password;
|
++password;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write on a byte of a PCF7931 tag
|
/* Write on a byte of a PCF7931 tag
|
||||||
* @param address : address of the block to write
|
* @param address : address of the block to write
|
||||||
@param byte : address of the byte to write
|
@param byte : address of the byte to write
|
||||||
@param data : data to write
|
@param data : data to write
|
||||||
*/
|
*/
|
||||||
void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) {
|
void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, uint8_t pass5, uint8_t pass6, uint8_t pass7, uint16_t init_delay, int32_t l, int32_t p, uint8_t address, uint8_t byte, uint8_t data) {
|
||||||
Dbprintf("Initialization delay : %d us", init_delay);
|
Dbprintf("Initialization delay : %d us", init_delay);
|
||||||
|
@ -446,9 +440,9 @@ void WritePCF7931(uint8_t pass1, uint8_t pass2, uint8_t pass3, uint8_t pass4, ui
|
||||||
Dbprintf("Block address : %02x", address);
|
Dbprintf("Block address : %02x", address);
|
||||||
Dbprintf("Byte address : %02x", byte);
|
Dbprintf("Byte address : %02x", byte);
|
||||||
Dbprintf("Data : %02x", data);
|
Dbprintf("Data : %02x", data);
|
||||||
|
|
||||||
uint8_t password[7] = {pass1, pass2, pass3, pass4, pass5, pass6, pass7};
|
uint8_t password[7] = {pass1, pass2, pass3, pass4, pass5, pass6, pass7};
|
||||||
|
|
||||||
RealWritePCF7931 (password, init_delay, l, p, address, byte, data);
|
RealWritePCF7931 (password, init_delay, l, p, address, byte, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,7 +482,7 @@ void SendCmdPCF7931(uint32_t * tab) {
|
||||||
HIGH(GPIO_SSC_DOUT);
|
HIGH(GPIO_SSC_DOUT);
|
||||||
while(tempo != tab[u])
|
while(tempo != tab[u])
|
||||||
tempo = AT91C_BASE_TC0->TC_CV;
|
tempo = AT91C_BASE_TC0->TC_CV;
|
||||||
|
|
||||||
// stop modulating antenna
|
// stop modulating antenna
|
||||||
LOW(GPIO_SSC_DOUT);
|
LOW(GPIO_SSC_DOUT);
|
||||||
while(tempo != tab[u+1])
|
while(tempo != tab[u+1])
|
||||||
|
@ -510,7 +504,7 @@ void SendCmdPCF7931(uint32_t * tab) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Add a byte for building the data frame of PCF7931 tags
|
/* Add a byte for building the data frame of PCF7931 tags
|
||||||
* @param b : byte to add
|
* @param b : byte to add
|
||||||
* @param tab : array of the data frame
|
* @param tab : array of the data frame
|
||||||
* @param l : offset on low pulse width
|
* @param l : offset on low pulse width
|
||||||
|
@ -519,7 +513,7 @@ void SendCmdPCF7931(uint32_t * tab) {
|
||||||
bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p) {
|
bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p) {
|
||||||
uint32_t u;
|
uint32_t u;
|
||||||
for (u = 0; u < 8; ++u) {
|
for (u = 0; u < 8; ++u) {
|
||||||
if (byte & (1 << u)) { //bit is 1
|
if (byte & (1 << u)) { //bit is 1
|
||||||
if(AddBitPCF7931(1, tab, l, p)==1)return 1;
|
if(AddBitPCF7931(1, tab, l, p)==1)return 1;
|
||||||
} else { //bit is 0
|
} else { //bit is 0
|
||||||
if(AddBitPCF7931(0, tab, l, p)==1)return 1;
|
if(AddBitPCF7931(0, tab, l, p)==1)return 1;
|
||||||
|
@ -529,7 +523,7 @@ bool AddBytePCF7931(uint8_t byte, uint32_t * tab, int32_t l, int32_t p) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a bits for building the data frame of PCF7931 tags
|
/* Add a bits for building the data frame of PCF7931 tags
|
||||||
* @param b : bit to add
|
* @param b : bit to add
|
||||||
* @param tab : array of the data frame
|
* @param tab : array of the data frame
|
||||||
* @param l : offset on low pulse width
|
* @param l : offset on low pulse width
|
||||||
|
@ -540,23 +534,23 @@ bool AddBitPCF7931(bool b, uint32_t * tab, int32_t l, int32_t p) {
|
||||||
|
|
||||||
for (u = 0; tab[u] != 0; u += 3){} //we put the cursor at the last value of the array
|
for (u = 0; tab[u] != 0; u += 3){} //we put the cursor at the last value of the array
|
||||||
|
|
||||||
if (b == 1) { //add a bit 1
|
if (b == 1) { //add a bit 1
|
||||||
if (u == 0) tab[u] = 34 * T0_PCF + p;
|
if (u == 0) tab[u] = 34 * T0_PCF + p;
|
||||||
else tab[u] = 34 * T0_PCF + tab[u-1] + p;
|
else tab[u] = 34 * T0_PCF + tab[u-1] + p;
|
||||||
|
|
||||||
tab[u+1] = 6 * T0_PCF+tab[u] + l;
|
tab[u+1] = 6 * T0_PCF+tab[u] + l;
|
||||||
tab[u+2] = 88 * T0_PCF+tab[u + 1] - l - p;
|
tab[u+2] = 88 * T0_PCF+tab[u + 1] - l - p;
|
||||||
return 0;
|
return 0;
|
||||||
} else { //add a bit 0
|
} else { //add a bit 0
|
||||||
|
|
||||||
if (u == 0) tab[u] = 98 * T0_PCF + p;
|
if (u == 0) tab[u] = 98 * T0_PCF + p;
|
||||||
else tab[u] = 98 * T0_PCF + tab[u-1] + p;
|
else tab[u] = 98 * T0_PCF + tab[u-1] + p;
|
||||||
|
|
||||||
tab[u + 1] = 6 * T0_PCF + tab[u] + l;
|
tab[u + 1] = 6 * T0_PCF + tab[u] + l;
|
||||||
tab[u + 2] = 24 * T0_PCF + tab[u + 1] - l - p;
|
tab[u + 2] = 24 * T0_PCF + tab[u + 1] - l - p;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,8 +564,8 @@ bool AddPatternPCF7931(uint32_t a, uint32_t b, uint32_t c, uint32_t * tab) {
|
||||||
uint32_t u = 0;
|
uint32_t u = 0;
|
||||||
for(u = 0; tab[u] != 0; u += 3){} //we put the cursor at the last value of the array
|
for(u = 0; tab[u] != 0; u += 3){} //we put the cursor at the last value of the array
|
||||||
|
|
||||||
if (u == 0) tab[u] = a;
|
if (u == 0) tab[u] = a;
|
||||||
else tab[u] = a + tab[u - 1];
|
else tab[u] = a + tab[u - 1];
|
||||||
|
|
||||||
tab[u + 1] = b + tab[u];
|
tab[u + 1] = b + tab[u];
|
||||||
tab[u + 2] = c + tab[u + 1];
|
tab[u + 2] = c + tab[u + 1];
|
||||||
|
|
|
@ -16,13 +16,14 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "mifare.h"
|
#include "mifare.h"
|
||||||
|
|
||||||
int CmdHF14A(const char *Cmd);
|
extern int CmdHF14A(const char *Cmd);
|
||||||
int CmdHF14AList(const char *Cmd);
|
extern int CmdHF14AMfDbg(const char* cmd);
|
||||||
int CmdHF14AMifare(const char *Cmd);
|
extern int CmdHF14AList(const char *Cmd);
|
||||||
int CmdHF14AReader(const char *Cmd);
|
extern int CmdHF14AMifare(const char *Cmd);
|
||||||
|
extern int CmdHF14AReader(const char *Cmd);
|
||||||
extern int CmdHF14AInfo(const char *Cmd);
|
extern int CmdHF14AInfo(const char *Cmd);
|
||||||
int CmdHF14ASim(const char *Cmd);
|
extern int CmdHF14ASim(const char *Cmd);
|
||||||
int CmdHF14ASnoop(const char *Cmd);
|
extern int CmdHF14ASnoop(const char *Cmd);
|
||||||
|
|
||||||
extern void DropField();
|
extern void DropField();
|
||||||
|
|
||||||
|
|
|
@ -382,6 +382,7 @@ static command_t CommandTable15[] =
|
||||||
{"cmd", CmdHF15Cmd, 0, "Send direct commands to ISO15693 tag"},
|
{"cmd", CmdHF15Cmd, 0, "Send direct commands to ISO15693 tag"},
|
||||||
{"findafi", CmdHF15Afi, 0, "Brute force AFI of an ISO15693 tag"},
|
{"findafi", CmdHF15Afi, 0, "Brute force AFI of an ISO15693 tag"},
|
||||||
{"dumpmemory", CmdHF15DumpMem, 0, "Read all memory pages of an ISO15693 tag"},
|
{"dumpmemory", CmdHF15DumpMem, 0, "Read all memory pages of an ISO15693 tag"},
|
||||||
|
{"csetuid", CmdHF15CSetUID, 0, "Set UID for magic Chinese card"},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -954,6 +955,92 @@ int CmdHF15CmdWrite(const char *Cmd) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CmdHF15CSetUID(const char *Cmd)
|
||||||
|
{
|
||||||
|
uint8_t uid[8] = {0x00};
|
||||||
|
uint8_t oldUid[8], newUid[8] = {0x00};
|
||||||
|
|
||||||
|
uint8_t needHelp = 0;
|
||||||
|
char cmdp = 1;
|
||||||
|
|
||||||
|
if (param_getchar(Cmd, 0) && param_gethex(Cmd, 0, uid, 16)) {
|
||||||
|
PrintAndLog("UID must include 16 HEX symbols");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uid[0] != 0xe0) {
|
||||||
|
PrintAndLog("UID must begin with the byte 'E0'");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(param_getchar(Cmd, cmdp) != 0x00)
|
||||||
|
{
|
||||||
|
switch(param_getchar(Cmd, cmdp))
|
||||||
|
{
|
||||||
|
case 'h':
|
||||||
|
case 'H':
|
||||||
|
needHelp = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PrintAndLog("ERROR: Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
|
needHelp = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cmdp++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(Cmd) < 1 || needHelp) {
|
||||||
|
PrintAndLog("");
|
||||||
|
PrintAndLog("Usage: hf 15 csetuid <UID 16 hex symbols>");
|
||||||
|
PrintAndLog("sample: hf 15 csetuid E004013344556677");
|
||||||
|
PrintAndLog("Set UID for magic Chinese card (only works with such cards)");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLog("");
|
||||||
|
PrintAndLog("new UID | %s", sprint_hex(uid, 8));
|
||||||
|
PrintAndLog("Using backdoor Magic tag function");
|
||||||
|
|
||||||
|
if (!getUID(oldUid)) {
|
||||||
|
PrintAndLog("Can't get old UID.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
UsbCommand resp;
|
||||||
|
uint8_t *recv;
|
||||||
|
char *hexout;
|
||||||
|
UsbCommand c = {CMD_CSETUID_ISO_15693, {0, 0, 0}};
|
||||||
|
memcpy(c.d.asBytes, uid, 8);
|
||||||
|
|
||||||
|
SendCommand(&c);
|
||||||
|
|
||||||
|
for (int i=0; i<4; i++) {
|
||||||
|
if (WaitForResponseTimeout(CMD_ACK,&resp,1000)) {
|
||||||
|
recv = resp.d.asBytes;
|
||||||
|
PrintAndLog("received %i octets",resp.arg[0]);
|
||||||
|
hexout = (char *)malloc(resp.arg[0] * 3 + 1);
|
||||||
|
if (hexout != NULL) {
|
||||||
|
for (int i = 0; i < resp.arg[0]; i++) { // data in hex
|
||||||
|
sprintf(&hexout[i * 3], "%02X ", recv[i]);
|
||||||
|
}
|
||||||
|
PrintAndLog("%s", hexout);
|
||||||
|
free(hexout);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PrintAndLog("timeout while waiting for reply.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!getUID(newUid)) {
|
||||||
|
PrintAndLog("Can't get new UID.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLog("");
|
||||||
|
PrintAndLog("old UID : %02X %02X %02X %02X %02X %02X %02X %02X", oldUid[7], oldUid[6], oldUid[5], oldUid[4], oldUid[3], oldUid[2], oldUid[1], oldUid[0]);
|
||||||
|
PrintAndLog("new UID : %02X %02X %02X %02X %02X %02X %02X %02X", newUid[7], newUid[6], newUid[5], newUid[4], newUid[3], newUid[2], newUid[1], newUid[0]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static command_t CommandTable15Cmd[] =
|
static command_t CommandTable15Cmd[] =
|
||||||
|
@ -967,7 +1054,8 @@ static command_t CommandTable15Cmd[] =
|
||||||
{"write", CmdHF15CmdWrite, 0, "Write a block"},
|
{"write", CmdHF15CmdWrite, 0, "Write a block"},
|
||||||
{"readmulti",CmdHF15CmdReadmulti, 0, "Reads multiple Blocks"},
|
{"readmulti",CmdHF15CmdReadmulti, 0, "Reads multiple Blocks"},
|
||||||
{"sysinfo",CmdHF15CmdSysinfo, 0, "Get Card Information"},
|
{"sysinfo",CmdHF15CmdSysinfo, 0, "Get Card Information"},
|
||||||
{"raw", CmdHF15CmdRaw, 0, "Send raw hex data to tag"},
|
{"raw", CmdHF15CmdRaw, 0, "Send raw hex data to tag"},
|
||||||
|
{"csetuid", CmdHF15CSetUID, 0, "Set UID for magic Chinese card"},
|
||||||
{"debug", CmdHF15CmdDebug, 0, "Turn debugging on/off"},
|
{"debug", CmdHF15CmdDebug, 0, "Turn debugging on/off"},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,6 +22,7 @@ int CmdHF15Reader(const char *Cmd);
|
||||||
int CmdHF15Sim(const char *Cmd);
|
int CmdHF15Sim(const char *Cmd);
|
||||||
int CmdHF15Record(const char *Cmd);
|
int CmdHF15Record(const char *Cmd);
|
||||||
int CmdHF15Cmd(const char*Cmd);
|
int CmdHF15Cmd(const char*Cmd);
|
||||||
|
int CmdHF15CSetUID(const char *Cmd);
|
||||||
int CmdHF15CmdHelp(const char*Cmd);
|
int CmdHF15CmdHelp(const char*Cmd);
|
||||||
int CmdHF15Help(const char*Cmd);
|
int CmdHF15Help(const char*Cmd);
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "usb_cmd.h"
|
#include "usb_cmd.h"
|
||||||
#include "cmdhfmfu.h"
|
#include "cmdhfmfu.h"
|
||||||
#include "util_posix.h"
|
#include "util_posix.h"
|
||||||
|
#include "cmdhf14a.h" // DropField()
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
|
|
|
@ -22,29 +22,29 @@
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
static command_t CommandTable[] =
|
static command_t CommandTable[] =
|
||||||
{
|
{
|
||||||
{"help", CmdHelp, 1, "This help"},
|
{"help", CmdHelp, 1, "This help"},
|
||||||
{"decode", CmdLegicDecode, 0, "Display deobfuscated and decoded LEGIC RF tag data (use after hf legic reader)"},
|
{"decode", CmdLegicDecode, 0, "Display deobfuscated and decoded LEGIC RF tag data (use after hf legic reader)"},
|
||||||
{"reader", CmdLegicRFRead, 0, "[offset [length]] -- read bytes from a LEGIC card"},
|
{"reader", CmdLegicRFRead, 0, "[offset [length]] -- read bytes from a LEGIC card"},
|
||||||
{"save", CmdLegicSave, 0, "<filename> [<length>] -- Store samples"},
|
{"save", CmdLegicSave, 0, "<filename> [<length>] -- Store samples"},
|
||||||
{"load", CmdLegicLoad, 0, "<filename> -- Restore samples"},
|
{"load", CmdLegicLoad, 0, "<filename> -- Restore samples"},
|
||||||
{"sim", CmdLegicRfSim, 0, "[tagtype, 0:MIM22, 1:MIM256, 2:MIM1024] Start tag simulator (use after load or read)"},
|
{"sim", CmdLegicRfSim, 0, "[tagtype, 0:MIM22, 1:MIM256, 2:MIM1024] Start tag simulator (use after load or read)"},
|
||||||
{"write", CmdLegicRfWrite,0, "<offset> <length> -- Write sample buffer (user after load or read)"},
|
{"write", CmdLegicRfWrite,0, "<offset> <length> -- Write sample buffer (user after load or read)"},
|
||||||
{"fill", CmdLegicRfFill, 0, "<offset> <length> <value> -- Fill/Write tag with constant value"},
|
{"fill", CmdLegicRfFill, 0, "<offset> <length> <value> -- Fill/Write tag with constant value"},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
int CmdHFLegic(const char *Cmd)
|
int CmdHFLegic(const char *Cmd)
|
||||||
{
|
{
|
||||||
CmdsParse(CommandTable, Cmd);
|
CmdsParse(CommandTable, Cmd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdHelp(const char *Cmd)
|
int CmdHelp(const char *Cmd)
|
||||||
{
|
{
|
||||||
CmdsHelp(CommandTable);
|
CmdsHelp(CommandTable);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -54,189 +54,191 @@ int CmdHelp(const char *Cmd)
|
||||||
*/
|
*/
|
||||||
int CmdLegicDecode(const char *Cmd)
|
int CmdLegicDecode(const char *Cmd)
|
||||||
{
|
{
|
||||||
int i, j, k, n;
|
int i, j, k, n;
|
||||||
int segment_len = 0;
|
int segment_len = 0;
|
||||||
int segment_flag = 0;
|
int segment_flag = 0;
|
||||||
int stamp_len = 0;
|
int stamp_len = 0;
|
||||||
int crc = 0;
|
int crc = 0;
|
||||||
int wrp = 0;
|
int wrp = 0;
|
||||||
int wrc = 0;
|
int wrc = 0;
|
||||||
uint8_t data_buf[1053]; // receiver buffer
|
uint8_t data_buf[1053]; // receiver buffer
|
||||||
char out_string[3076]; // just use big buffer - bad practice
|
char out_string[3076]; // just use big buffer - bad practice
|
||||||
char token_type[4];
|
char token_type[4];
|
||||||
|
|
||||||
// copy data from proxmark into buffer
|
// copy data from proxmark into buffer
|
||||||
GetFromBigBuf(data_buf, sizeof(data_buf), 0, NULL, -1, false);
|
GetFromBigBuf(data_buf, sizeof(data_buf), 0, NULL, -1, false);
|
||||||
|
|
||||||
// Output CDF System area (9 bytes) plus remaining header area (12 bytes)
|
// Output CDF System area (9 bytes) plus remaining header area (12 bytes)
|
||||||
|
|
||||||
PrintAndLog("\nCDF: System Area");
|
PrintAndLog("\nCDF: System Area");
|
||||||
|
|
||||||
PrintAndLog("MCD: %02x, MSN: %02x %02x %02x, MCC: %02x",
|
PrintAndLog("MCD: %02x, MSN: %02x %02x %02x, MCC: %02x",
|
||||||
data_buf[0],
|
data_buf[0],
|
||||||
data_buf[1],
|
data_buf[1],
|
||||||
data_buf[2],
|
data_buf[2],
|
||||||
data_buf[3],
|
data_buf[3],
|
||||||
data_buf[4]
|
data_buf[4]
|
||||||
);
|
);
|
||||||
|
|
||||||
crc = data_buf[4];
|
crc = data_buf[4];
|
||||||
|
|
||||||
switch (data_buf[5]&0x7f) {
|
switch (data_buf[5]&0x7f) {
|
||||||
case 0x00 ... 0x2f:
|
case 0x00 ... 0x2f:
|
||||||
strncpy(token_type, "IAM",sizeof(token_type));
|
strncpy(token_type, "IAM",sizeof(token_type));
|
||||||
break;
|
break;
|
||||||
case 0x30 ... 0x6f:
|
case 0x30 ... 0x6f:
|
||||||
strcpy(token_type, "SAM");
|
strcpy(token_type, "SAM");
|
||||||
break;
|
break;
|
||||||
case 0x70 ... 0x7f:
|
case 0x70 ... 0x7f:
|
||||||
strcpy(token_type, "GAM");
|
strcpy(token_type, "GAM");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
strcpy(token_type, "???");
|
strcpy(token_type, "???");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
stamp_len = 0xfc - data_buf[6];
|
stamp_len = 0xfc - data_buf[6];
|
||||||
|
|
||||||
PrintAndLog("DCF: %02x %02x, Token_Type=%s (OLE=%01u), Stamp_len=%02u",
|
PrintAndLog("DCF: %02x %02x, Token_Type=%s (OLE=%01u), Stamp_len=%02u",
|
||||||
data_buf[5],
|
data_buf[5],
|
||||||
data_buf[6],
|
data_buf[6],
|
||||||
token_type,
|
token_type,
|
||||||
(data_buf[5]&0x80)>>7,
|
(data_buf[5]&0x80)>>7,
|
||||||
stamp_len
|
stamp_len
|
||||||
);
|
);
|
||||||
|
|
||||||
PrintAndLog("WRP=%02u, WRC=%01u, RD=%01u, raw=%02x, SSC=%02x",
|
PrintAndLog("WRP=%02u, WRC=%01u, RD=%01u, raw=%02x, SSC=%02x",
|
||||||
data_buf[7]&0x0f,
|
data_buf[7]&0x0f,
|
||||||
(data_buf[7]&0x70)>>4,
|
(data_buf[7]&0x70)>>4,
|
||||||
(data_buf[7]&0x80)>>7,
|
(data_buf[7]&0x80)>>7,
|
||||||
data_buf[7],
|
data_buf[7],
|
||||||
data_buf[8]
|
data_buf[8]
|
||||||
);
|
);
|
||||||
|
|
||||||
PrintAndLog("Remaining Header Area");
|
PrintAndLog("Remaining Header Area");
|
||||||
|
|
||||||
PrintAndLog("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
PrintAndLog("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||||
data_buf[9],
|
data_buf[9],
|
||||||
data_buf[10],
|
data_buf[10],
|
||||||
data_buf[11],
|
data_buf[11],
|
||||||
data_buf[12],
|
data_buf[12],
|
||||||
data_buf[13],
|
data_buf[13],
|
||||||
data_buf[14],
|
data_buf[14],
|
||||||
data_buf[15],
|
data_buf[15],
|
||||||
data_buf[16],
|
data_buf[16],
|
||||||
data_buf[17],
|
data_buf[17],
|
||||||
data_buf[18],
|
data_buf[18],
|
||||||
data_buf[19],
|
data_buf[19],
|
||||||
data_buf[20],
|
data_buf[20],
|
||||||
data_buf[21]
|
data_buf[21]
|
||||||
);
|
);
|
||||||
|
|
||||||
PrintAndLog("\nADF: User Area");
|
PrintAndLog("\nADF: User Area");
|
||||||
|
|
||||||
i = 22;
|
i = 22;
|
||||||
for (n=0; n<64; n++) {
|
for (n=0; n<64; n++) {
|
||||||
segment_len = ((data_buf[i+1]^crc)&0x0f) * 256 + (data_buf[i]^crc);
|
segment_len = ((data_buf[i+1]^crc)&0x0f) * 256 + (data_buf[i]^crc);
|
||||||
segment_flag = ((data_buf[i+1]^crc)&0xf0)>>4;
|
segment_flag = ((data_buf[i+1]^crc)&0xf0)>>4;
|
||||||
|
|
||||||
wrp = (data_buf[i+2]^crc);
|
wrp = (data_buf[i+2]^crc);
|
||||||
wrc = ((data_buf[i+3]^crc)&0x70)>>4;
|
wrc = ((data_buf[i+3]^crc)&0x70)>>4;
|
||||||
|
|
||||||
PrintAndLog("Segment %02u: raw header=%02x %02x %02x %02x, flag=%01x (valid=%01u, last=%01u), len=%04u, WRP=%02u, WRC=%02u, RD=%01u, CRC=%02x",
|
PrintAndLog("Segment %02u: raw header=%02x %02x %02x %02x, flag=%01x (valid=%01u, last=%01u), len=%04u, WRP=%02u, WRC=%02u, RD=%01u, CRC=%02x",
|
||||||
n,
|
n,
|
||||||
data_buf[i]^crc,
|
data_buf[i]^crc,
|
||||||
data_buf[i+1]^crc,
|
data_buf[i+1]^crc,
|
||||||
data_buf[i+2]^crc,
|
data_buf[i+2]^crc,
|
||||||
data_buf[i+3]^crc,
|
data_buf[i+3]^crc,
|
||||||
segment_flag,
|
segment_flag,
|
||||||
(segment_flag&0x4)>>2,
|
(segment_flag&0x4)>>2,
|
||||||
(segment_flag&0x8)>>3,
|
(segment_flag&0x8)>>3,
|
||||||
segment_len,
|
segment_len,
|
||||||
wrp,
|
wrp,
|
||||||
wrc,
|
wrc,
|
||||||
((data_buf[i+3]^crc)&0x80)>>7,
|
((data_buf[i+3]^crc)&0x80)>>7,
|
||||||
(data_buf[i+4]^crc)
|
(data_buf[i+4]^crc)
|
||||||
);
|
);
|
||||||
|
|
||||||
i+=5;
|
i+=5;
|
||||||
|
|
||||||
if (wrc>0) {
|
if (wrc>0) {
|
||||||
PrintAndLog("WRC protected area:");
|
PrintAndLog("WRC protected area:");
|
||||||
for (k=0, j=0; k < wrc && j<(sizeof(out_string)-3); k++, i++, j += 3) {
|
for (k=0, j=0; k < wrc && j<(sizeof(out_string)-3); k++, i++, j += 3) {
|
||||||
sprintf(&out_string[j], "%02x", (data_buf[i]^crc));
|
sprintf(&out_string[j], "%02x", (data_buf[i]^crc));
|
||||||
out_string[j+2] = ' ';
|
out_string[j+2] = ' ';
|
||||||
};
|
};
|
||||||
|
|
||||||
out_string[j] = '\0';
|
out_string[j] = '\0';
|
||||||
|
|
||||||
PrintAndLog("%s", out_string);
|
PrintAndLog("%s", out_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wrp>wrc) {
|
if (wrp>wrc) {
|
||||||
PrintAndLog("Remaining write protected area:");
|
PrintAndLog("Remaining write protected area:");
|
||||||
|
|
||||||
for (k=0, j=0; k < (wrp-wrc) && j<(sizeof(out_string)-3); k++, i++, j += 3) {
|
for (k=0, j=0; k < (wrp-wrc) && j<(sizeof(out_string)-3); k++, i++, j += 3) {
|
||||||
sprintf(&out_string[j], "%02x", (data_buf[i]^crc));
|
sprintf(&out_string[j], "%02x", (data_buf[i]^crc));
|
||||||
out_string[j+2] = ' ';
|
out_string[j+2] = ' ';
|
||||||
};
|
};
|
||||||
|
|
||||||
out_string[j] = '\0';
|
out_string[j] = '\0';
|
||||||
|
|
||||||
PrintAndLog("%s", out_string);
|
PrintAndLog("%s", out_string);
|
||||||
if((wrp-wrc) == 8) {
|
if((wrp-wrc) == 8) {
|
||||||
sprintf(out_string,"Card ID: %2X%02X%02X",data_buf[i-4]^crc,data_buf[i-3]^crc,data_buf[i-2]^crc);
|
sprintf(out_string,"Card ID: %2X%02X%02X",data_buf[i-4]^crc,data_buf[i-3]^crc,data_buf[i-2]^crc);
|
||||||
PrintAndLog("%s", out_string);
|
PrintAndLog("%s", out_string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLog("Remaining segment payload:");
|
PrintAndLog("Remaining segment payload:");
|
||||||
for (k=0, j=0; k < (segment_len - wrp - 5) && j<(sizeof(out_string)-3); k++, i++, j += 3) {
|
for (k=0, j=0; k < (segment_len - wrp - 5) && j<(sizeof(out_string)-3); k++, i++, j += 3) {
|
||||||
sprintf(&out_string[j], "%02x", (data_buf[i]^crc));
|
sprintf(&out_string[j], "%02x", (data_buf[i]^crc));
|
||||||
out_string[j+2] = ' ';
|
out_string[j+2] = ' ';
|
||||||
};
|
};
|
||||||
|
|
||||||
out_string[j] = '\0';
|
out_string[j] = '\0';
|
||||||
|
|
||||||
PrintAndLog("%s", out_string);
|
PrintAndLog("%s", out_string);
|
||||||
|
|
||||||
// end with last segment
|
// end with last segment
|
||||||
if (segment_flag & 0x8)
|
if (segment_flag & 0x8)
|
||||||
return 0;
|
return 0;
|
||||||
};
|
};
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdLegicRFRead(const char *Cmd)
|
int CmdLegicRFRead(const char *Cmd)
|
||||||
{
|
{
|
||||||
int byte_count=0,offset=0;
|
int byte_count=0,offset=0;
|
||||||
sscanf(Cmd, "%i %i", &offset, &byte_count);
|
sscanf(Cmd, "%i %i", &offset, &byte_count);
|
||||||
if(byte_count == 0) byte_count = -1;
|
if(byte_count == 0) byte_count = -1;
|
||||||
if(byte_count + offset > 1024) byte_count = 1024 - offset;
|
if(byte_count + offset > 1024) byte_count = 1024 - offset;
|
||||||
UsbCommand c={CMD_READER_LEGIC_RF, {offset, byte_count, 0}};
|
UsbCommand c={CMD_READER_LEGIC_RF, {offset, byte_count, 0}};
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
WaitForResponse(CMD_ACK,&resp);
|
WaitForResponse(CMD_ACK,&resp);
|
||||||
switch (resp.arg[0]) {
|
switch (resp.arg[0]) {
|
||||||
case 0:
|
legic_card_select_t card;
|
||||||
PrintAndLog("Card (MIM %i) read, use 'hf legic decode' or", ((legic_card_select_t*)resp.d.asBytes)->cardsize);
|
case 0:
|
||||||
PrintAndLog("'data hexsamples %d' to view results", (resp.arg[1] + 7) & ~7);
|
memcpy(&card, resp.d.asBytes, sizeof(card));
|
||||||
break;
|
PrintAndLog("Card (MIM %i) read, use 'hf legic decode' or", card.cardsize);
|
||||||
case 1:
|
PrintAndLog("'data hexsamples %d' to view results", (resp.arg[1] + 7) & ~7);
|
||||||
PrintAndLog("No or unknown card found, aborting");
|
break;
|
||||||
break;
|
case 1:
|
||||||
case 2:
|
PrintAndLog("No or unknown card found, aborting");
|
||||||
PrintAndLog("operation failed @ 0x%03.3x", resp.arg[1]);
|
break;
|
||||||
break;
|
case 2:
|
||||||
}
|
PrintAndLog("operation failed @ 0x%03.3x", resp.arg[1]);
|
||||||
return resp.arg[0];
|
break;
|
||||||
|
}
|
||||||
|
return resp.arg[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdLegicLoad(const char *Cmd)
|
int CmdLegicLoad(const char *Cmd)
|
||||||
{
|
{
|
||||||
char filename[FILE_PATH_SIZE] = {0x00};
|
char filename[FILE_PATH_SIZE] = {0x00};
|
||||||
int len = 0;
|
int len = 0;
|
||||||
|
|
||||||
if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {
|
if (param_getchar(Cmd, 0) == 'h' || param_getchar(Cmd, 0)== 0x00) {
|
||||||
PrintAndLog("It loads datasamples from the file `filename`");
|
PrintAndLog("It loads datasamples from the file `filename`");
|
||||||
PrintAndLog("Usage: hf legic load <file name>");
|
PrintAndLog("Usage: hf legic load <file name>");
|
||||||
|
@ -244,92 +246,92 @@ int CmdLegicLoad(const char *Cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(Cmd);
|
len = strlen(Cmd);
|
||||||
if (len > FILE_PATH_SIZE) {
|
if (len > FILE_PATH_SIZE) {
|
||||||
PrintAndLog("Filepath too long (was %s bytes), max allowed is %s ", len, FILE_PATH_SIZE);
|
PrintAndLog("Filepath too long (was %s bytes), max allowed is %s ", len, FILE_PATH_SIZE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
memcpy(filename, Cmd, len);
|
memcpy(filename, Cmd, len);
|
||||||
|
|
||||||
FILE *f = fopen(filename, "r");
|
FILE *f = fopen(filename, "r");
|
||||||
if(!f) {
|
if (!f) {
|
||||||
PrintAndLog("couldn't open '%s'", Cmd);
|
PrintAndLog("couldn't open '%s'", Cmd);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
char line[80]; int offset = 0; unsigned int data[8];
|
char line[80]; int offset = 0; unsigned int data[8];
|
||||||
while(fgets(line, sizeof(line), f)) {
|
while (fgets(line, sizeof(line), f)) {
|
||||||
int res = sscanf(line, "%x %x %x %x %x %x %x %x",
|
int res = sscanf(line, "%x %x %x %x %x %x %x %x",
|
||||||
&data[0], &data[1], &data[2], &data[3],
|
&data[0], &data[1], &data[2], &data[3],
|
||||||
&data[4], &data[5], &data[6], &data[7]);
|
&data[4], &data[5], &data[6], &data[7]);
|
||||||
if(res != 8) {
|
if (res != 8) {
|
||||||
PrintAndLog("Error: could not read samples");
|
PrintAndLog("Error: could not read samples");
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {offset, 1, 0}};
|
UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {offset, 1, 0}};
|
||||||
int j; for(j = 0; j < 8; j++) {
|
int j; for(j = 0; j < 8; j++) {
|
||||||
c.d.asBytes[j] = data[j];
|
c.d.asBytes[j] = data[j];
|
||||||
}
|
}
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
WaitForResponse(CMD_ACK, NULL);
|
WaitForResponse(CMD_ACK, NULL);
|
||||||
offset += 8;
|
offset += 8;
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
PrintAndLog("loaded %u samples", offset);
|
PrintAndLog("loaded %u samples", offset);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdLegicSave(const char *Cmd)
|
int CmdLegicSave(const char *Cmd)
|
||||||
{
|
{
|
||||||
int requested = 1024;
|
int requested = 1024;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
int delivered = 0;
|
int delivered = 0;
|
||||||
char filename[FILE_PATH_SIZE];
|
char filename[FILE_PATH_SIZE];
|
||||||
uint8_t got[1024];
|
uint8_t got[1024];
|
||||||
|
|
||||||
sscanf(Cmd, " %s %i %i", filename, &requested, &offset);
|
|
||||||
|
|
||||||
/* If no length given save entire legic read buffer */
|
sscanf(Cmd, " %s %i %i", filename, &requested, &offset);
|
||||||
/* round up to nearest 8 bytes so the saved data can be used with legicload */
|
|
||||||
if (requested == 0) {
|
|
||||||
requested = 1024;
|
|
||||||
}
|
|
||||||
if (requested % 8 != 0) {
|
|
||||||
int remainder = requested % 8;
|
|
||||||
requested = requested + 8 - remainder;
|
|
||||||
}
|
|
||||||
if (offset + requested > sizeof(got)) {
|
|
||||||
PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > 1024");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILE *f = fopen(filename, "w");
|
|
||||||
if(!f) {
|
|
||||||
PrintAndLog("couldn't open '%s'", Cmd+1);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
GetFromBigBuf(got, requested, offset, NULL, -1, false);
|
/* If no length given save entire legic read buffer */
|
||||||
|
/* round up to nearest 8 bytes so the saved data can be used with legicload */
|
||||||
|
if (requested == 0) {
|
||||||
|
requested = 1024;
|
||||||
|
}
|
||||||
|
if (requested % 8 != 0) {
|
||||||
|
int remainder = requested % 8;
|
||||||
|
requested = requested + 8 - remainder;
|
||||||
|
}
|
||||||
|
if (offset + requested > sizeof(got)) {
|
||||||
|
PrintAndLog("Tried to read past end of buffer, <bytes> + <offset> > 1024");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (int j = 0; j < requested; j += 8) {
|
FILE *f = fopen(filename, "w");
|
||||||
fprintf(f, "%02x %02x %02x %02x %02x %02x %02x %02x\n",
|
if (!f) {
|
||||||
got[j+0],
|
PrintAndLog("couldn't open '%s'", Cmd+1);
|
||||||
got[j+1],
|
return -1;
|
||||||
got[j+2],
|
}
|
||||||
got[j+3],
|
|
||||||
got[j+4],
|
|
||||||
got[j+5],
|
|
||||||
got[j+6],
|
|
||||||
got[j+7]
|
|
||||||
);
|
|
||||||
delivered += 8;
|
|
||||||
if (delivered >= requested)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(f);
|
GetFromBigBuf(got, requested, offset, NULL, -1, false);
|
||||||
PrintAndLog("saved %u samples", delivered);
|
|
||||||
return 0;
|
for (int j = 0; j < requested; j += 8) {
|
||||||
|
fprintf(f, "%02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||||
|
got[j+0],
|
||||||
|
got[j+1],
|
||||||
|
got[j+2],
|
||||||
|
got[j+3],
|
||||||
|
got[j+4],
|
||||||
|
got[j+5],
|
||||||
|
got[j+6],
|
||||||
|
got[j+7]
|
||||||
|
);
|
||||||
|
delivered += 8;
|
||||||
|
if (delivered >= requested)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
PrintAndLog("saved %u samples", delivered);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdLegicRfSim(const char *Cmd)
|
int CmdLegicRfSim(const char *Cmd)
|
||||||
|
@ -343,36 +345,36 @@ int CmdLegicRfSim(const char *Cmd)
|
||||||
|
|
||||||
int CmdLegicRfWrite(const char *Cmd)
|
int CmdLegicRfWrite(const char *Cmd)
|
||||||
{
|
{
|
||||||
UsbCommand c={CMD_WRITER_LEGIC_RF};
|
UsbCommand c={CMD_WRITER_LEGIC_RF};
|
||||||
int res = sscanf(Cmd, " 0x%" SCNx64 " 0x%" SCNx64, &c.arg[0], &c.arg[1]);
|
int res = sscanf(Cmd, " 0x%" SCNx64 " 0x%" SCNx64, &c.arg[0], &c.arg[1]);
|
||||||
if(res != 2) {
|
if (res != 2) {
|
||||||
PrintAndLog("Please specify the offset and length as two hex strings");
|
PrintAndLog("Please specify the offset and length as two hex strings");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdLegicRfFill(const char *Cmd)
|
int CmdLegicRfFill(const char *Cmd)
|
||||||
{
|
{
|
||||||
UsbCommand cmd ={CMD_WRITER_LEGIC_RF};
|
UsbCommand cmd ={CMD_WRITER_LEGIC_RF};
|
||||||
int res = sscanf(Cmd, " 0x%" SCNx64 " 0x%" SCNx64 " 0x%" SCNx64, &cmd.arg[0], &cmd.arg[1], &cmd.arg[2]);
|
int res = sscanf(Cmd, " 0x%" SCNx64 " 0x%" SCNx64 " 0x%" SCNx64, &cmd.arg[0], &cmd.arg[1], &cmd.arg[2]);
|
||||||
if(res != 3) {
|
if (res != 3) {
|
||||||
PrintAndLog("Please specify the offset, length and value as two hex strings");
|
PrintAndLog("Please specify the offset, length and value as two hex strings");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {0, 1, 0}};
|
UsbCommand c={CMD_DOWNLOADED_SIM_SAMPLES_125K, {0, 1, 0}};
|
||||||
for(i = 0; i < 48; i++) {
|
for (i = 0; i < 48; i++) {
|
||||||
c.d.asBytes[i] = cmd.arg[2];
|
c.d.asBytes[i] = cmd.arg[2];
|
||||||
}
|
}
|
||||||
for(i = 0; i < 22; i++) {
|
for (i = 0; i < 22; i++) {
|
||||||
c.arg[0] = i*48;
|
c.arg[0] = i*48;
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
WaitForResponse(CMD_ACK,NULL);
|
WaitForResponse(CMD_ACK,NULL);
|
||||||
}
|
}
|
||||||
SendCommand(&cmd);
|
SendCommand(&cmd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -415,8 +415,8 @@ void annotateIso14443a(char *exp, size_t size, uint8_t* cmd, uint8_t cmdsize)
|
||||||
case ISO14443A_CMD_REQA:
|
case ISO14443A_CMD_REQA:
|
||||||
snprintf(exp,size,"REQA");
|
snprintf(exp,size,"REQA");
|
||||||
break;
|
break;
|
||||||
case ISO14443A_CMD_READBLOCK: snprintf(exp,size,"READBLOCK(%d)",cmd[1]); break;
|
case MIFARE_CMD_READBLOCK: snprintf(exp,size,"READBLOCK(%d)",cmd[1]); break;
|
||||||
case ISO14443A_CMD_WRITEBLOCK: snprintf(exp,size,"WRITEBLOCK(%d)",cmd[1]); break;
|
case MIFARE_CMD_WRITEBLOCK: snprintf(exp,size,"WRITEBLOCK(%d)",cmd[1]); break;
|
||||||
case ISO14443A_CMD_HALT:
|
case ISO14443A_CMD_HALT:
|
||||||
snprintf(exp,size,"HALT");
|
snprintf(exp,size,"HALT");
|
||||||
MifareAuthState = masNone;
|
MifareAuthState = masNone;
|
||||||
|
|
586
client/cmdhfmf.c
586
client/cmdhfmf.c
File diff suppressed because it is too large
Load diff
|
@ -11,38 +11,6 @@
|
||||||
#ifndef CMDHFMF_H__
|
#ifndef CMDHFMF_H__
|
||||||
#define CMDHFMF_H__
|
#define CMDHFMF_H__
|
||||||
|
|
||||||
#include "mifare/mifaredefault.h"
|
|
||||||
|
|
||||||
extern int CmdHFMF(const char *Cmd);
|
extern int CmdHFMF(const char *Cmd);
|
||||||
extern int CmdHFMF(const char *Cmd);
|
|
||||||
|
|
||||||
extern int CmdHF14AMfDbg(const char* cmd);
|
|
||||||
extern int CmdHF14AMfRdBl(const char* cmd);
|
|
||||||
extern int CmdHF14AMfURdBl(const char* cmd);
|
|
||||||
extern int CmdHF14AMfRdSc(const char* cmd);
|
|
||||||
extern int CmdHF14SMfURdCard(const char* cmd);
|
|
||||||
extern int CmdHF14AMfDump(const char* cmd);
|
|
||||||
extern int CmdHF14AMfRestore(const char* cmd);
|
|
||||||
extern int CmdHF14AMfWrBl(const char* cmd);
|
|
||||||
extern int CmdHF14AMfUWrBl(const char* cmd);
|
|
||||||
extern int CmdHF14AMfChk(const char* cmd);
|
|
||||||
extern int CmdHF14AMifare(const char* cmd);
|
|
||||||
extern int CmdHF14AMfNested(const char* cmd);
|
|
||||||
extern int CmdHF14AMfSniff(const char* cmd);
|
|
||||||
extern int CmdHF14AMf1kSim(const char* cmd);
|
|
||||||
extern int CmdHF14AMfEClear(const char* cmd);
|
|
||||||
extern int CmdHF14AMfEGet(const char* cmd);
|
|
||||||
extern int CmdHF14AMfESet(const char* cmd);
|
|
||||||
extern int CmdHF14AMfELoad(const char* cmd);
|
|
||||||
extern int CmdHF14AMfESave(const char* cmd);
|
|
||||||
extern int CmdHF14AMfECFill(const char* cmd);
|
|
||||||
extern int CmdHF14AMfEKeyPrn(const char* cmd);
|
|
||||||
extern int CmdHF14AMfCWipe(const char* cmd);
|
|
||||||
extern int CmdHF14AMfCSetUID(const char* cmd);
|
|
||||||
extern int CmdHF14AMfCSetBlk(const char* cmd);
|
|
||||||
extern int CmdHF14AMfCGetBlk(const char* cmd);
|
|
||||||
extern int CmdHF14AMfCGetSc(const char* cmd);
|
|
||||||
extern int CmdHF14AMfCLoad(const char* cmd);
|
|
||||||
extern int CmdHF14AMfCSave(const char* cmd);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
1779
client/cmdhfmfu.c
1779
client/cmdhfmfu.c
File diff suppressed because it is too large
Load diff
|
@ -1,54 +1,10 @@
|
||||||
#include "cmdhfmf.h"
|
|
||||||
#include "cmdhf14a.h"
|
|
||||||
|
|
||||||
#ifndef CMDHFMFU_H__
|
#ifndef CMDHFMFU_H__
|
||||||
#define CMDHFMFU_H__
|
#define CMDHFMFU_H__
|
||||||
|
|
||||||
int CmdHF14AMfUWrBl(const char *Cmd);
|
#include <stdint.h>
|
||||||
int CmdHF14AMfURdBl(const char *Cmd);
|
|
||||||
|
|
||||||
//Crypto Cards
|
extern int CmdHFMFUltra(const char *Cmd);
|
||||||
int CmdHF14AMfucAuth(const char *Cmd);
|
extern uint32_t GetHF14AMfU_Type(void);
|
||||||
|
extern int ul_print_type(uint32_t tagtype, uint8_t spacer);
|
||||||
//general stuff
|
|
||||||
int CmdHF14AMfUDump(const char *Cmd);
|
|
||||||
int CmdHF14AMfUInfo(const char *Cmd);
|
|
||||||
|
|
||||||
uint32_t GetHF14AMfU_Type(void);
|
|
||||||
int ul_print_type(uint32_t tagtype, uint8_t spacer);
|
|
||||||
|
|
||||||
int usage_hf_mfu_dump(void);
|
|
||||||
int usage_hf_mfu_info(void);
|
|
||||||
int usage_hf_mfu_rdbl(void);
|
|
||||||
int usage_hf_mfu_wrbl(void);
|
|
||||||
|
|
||||||
int CmdHFMFUltra(const char *Cmd);
|
|
||||||
|
|
||||||
typedef enum TAGTYPE_UL {
|
|
||||||
UNKNOWN = 0x000000,
|
|
||||||
UL = 0x000001,
|
|
||||||
UL_C = 0x000002,
|
|
||||||
UL_EV1_48 = 0x000004,
|
|
||||||
UL_EV1_128 = 0x000008,
|
|
||||||
NTAG = 0x000010,
|
|
||||||
NTAG_203 = 0x000020,
|
|
||||||
NTAG_210 = 0x000040,
|
|
||||||
NTAG_212 = 0x000080,
|
|
||||||
NTAG_213 = 0x000100,
|
|
||||||
NTAG_215 = 0x000200,
|
|
||||||
NTAG_216 = 0x000400,
|
|
||||||
MY_D = 0x000800,
|
|
||||||
MY_D_NFC = 0x001000,
|
|
||||||
MY_D_MOVE = 0x002000,
|
|
||||||
MY_D_MOVE_NFC = 0x004000,
|
|
||||||
MY_D_MOVE_LEAN= 0x008000,
|
|
||||||
NTAG_I2C_1K = 0x010000,
|
|
||||||
NTAG_I2C_2K = 0x020000,
|
|
||||||
FUDAN_UL = 0x040000,
|
|
||||||
MAGIC = 0x080000,
|
|
||||||
UL_MAGIC = UL | MAGIC,
|
|
||||||
UL_C_MAGIC = UL_C | MAGIC,
|
|
||||||
UL_ERROR = 0xFFFFFF,
|
|
||||||
} TagTypeUL_t;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -224,24 +224,25 @@ int usage_lf_config(void)
|
||||||
{
|
{
|
||||||
PrintAndLog("Usage: lf config [H|<divisor>] [b <bps>] [d <decim>] [a 0|1]");
|
PrintAndLog("Usage: lf config [H|<divisor>] [b <bps>] [d <decim>] [a 0|1]");
|
||||||
PrintAndLog("Options: ");
|
PrintAndLog("Options: ");
|
||||||
PrintAndLog(" h This help");
|
PrintAndLog(" h This help");
|
||||||
PrintAndLog(" L Low frequency (125 KHz)");
|
PrintAndLog(" L Low frequency (125 KHz)");
|
||||||
PrintAndLog(" H High frequency (134 KHz)");
|
PrintAndLog(" H High frequency (134 KHz)");
|
||||||
PrintAndLog(" q <divisor> Manually set divisor. 88-> 134 KHz, 95-> 125 KHz");
|
PrintAndLog(" q <divisor> Manually set divisor. 88-> 134 KHz, 95-> 125 KHz");
|
||||||
PrintAndLog(" b <bps> Sets resolution of bits per sample. Default (max): 8");
|
PrintAndLog(" b <bps> Sets resolution of bits per sample. Default (max): 8");
|
||||||
PrintAndLog(" d <decim> Sets decimation. A value of N saves only 1 in N samples. Default: 1");
|
PrintAndLog(" d <decim> Sets decimation. A value of N saves only 1 in N samples. Default: 1");
|
||||||
PrintAndLog(" a [0|1] Averaging - if set, will average the stored sample value when decimating. Default: 1");
|
PrintAndLog(" a [0|1] Averaging - if set, will average the stored sample value when decimating. Default: 1");
|
||||||
PrintAndLog(" t <threshold> Sets trigger threshold. 0 means no threshold (range: 0-128)");
|
PrintAndLog(" t <threshold> Sets trigger threshold. 0 means no threshold (range: 0-128)");
|
||||||
|
PrintAndLog(" s <smplstoskip> Sets a number of samples to skip before capture. Default: 0");
|
||||||
PrintAndLog("Examples:");
|
PrintAndLog("Examples:");
|
||||||
PrintAndLog(" lf config b 8 L");
|
PrintAndLog(" lf config b 8 L");
|
||||||
PrintAndLog(" Samples at 125KHz, 8bps.");
|
PrintAndLog(" Samples at 125KHz, 8bps.");
|
||||||
PrintAndLog(" lf config H b 4 d 3");
|
PrintAndLog(" lf config H b 4 d 3");
|
||||||
PrintAndLog(" Samples at 134KHz, averages three samples into one, stored with ");
|
PrintAndLog(" Samples at 134KHz, averages three samples into one, stored with ");
|
||||||
PrintAndLog(" a resolution of 4 bits per sample.");
|
PrintAndLog(" a resolution of 4 bits per sample.");
|
||||||
PrintAndLog(" lf read");
|
PrintAndLog(" lf read");
|
||||||
PrintAndLog(" Performs a read (active field)");
|
PrintAndLog(" Performs a read (active field)");
|
||||||
PrintAndLog(" lf snoop");
|
PrintAndLog(" lf snoop");
|
||||||
PrintAndLog(" Performs a snoop (no active field)");
|
PrintAndLog(" Performs a snoop (no active field)");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,6 +256,7 @@ int CmdLFSetConfig(const char *Cmd)
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
int trigger_threshold =-1;//Means no change
|
int trigger_threshold =-1;//Means no change
|
||||||
uint8_t unsigned_trigg = 0;
|
uint8_t unsigned_trigg = 0;
|
||||||
|
int samples_to_skip = -1;
|
||||||
|
|
||||||
uint8_t cmdp =0;
|
uint8_t cmdp =0;
|
||||||
while(param_getchar(Cmd, cmdp) != 0x00)
|
while(param_getchar(Cmd, cmdp) != 0x00)
|
||||||
|
@ -295,6 +297,10 @@ int CmdLFSetConfig(const char *Cmd)
|
||||||
averaging = param_getchar(Cmd,cmdp+1) == '1';
|
averaging = param_getchar(Cmd,cmdp+1) == '1';
|
||||||
cmdp+=2;
|
cmdp+=2;
|
||||||
break;
|
break;
|
||||||
|
case 's':
|
||||||
|
samples_to_skip = param_get32ex(Cmd,cmdp+1,0,10);
|
||||||
|
cmdp+=2;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
errors = 1;
|
errors = 1;
|
||||||
|
@ -316,7 +322,7 @@ int CmdLFSetConfig(const char *Cmd)
|
||||||
if(bps >> 4) bps = 8;
|
if(bps >> 4) bps = 8;
|
||||||
|
|
||||||
sample_config config = {
|
sample_config config = {
|
||||||
decimation,bps,averaging,divisor,trigger_threshold
|
decimation,bps,averaging,divisor,trigger_threshold,samples_to_skip
|
||||||
};
|
};
|
||||||
//Averaging is a flag on high-bit of arg[1]
|
//Averaging is a flag on high-bit of arg[1]
|
||||||
UsbCommand c = {CMD_SET_LF_SAMPLING_CONFIG};
|
UsbCommand c = {CMD_SET_LF_SAMPLING_CONFIG};
|
||||||
|
|
|
@ -1161,6 +1161,119 @@ int CmdEM4x05WriteWord(const char *Cmd) {
|
||||||
return EM4x05WriteWord(addr, data, pwd, usePwd, swap, invert);
|
return EM4x05WriteWord(addr, data, pwd, usePwd, swap, invert);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int usage_lf_em_protect(void) {
|
||||||
|
PrintAndLog("Protect EM4x05. Tag must be on antenna. ");
|
||||||
|
PrintAndLog("");
|
||||||
|
PrintAndLog("Usage: lf em 4x05protect [h] d <data> p <pwd> [s] [i]");
|
||||||
|
PrintAndLog("Options:");
|
||||||
|
PrintAndLog(" h - this help");
|
||||||
|
PrintAndLog(" d <data> - data to write (hex)");
|
||||||
|
PrintAndLog(" p <pwd> - password (hex) (optional)");
|
||||||
|
PrintAndLog(" s - swap the data bit order before write");
|
||||||
|
PrintAndLog(" i - invert the data bits before write");
|
||||||
|
PrintAndLog("samples:");
|
||||||
|
PrintAndLog(" lf em 4x05protect d 11223344");
|
||||||
|
PrintAndLog(" lf em 4x05protect p deadc0de d 11223344 s i");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int EM4x05Protect(uint32_t data, uint32_t pwd, bool usePwd, bool swap, bool invert) {
|
||||||
|
if (swap) data = SwapBits(data, 32);
|
||||||
|
|
||||||
|
if (invert) data ^= 0xFFFFFFFF;
|
||||||
|
|
||||||
|
if ( !usePwd ) {
|
||||||
|
PrintAndLog("Writing Protect data %08X", data);
|
||||||
|
} else {
|
||||||
|
PrintAndLog("Writing Protect data %08X using password %08X", data, pwd);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t flag = usePwd;
|
||||||
|
|
||||||
|
UsbCommand c = {CMD_EM4X_PROTECT, {flag, data, pwd}};
|
||||||
|
clearCommandBuffer();
|
||||||
|
SendCommand(&c);
|
||||||
|
UsbCommand resp;
|
||||||
|
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)){
|
||||||
|
PrintAndLog("Error occurred, device did not respond during protect operation.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if ( !downloadSamplesEM() ) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
//check response for 00001010 for write confirmation!
|
||||||
|
//attempt demod:
|
||||||
|
uint32_t dummy = 0;
|
||||||
|
int result = demodEM4x05resp(&dummy,false);
|
||||||
|
if (result == 1) {
|
||||||
|
PrintAndLog("Protect Verified");
|
||||||
|
} else {
|
||||||
|
PrintAndLog("Protect could not be verified");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CmdEM4x05ProtectWrite(const char *Cmd) {
|
||||||
|
bool errors = false;
|
||||||
|
bool usePwd = false;
|
||||||
|
uint32_t data = 0xFFFFFFFF;
|
||||||
|
uint32_t pwd = 0xFFFFFFFF;
|
||||||
|
bool swap = false;
|
||||||
|
bool invert = false;
|
||||||
|
bool gotData = false;
|
||||||
|
char cmdp = 0;
|
||||||
|
while(param_getchar(Cmd, cmdp) != 0x00)
|
||||||
|
{
|
||||||
|
switch(param_getchar(Cmd, cmdp))
|
||||||
|
{
|
||||||
|
case 'h':
|
||||||
|
case 'H':
|
||||||
|
return usage_lf_em_write();
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
data = param_get32ex(Cmd, cmdp+1, 0, 16);
|
||||||
|
gotData = true;
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
case 'I':
|
||||||
|
invert = true;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
case 'P':
|
||||||
|
pwd = param_get32ex(Cmd, cmdp+1, 1, 16);
|
||||||
|
if (pwd == 1) {
|
||||||
|
PrintAndLog("invalid pwd");
|
||||||
|
errors = true;
|
||||||
|
}
|
||||||
|
usePwd = true;
|
||||||
|
cmdp += 2;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
case 'S':
|
||||||
|
swap = true;
|
||||||
|
cmdp++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
|
errors = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(errors) break;
|
||||||
|
}
|
||||||
|
//Validations
|
||||||
|
if(errors) return usage_lf_em_protect();
|
||||||
|
|
||||||
|
if ( strlen(Cmd) == 0 ) return usage_lf_em_protect();
|
||||||
|
|
||||||
|
if (!gotData) {
|
||||||
|
PrintAndLog("You must enter the data you want to write");
|
||||||
|
return usage_lf_em_protect();
|
||||||
|
}
|
||||||
|
return EM4x05Protect(data, pwd, usePwd, swap, invert);
|
||||||
|
}
|
||||||
|
|
||||||
void printEM4x05config(uint32_t wordData) {
|
void printEM4x05config(uint32_t wordData) {
|
||||||
uint16_t datarate = EM4x05_GET_BITRATE(wordData);
|
uint16_t datarate = EM4x05_GET_BITRATE(wordData);
|
||||||
uint8_t encoder = ((wordData >> 6) & 0xF);
|
uint8_t encoder = ((wordData >> 6) & 0xF);
|
||||||
|
@ -1345,6 +1458,7 @@ static command_t CommandTable[] =
|
||||||
{"4x05info", CmdEM4x05info, 0, "(pwd) -- Get info from EM4x05/EM4x69 tag"},
|
{"4x05info", CmdEM4x05info, 0, "(pwd) -- Get info from EM4x05/EM4x69 tag"},
|
||||||
{"4x05readword", CmdEM4x05ReadWord, 0, "<Word> (pwd) -- Read EM4x05/EM4x69 word data"},
|
{"4x05readword", CmdEM4x05ReadWord, 0, "<Word> (pwd) -- Read EM4x05/EM4x69 word data"},
|
||||||
{"4x05writeword", CmdEM4x05WriteWord, 0, "<Word> <data> (pwd) -- Write EM4x05/EM4x69 word data"},
|
{"4x05writeword", CmdEM4x05WriteWord, 0, "<Word> <data> (pwd) -- Write EM4x05/EM4x69 word data"},
|
||||||
|
{"4x05protect", CmdEM4x05ProtectWrite, 0, "<data> (pwd) -- Write Protection to EM4x05"},
|
||||||
{"4x50read", CmdEM4x50Read, 1, "demod data from EM4x50 tag from the graph buffer"},
|
{"4x50read", CmdEM4x50Read, 1, "demod data from EM4x50 tag from the graph buffer"},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Copyright (C) 2012 Chalk <chalk.secu at gmail.com>
|
// Copyright (C) 2012 Chalk <chalk.secu at gmail.com>
|
||||||
// 2015 Dake <thomas.cayrou at gmail.com>
|
// 2015 Dake <thomas.cayrou at gmail.com>
|
||||||
// 2018 sguerrini97 <sguerrini97 at gmail.com>
|
// 2018 sguerrini97 <sguerrini97 at gmail.com>
|
||||||
|
|
||||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
// 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
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
@ -33,7 +33,7 @@ static int CmdHelp(const char *Cmd);
|
||||||
struct pcf7931_config configPcf = {
|
struct pcf7931_config configPcf = {
|
||||||
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
|
{0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},
|
||||||
PCF7931_DEFAULT_INITDELAY,
|
PCF7931_DEFAULT_INITDELAY,
|
||||||
PCF7931_DEFAULT_OFFSET_WIDTH,
|
PCF7931_DEFAULT_OFFSET_WIDTH,
|
||||||
PCF7931_DEFAULT_OFFSET_POSITION
|
PCF7931_DEFAULT_OFFSET_POSITION
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -41,8 +41,8 @@ struct pcf7931_config configPcf = {
|
||||||
int pcf7931_resetConfig(){
|
int pcf7931_resetConfig(){
|
||||||
memset(configPcf.Pwd, 0xFF, sizeof(configPcf.Pwd) );
|
memset(configPcf.Pwd, 0xFF, sizeof(configPcf.Pwd) );
|
||||||
configPcf.InitDelay = PCF7931_DEFAULT_INITDELAY;
|
configPcf.InitDelay = PCF7931_DEFAULT_INITDELAY;
|
||||||
configPcf.OffsetWidth = PCF7931_DEFAULT_OFFSET_WIDTH;
|
configPcf.OffsetWidth = PCF7931_DEFAULT_OFFSET_WIDTH;
|
||||||
configPcf.OffsetPosition = PCF7931_DEFAULT_OFFSET_POSITION;
|
configPcf.OffsetPosition = PCF7931_DEFAULT_OFFSET_POSITION;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ int usage_pcf7931_config(){
|
||||||
PrintAndLog(" pwd Password, hex, 7bytes, LSB-order");
|
PrintAndLog(" pwd Password, hex, 7bytes, LSB-order");
|
||||||
PrintAndLog(" delay Tag initialization delay (in us) decimal");
|
PrintAndLog(" delay Tag initialization delay (in us) decimal");
|
||||||
PrintAndLog(" offset Low pulses width (in us) decimal");
|
PrintAndLog(" offset Low pulses width (in us) decimal");
|
||||||
PrintAndLog(" offset Low pulses position (in us) decimal");
|
PrintAndLog(" offset Low pulses position (in us) decimal");
|
||||||
PrintAndLog("Examples:");
|
PrintAndLog("Examples:");
|
||||||
PrintAndLog(" lf pcf7931 config");
|
PrintAndLog(" lf pcf7931 config");
|
||||||
PrintAndLog(" lf pcf7931 config r");
|
PrintAndLog(" lf pcf7931 config r");
|
||||||
|
@ -112,7 +112,7 @@ int usage_pcf7931_config(){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdLFPCF7931Read(const char *Cmd){
|
int CmdLFPCF7931Read(const char *Cmd){
|
||||||
|
|
||||||
uint8_t ctmp = param_getchar(Cmd, 0);
|
uint8_t ctmp = param_getchar(Cmd, 0);
|
||||||
if ( ctmp == 'H' || ctmp == 'h' ) return usage_pcf7931_read();
|
if ( ctmp == 'H' || ctmp == 'h' ) return usage_pcf7931_read();
|
||||||
|
@ -128,12 +128,12 @@ int CmdLFPCF7931Read(const char *Cmd){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CmdLFPCF7931Config(const char *Cmd){
|
int CmdLFPCF7931Config(const char *Cmd){
|
||||||
|
|
||||||
uint8_t ctmp = param_getchar(Cmd, 0);
|
uint8_t ctmp = param_getchar(Cmd, 0);
|
||||||
if ( ctmp == 0) return pcf7931_printConfig();
|
if ( ctmp == 0) return pcf7931_printConfig();
|
||||||
if ( ctmp == 'H' || ctmp == 'h' ) return usage_pcf7931_config();
|
if ( ctmp == 'H' || ctmp == 'h' ) return usage_pcf7931_config();
|
||||||
if ( ctmp == 'R' || ctmp == 'r' ) return pcf7931_resetConfig();
|
if ( ctmp == 'R' || ctmp == 'r' ) return pcf7931_resetConfig();
|
||||||
|
|
||||||
if ( param_gethex(Cmd, 0, configPcf.Pwd, 14) ) return usage_pcf7931_config();
|
if ( param_gethex(Cmd, 0, configPcf.Pwd, 14) ) return usage_pcf7931_config();
|
||||||
|
|
||||||
|
@ -148,17 +148,17 @@ int CmdLFPCF7931Config(const char *Cmd){
|
||||||
int CmdLFPCF7931Write(const char *Cmd){
|
int CmdLFPCF7931Write(const char *Cmd){
|
||||||
|
|
||||||
uint8_t ctmp = param_getchar(Cmd, 0);
|
uint8_t ctmp = param_getchar(Cmd, 0);
|
||||||
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_pcf7931_write();
|
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_pcf7931_write();
|
||||||
|
|
||||||
uint8_t block = 0, bytepos = 0, data = 0;
|
uint8_t block = 0, bytepos = 0, data = 0;
|
||||||
|
|
||||||
if ( param_getdec(Cmd, 0, &block) ) return usage_pcf7931_write();
|
if ( param_getdec(Cmd, 0, &block) ) return usage_pcf7931_write();
|
||||||
if ( param_getdec(Cmd, 1, &bytepos) ) return usage_pcf7931_write();
|
if ( param_getdec(Cmd, 1, &bytepos) ) return usage_pcf7931_write();
|
||||||
|
|
||||||
if ( (block > 7) || (bytepos > 15) ) return usage_pcf7931_write();
|
if ( (block > 7) || (bytepos > 15) ) return usage_pcf7931_write();
|
||||||
|
|
||||||
data = param_get8ex(Cmd, 2, 0, 16);
|
data = param_get8ex(Cmd, 2, 0, 16);
|
||||||
|
|
||||||
PrintAndLog("Writing block: %d", block);
|
PrintAndLog("Writing block: %d", block);
|
||||||
PrintAndLog(" pos: %d", bytepos);
|
PrintAndLog(" pos: %d", bytepos);
|
||||||
PrintAndLog(" data: 0x%02X", data);
|
PrintAndLog(" data: 0x%02X", data);
|
||||||
|
@ -178,27 +178,27 @@ int CmdLFPCF7931Write(const char *Cmd){
|
||||||
int CmdLFPCF7931BruteForce(const char *Cmd){
|
int CmdLFPCF7931BruteForce(const char *Cmd){
|
||||||
|
|
||||||
uint8_t ctmp = param_getchar(Cmd, 0);
|
uint8_t ctmp = param_getchar(Cmd, 0);
|
||||||
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_pcf7931_bruteforce();
|
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_pcf7931_bruteforce();
|
||||||
|
|
||||||
uint64_t start_password = 0;
|
uint8_t start_password[7] = {0};
|
||||||
uint8_t tries = 3;
|
uint8_t tries = 3;
|
||||||
|
|
||||||
if (param_gethex(Cmd, 0, (uint8_t*)(&start_password), 14)) return usage_pcf7931_bruteforce();
|
if (param_gethex(Cmd, 0, start_password, 14)) return usage_pcf7931_bruteforce();
|
||||||
if (param_getdec(Cmd, 1, &tries)) return usage_pcf7931_bruteforce();
|
if (param_getdec(Cmd, 1, &tries)) return usage_pcf7931_bruteforce();
|
||||||
|
|
||||||
PrintAndLog("Bruteforcing from password: %02x %02x %02x %02x %02x %02x %02x",
|
PrintAndLog("Bruteforcing from password: %02x %02x %02x %02x %02x %02x %02x",
|
||||||
start_password & 0xFF,
|
start_password[0],
|
||||||
(start_password >> 8) & 0xFF,
|
start_password[1],
|
||||||
(start_password >> 16) & 0xFF,
|
start_password[2],
|
||||||
(start_password >> 24) & 0xFF,
|
start_password[3],
|
||||||
(start_password >> 32) & 0xFF,
|
start_password[4],
|
||||||
(start_password >> 48) & 0xFF,
|
start_password[5],
|
||||||
(start_password >> 56) & 0xFF);
|
start_password[6]);
|
||||||
|
|
||||||
PrintAndLog("Trying each password %d times", tries);
|
PrintAndLog("Trying each password %d times", tries);
|
||||||
|
|
||||||
UsbCommand c = {CMD_PCF7931_BRUTEFORCE, {start_password, tries} };
|
UsbCommand c = {CMD_PCF7931_BRUTEFORCE, {bytes_to_num(start_password, 7), tries} };
|
||||||
|
|
||||||
c.d.asDwords[7] = (configPcf.OffsetWidth + 128);
|
c.d.asDwords[7] = (configPcf.OffsetWidth + 128);
|
||||||
c.d.asDwords[8] = (configPcf.OffsetPosition + 128);
|
c.d.asDwords[8] = (configPcf.OffsetPosition + 128);
|
||||||
c.d.asDwords[9] = configPcf.InitDelay;
|
c.d.asDwords[9] = configPcf.InitDelay;
|
||||||
|
@ -209,7 +209,7 @@ int CmdLFPCF7931BruteForce(const char *Cmd){
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static command_t CommandTable[] =
|
static command_t CommandTable[] =
|
||||||
{
|
{
|
||||||
{"help", CmdHelp, 1, "This help"},
|
{"help", CmdHelp, 1, "This help"},
|
||||||
{"read", CmdLFPCF7931Read, 0, "Read content of a PCF7931 transponder"},
|
{"read", CmdLFPCF7931Read, 0, "Read content of a PCF7931 transponder"},
|
||||||
|
|
|
@ -67,6 +67,8 @@ int usage_t55xx_read(){
|
||||||
PrintAndLog(" p <password> - OPTIONAL password (8 hex characters)");
|
PrintAndLog(" p <password> - OPTIONAL password (8 hex characters)");
|
||||||
PrintAndLog(" o - OPTIONAL override safety check");
|
PrintAndLog(" o - OPTIONAL override safety check");
|
||||||
PrintAndLog(" 1 - OPTIONAL read Page 1 instead of Page 0");
|
PrintAndLog(" 1 - OPTIONAL read Page 1 instead of Page 0");
|
||||||
|
PrintAndLog(" r <mode> - OPTIONAL downlink encoding '0' fixed bit length (default), '1' long leading reference");
|
||||||
|
PrintAndLog(" '2' leading zero, '3' 1 of 4 coding reference");
|
||||||
PrintAndLog(" ****WARNING****");
|
PrintAndLog(" ****WARNING****");
|
||||||
PrintAndLog(" Use of read with password on a tag not configured for a pwd");
|
PrintAndLog(" Use of read with password on a tag not configured for a pwd");
|
||||||
PrintAndLog(" can damage the tag");
|
PrintAndLog(" can damage the tag");
|
||||||
|
@ -86,6 +88,8 @@ int usage_t55xx_write(){
|
||||||
PrintAndLog(" p <password> - OPTIONAL password 4bytes (8 hex characters)");
|
PrintAndLog(" p <password> - OPTIONAL password 4bytes (8 hex characters)");
|
||||||
PrintAndLog(" 1 - OPTIONAL write Page 1 instead of Page 0");
|
PrintAndLog(" 1 - OPTIONAL write Page 1 instead of Page 0");
|
||||||
PrintAndLog(" t - OPTIONAL test mode write - ****DANGER****");
|
PrintAndLog(" t - OPTIONAL test mode write - ****DANGER****");
|
||||||
|
PrintAndLog(" r <mode> - OPTIONAL downlink encoding '0' fixed bit length (default), '1' long leading reference");
|
||||||
|
PrintAndLog(" '2' leading zero, '3' 1 of 4 coding reference");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
PrintAndLog("Examples:");
|
PrintAndLog("Examples:");
|
||||||
PrintAndLog(" lf t55xx write b 3 d 11223344 - write 11223344 to block 3");
|
PrintAndLog(" lf t55xx write b 3 d 11223344 - write 11223344 to block 3");
|
||||||
|
@ -132,6 +136,8 @@ int usage_t55xx_detect(){
|
||||||
PrintAndLog("Options:");
|
PrintAndLog("Options:");
|
||||||
PrintAndLog(" 1 - if set, use Graphbuffer otherwise read data from tag.");
|
PrintAndLog(" 1 - if set, use Graphbuffer otherwise read data from tag.");
|
||||||
PrintAndLog(" p <password> - OPTIONAL password (8 hex characters)");
|
PrintAndLog(" p <password> - OPTIONAL password (8 hex characters)");
|
||||||
|
PrintAndLog(" r <mode> - OPTIONAL downlink encoding '0' fixed bit length (default), '1' long leading reference");
|
||||||
|
PrintAndLog(" '2' leading zero, '3' 1 of 4 coding reference");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
PrintAndLog("Examples:");
|
PrintAndLog("Examples:");
|
||||||
PrintAndLog(" lf t55xx detect");
|
PrintAndLog(" lf t55xx detect");
|
||||||
|
@ -162,7 +168,7 @@ int usage_t55xx_wakup(){
|
||||||
PrintAndLog(" <password> - [required] password 4bytes (8 hex symbols)");
|
PrintAndLog(" <password> - [required] password 4bytes (8 hex symbols)");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
PrintAndLog("Examples:");
|
PrintAndLog("Examples:");
|
||||||
PrintAndLog(" lf t55xx wakeup 11223344 - send wakeup password");
|
PrintAndLog(" lf t55xx wakeup 11223344 - send wakeup password");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int usage_t55xx_bruteforce(){
|
int usage_t55xx_bruteforce(){
|
||||||
|
@ -172,13 +178,16 @@ int usage_t55xx_bruteforce(){
|
||||||
PrintAndLog(" password must be 4 bytes (8 hex symbols)");
|
PrintAndLog(" password must be 4 bytes (8 hex symbols)");
|
||||||
PrintAndLog("Options:");
|
PrintAndLog("Options:");
|
||||||
PrintAndLog(" h - this help");
|
PrintAndLog(" h - this help");
|
||||||
|
PrintAndLog(" r <mode> - OPTIONAL downlink encoding '0' fixed bit length (default)");
|
||||||
|
PrintAndLog(" '1' long leading reference, '2' leading zero ");
|
||||||
|
PrintAndLog(" '3' 1 of 4 coding reference, '4' special - try all downlink modes");
|
||||||
PrintAndLog(" <start_pwd> - 4 byte hex value to start pwd search at");
|
PrintAndLog(" <start_pwd> - 4 byte hex value to start pwd search at");
|
||||||
PrintAndLog(" <end_pwd> - 4 byte hex value to end pwd search at");
|
PrintAndLog(" <end_pwd> - 4 byte hex value to end pwd search at");
|
||||||
PrintAndLog(" i <*.dic> - loads a default keys dictionary file <*.dic>");
|
PrintAndLog(" i <*.dic> - loads a default keys dictionary file <*.dic>");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
PrintAndLog("Examples:");
|
PrintAndLog("Examples:");
|
||||||
PrintAndLog(" lf t55xx bruteforce aaaaaaaa bbbbbbbb");
|
PrintAndLog(" lf t55xx bruteforce [r 2] aaaaaaaa bbbbbbbb");
|
||||||
PrintAndLog(" lf t55xx bruteforce i default_pwd.dic");
|
PrintAndLog(" lf t55xx bruteforce [r 2] i default_pwd.dic");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -302,21 +311,21 @@ int CmdT55xxSetConfig(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// No args
|
// No args
|
||||||
if (cmdp == 0) return printConfiguration( config );
|
if (cmdp == 0) return printConfiguration( config);
|
||||||
|
|
||||||
//Validations
|
//Validations
|
||||||
if (errors) return usage_t55xx_config();
|
if (errors) return usage_t55xx_config();
|
||||||
|
|
||||||
config.block0 = 0;
|
config.block0 = 0;
|
||||||
return printConfiguration ( config );
|
return printConfiguration ( config);
|
||||||
}
|
}
|
||||||
|
|
||||||
int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32_t password){
|
int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32_t password, uint8_t downlink_mode){
|
||||||
//Password mode
|
//Password mode
|
||||||
if ( usepwd ) {
|
if ( usepwd ) {
|
||||||
// try reading the config block and verify that PWD bit is set before doing this!
|
// try reading the config block and verify that PWD bit is set before doing this!
|
||||||
if ( !override ) {
|
if ( !override ) {
|
||||||
if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0 ) ) return 0;
|
if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, false, 0,downlink_mode ) ) return 0;
|
||||||
if ( !tryDetectModulation() ) {
|
if ( !tryDetectModulation() ) {
|
||||||
PrintAndLog("Safety Check: Could not detect if PWD bit is set in config block. Exits.");
|
PrintAndLog("Safety Check: Could not detect if PWD bit is set in config block. Exits.");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -330,7 +339,7 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!AquireData(page1, block, usepwd, password) ) return 0;
|
if (!AquireData(page1, block, usepwd, password,downlink_mode) ) return 0;
|
||||||
if (!DecodeT55xxBlock()) return 0;
|
if (!DecodeT55xxBlock()) return 0;
|
||||||
|
|
||||||
char blk[10]={0};
|
char blk[10]={0};
|
||||||
|
@ -342,6 +351,8 @@ int T55xxReadBlock(uint8_t block, bool page1, bool usepwd, bool override, uint32
|
||||||
int CmdT55xxReadBlock(const char *Cmd) {
|
int CmdT55xxReadBlock(const char *Cmd) {
|
||||||
uint8_t block = REGULAR_READ_MODE_BLOCK;
|
uint8_t block = REGULAR_READ_MODE_BLOCK;
|
||||||
uint32_t password = 0; //default to blank Block 7
|
uint32_t password = 0; //default to blank Block 7
|
||||||
|
uint8_t downlink_mode = 0;
|
||||||
|
|
||||||
bool usepwd = false;
|
bool usepwd = false;
|
||||||
bool override = false;
|
bool override = false;
|
||||||
bool page1 = false;
|
bool page1 = false;
|
||||||
|
@ -372,6 +383,12 @@ int CmdT55xxReadBlock(const char *Cmd) {
|
||||||
page1 = true;
|
page1 = true;
|
||||||
cmdp++;
|
cmdp++;
|
||||||
break;
|
break;
|
||||||
|
case 'r':
|
||||||
|
case 'R':
|
||||||
|
downlink_mode = param_getchar(Cmd, cmdp+1) - '0';
|
||||||
|
if (downlink_mode > 3) downlink_mode = 0;
|
||||||
|
cmdp +=2;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
errors = true;
|
errors = true;
|
||||||
|
@ -386,7 +403,7 @@ int CmdT55xxReadBlock(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
printT5xxHeader(page1);
|
printT5xxHeader(page1);
|
||||||
return T55xxReadBlock(block, page1, usepwd, override, password);
|
return T55xxReadBlock(block, page1, usepwd, override, password, downlink_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DecodeT55xxBlock(){
|
bool DecodeT55xxBlock(){
|
||||||
|
@ -459,12 +476,32 @@ bool DecodeT5555TraceBlock() {
|
||||||
return (bool) ASKDemod("64 0 1", false, false, 1);
|
return (bool) ASKDemod("64 0 1", false, false, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void T55xx_Print_DownlinkMode (uint8_t downlink_mode)
|
||||||
|
{
|
||||||
|
char Msg[80];
|
||||||
|
sprintf (Msg,"Downlink Mode used : ");
|
||||||
|
|
||||||
|
switch (downlink_mode) {
|
||||||
|
case 0 : strcat (Msg,"default/fixed bit length"); break;
|
||||||
|
case 1 : strcat (Msg,"long leading reference (r 1)"); break;
|
||||||
|
case 2 : strcat (Msg,"leading zero reference (r 2)"); break;
|
||||||
|
case 3 : strcat (Msg,"1 of 4 coding reference (r 3)"); break;
|
||||||
|
default :
|
||||||
|
strcat (Msg,"default/fixed bit length"); break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
PrintAndLog (Msg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
int CmdT55xxDetect(const char *Cmd){
|
int CmdT55xxDetect(const char *Cmd){
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
bool useGB = false;
|
bool useGB = false;
|
||||||
bool usepwd = false;
|
bool usepwd = false;
|
||||||
uint32_t password = 0;
|
uint32_t password = 0;
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
|
uint8_t downlink_mode = 0;
|
||||||
|
|
||||||
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
switch(param_getchar(Cmd, cmdp)) {
|
switch(param_getchar(Cmd, cmdp)) {
|
||||||
|
@ -482,6 +519,12 @@ int CmdT55xxDetect(const char *Cmd){
|
||||||
useGB = true;
|
useGB = true;
|
||||||
cmdp++;
|
cmdp++;
|
||||||
break;
|
break;
|
||||||
|
case 'r':
|
||||||
|
case 'R':
|
||||||
|
downlink_mode = param_getchar(Cmd, cmdp+1) - '0';
|
||||||
|
if (downlink_mode > 3) downlink_mode = 0;
|
||||||
|
cmdp +=2;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
errors = true;
|
errors = true;
|
||||||
|
@ -491,13 +534,16 @@ int CmdT55xxDetect(const char *Cmd){
|
||||||
if (errors) return usage_t55xx_detect();
|
if (errors) return usage_t55xx_detect();
|
||||||
|
|
||||||
if ( !useGB) {
|
if ( !useGB) {
|
||||||
if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password) )
|
if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, usepwd, password,downlink_mode) )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !tryDetectModulation() )
|
if ( !tryDetectModulation() )
|
||||||
PrintAndLog("Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'");
|
PrintAndLog("Could not detect modulation automatically. Try setting it manually with \'lf t55xx config\'");
|
||||||
|
else {
|
||||||
|
// Add downlink mode for reference.
|
||||||
|
T55xx_Print_DownlinkMode (downlink_mode);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -649,7 +695,8 @@ bool tryDetectModulation(){
|
||||||
config.block0 = tests[0].block0;
|
config.block0 = tests[0].block0;
|
||||||
config.Q5 = tests[0].Q5;
|
config.Q5 = tests[0].Q5;
|
||||||
config.ST = tests[0].ST;
|
config.ST = tests[0].ST;
|
||||||
printConfiguration( config );
|
|
||||||
|
printConfiguration( config);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,7 +704,7 @@ bool tryDetectModulation(){
|
||||||
PrintAndLog("Found [%d] possible matches for modulation.",hits);
|
PrintAndLog("Found [%d] possible matches for modulation.",hits);
|
||||||
for(int i=0; i<hits; ++i){
|
for(int i=0; i<hits; ++i){
|
||||||
PrintAndLog("--[%d]---------------", i+1);
|
PrintAndLog("--[%d]---------------", i+1);
|
||||||
printConfiguration( tests[i] );
|
printConfiguration( tests[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -898,6 +945,8 @@ int CmdT55xxWriteBlock(const char *Cmd) {
|
||||||
uint8_t block = 0xFF; //default to invalid block
|
uint8_t block = 0xFF; //default to invalid block
|
||||||
uint32_t data = 0; //default to blank Block
|
uint32_t data = 0; //default to blank Block
|
||||||
uint32_t password = 0; //default to blank Block 7
|
uint32_t password = 0; //default to blank Block 7
|
||||||
|
uint32_t downlink_mode = 0;
|
||||||
|
|
||||||
bool usepwd = false;
|
bool usepwd = false;
|
||||||
bool page1 = false;
|
bool page1 = false;
|
||||||
bool gotdata = false;
|
bool gotdata = false;
|
||||||
|
@ -935,6 +984,12 @@ int CmdT55xxWriteBlock(const char *Cmd) {
|
||||||
page1 = true;
|
page1 = true;
|
||||||
cmdp++;
|
cmdp++;
|
||||||
break;
|
break;
|
||||||
|
case 'r':
|
||||||
|
case 'R':
|
||||||
|
downlink_mode = param_getchar(Cmd, cmdp+1) - '0';
|
||||||
|
if (downlink_mode > 3) downlink_mode = 0;
|
||||||
|
cmdp +=2;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||||
errors = true;
|
errors = true;
|
||||||
|
@ -952,17 +1007,19 @@ int CmdT55xxWriteBlock(const char *Cmd) {
|
||||||
UsbCommand resp;
|
UsbCommand resp;
|
||||||
c.d.asBytes[0] = (page1) ? 0x2 : 0;
|
c.d.asBytes[0] = (page1) ? 0x2 : 0;
|
||||||
c.d.asBytes[0] |= (testMode) ? 0x4 : 0;
|
c.d.asBytes[0] |= (testMode) ? 0x4 : 0;
|
||||||
|
c.d.asBytes[0] |= (downlink_mode << 3);
|
||||||
|
|
||||||
char pwdStr[16] = {0};
|
char pwdStr[16] = {0};
|
||||||
snprintf(pwdStr, sizeof(pwdStr), "pwd: 0x%08X", password);
|
snprintf(pwdStr, sizeof(pwdStr), "pwd: 0x%08X", password);
|
||||||
|
|
||||||
PrintAndLog("Writing page %d block: %02d data: 0x%08X %s", page1, block, data, (usepwd) ? pwdStr : "" );
|
PrintAndLog("Writing page %d block: %02d data: 0x%08X %s", page1, block, data, (usepwd) ? pwdStr : "" );
|
||||||
|
|
||||||
//Password mode
|
//Password mode
|
||||||
if (usepwd) {
|
if (usepwd) {
|
||||||
c.arg[2] = password;
|
c.arg[2] = password;
|
||||||
c.d.asBytes[0] |= 0x1;
|
c.d.asBytes[0] |= 0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){
|
if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){
|
||||||
|
@ -980,7 +1037,7 @@ int CmdT55xxReadTrace(const char *Cmd) {
|
||||||
return usage_t55xx_trace();
|
return usage_t55xx_trace();
|
||||||
|
|
||||||
if (strlen(Cmd)==0)
|
if (strlen(Cmd)==0)
|
||||||
if ( !AquireData( T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password ) )
|
if ( !AquireData( T55x7_PAGE1, REGULAR_READ_MODE_BLOCK, pwdmode, password,0 ) )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if ( config.Q5 ) {
|
if ( config.Q5 ) {
|
||||||
|
@ -1144,7 +1201,7 @@ int CmdT55xxInfo(const char *Cmd){
|
||||||
return usage_t55xx_info();
|
return usage_t55xx_info();
|
||||||
|
|
||||||
if (strlen(Cmd)==0)
|
if (strlen(Cmd)==0)
|
||||||
if ( !AquireData( T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, pwdmode, password ) )
|
if ( !AquireData( T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, pwdmode, password,0 ) )
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!DecodeT55xxBlock()) return 1;
|
if (!DecodeT55xxBlock()) return 1;
|
||||||
|
@ -1212,20 +1269,21 @@ int CmdT55xxDump(const char *Cmd){
|
||||||
|
|
||||||
printT5xxHeader(0);
|
printT5xxHeader(0);
|
||||||
for ( uint8_t i = 0; i <8; ++i)
|
for ( uint8_t i = 0; i <8; ++i)
|
||||||
T55xxReadBlock(i, 0, usepwd, override, password);
|
T55xxReadBlock(i, 0, usepwd, override, password,0);
|
||||||
|
|
||||||
printT5xxHeader(1);
|
printT5xxHeader(1);
|
||||||
for ( uint8_t i = 0; i<4; i++)
|
for ( uint8_t i = 0; i<4; i++)
|
||||||
T55xxReadBlock(i, 1, usepwd, override, password);
|
T55xxReadBlock(i, 1, usepwd, override, password,0);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ){
|
int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password, uint8_t downlink_mode ){
|
||||||
// arg0 bitmodes:
|
// arg0 bitmodes:
|
||||||
// bit0 = pwdmode
|
// bit0 = pwdmode
|
||||||
// bit1 = page to read from
|
// bit1 = page to read from
|
||||||
uint8_t arg0 = (page<<1) | pwdmode;
|
uint8_t arg0 = (page<<1) | pwdmode;
|
||||||
|
arg0 |= (downlink_mode << 3);
|
||||||
UsbCommand c = {CMD_T55XX_READ_BLOCK, {arg0, block, password}};
|
UsbCommand c = {CMD_T55XX_READ_BLOCK, {arg0, block, password}};
|
||||||
|
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
|
@ -1403,9 +1461,23 @@ int CmdT55xxBruteForce(const char *Cmd) {
|
||||||
uint32_t start_password = 0x00000000; //start password
|
uint32_t start_password = 0x00000000; //start password
|
||||||
uint32_t end_password = 0xFFFFFFFF; //end password
|
uint32_t end_password = 0xFFFFFFFF; //end password
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
uint8_t downlink_mode = 0;
|
||||||
|
bool try_all_dl_modes = false;
|
||||||
|
uint8_t dl_mode = 0;
|
||||||
|
uint8_t cmd_offset = 0;
|
||||||
|
int cmd_opt = 0;
|
||||||
|
|
||||||
char cmdp = param_getchar(Cmd, 0);
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
|
||||||
if (cmdp == 'h' || cmdp == 'H') return usage_t55xx_bruteforce();
|
if (cmdp == 'h' || cmdp == 'H') return usage_t55xx_bruteforce();
|
||||||
|
if (cmdp == 'r' || cmdp == 'R') {
|
||||||
|
downlink_mode = param_getchar(Cmd, 1) - '0'; // get 2nd option, as this is fixed order.
|
||||||
|
if (downlink_mode == 4) try_all_dl_modes = true;
|
||||||
|
if (downlink_mode > 3) downlink_mode = 0;
|
||||||
|
cmd_opt += 2; // To help start/end passwords for range to be found
|
||||||
|
cmd_offset += 4; // r <sp> x <sp> To help the string offset for filename start position in cmd
|
||||||
|
cmdp = param_getchar(Cmd, 2); // get 3rd option, as this is fixed order.
|
||||||
|
}
|
||||||
|
|
||||||
keyBlock = calloc(stKeyBlock, 6);
|
keyBlock = calloc(stKeyBlock, 6);
|
||||||
if (keyBlock == NULL) return 1;
|
if (keyBlock == NULL) return 1;
|
||||||
|
@ -1414,7 +1486,7 @@ int CmdT55xxBruteForce(const char *Cmd) {
|
||||||
|
|
||||||
int len = strlen(Cmd+2);
|
int len = strlen(Cmd+2);
|
||||||
if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
|
if (len > FILE_PATH_SIZE) len = FILE_PATH_SIZE;
|
||||||
memcpy(filename, Cmd+2, len);
|
memcpy(filename, Cmd+2+cmd_offset, len);
|
||||||
|
|
||||||
FILE * f = fopen( filename , "r");
|
FILE * f = fopen( filename , "r");
|
||||||
|
|
||||||
|
@ -1479,20 +1551,29 @@ int CmdT55xxBruteForce(const char *Cmd) {
|
||||||
testpwd = bytes_to_num(keyBlock + 4*c, 4);
|
testpwd = bytes_to_num(keyBlock + 4*c, 4);
|
||||||
|
|
||||||
PrintAndLog("Testing %08X", testpwd);
|
PrintAndLog("Testing %08X", testpwd);
|
||||||
|
|
||||||
|
// Try each downlink_mode if asked to
|
||||||
|
// donwlink_mode will = 0 if > 3 or set to 0, so loop from 0 - 3
|
||||||
|
for (dl_mode = downlink_mode; dl_mode <= 3; dl_mode++){
|
||||||
|
if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, testpwd, dl_mode)) {
|
||||||
|
PrintAndLog("Acquiring data from device failed. Quitting");
|
||||||
|
free(keyBlock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if ( !AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, testpwd)) {
|
found = tryDetectModulation();
|
||||||
PrintAndLog("Aquireing data from device failed. Quitting");
|
|
||||||
free(keyBlock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
found = tryDetectModulation();
|
if ( found ) {
|
||||||
|
PrintAndLog("Found valid password: [%08X]", testpwd);
|
||||||
|
free(keyBlock);
|
||||||
|
|
||||||
|
T55xx_Print_DownlinkMode (dl_mode);
|
||||||
|
|
||||||
if ( found ) {
|
return 0;
|
||||||
PrintAndLog("Found valid password: [%08X]", testpwd);
|
}
|
||||||
free(keyBlock);
|
if (!try_all_dl_modes) // Exit loop if not trying all downlink modes
|
||||||
return 0;
|
dl_mode = 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PrintAndLog("Password NOT found.");
|
PrintAndLog("Password NOT found.");
|
||||||
free(keyBlock);
|
free(keyBlock);
|
||||||
|
@ -1502,8 +1583,8 @@ int CmdT55xxBruteForce(const char *Cmd) {
|
||||||
// Try to read Block 7, first :)
|
// Try to read Block 7, first :)
|
||||||
|
|
||||||
// incremental pwd range search
|
// incremental pwd range search
|
||||||
start_password = param_get32ex(Cmd, 0, 0, 16);
|
start_password = param_get32ex(Cmd, cmd_opt , 0, 16);
|
||||||
end_password = param_get32ex(Cmd, 1, 0, 16);
|
end_password = param_get32ex(Cmd, cmd_opt+1 , 0, 16);
|
||||||
|
|
||||||
if ( start_password >= end_password ) {
|
if ( start_password >= end_password ) {
|
||||||
free(keyBlock);
|
free(keyBlock);
|
||||||
|
@ -1524,29 +1605,36 @@ int CmdT55xxBruteForce(const char *Cmd) {
|
||||||
free(keyBlock);
|
free(keyBlock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
// Try each downlink_mode if asked to
|
||||||
|
// donwlink_mode will = 0 if > 3 or set to 0, so loop from 0 - 3
|
||||||
|
for (dl_mode = downlink_mode; dl_mode <= 3; dl_mode++){
|
||||||
|
if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, i,dl_mode)) {
|
||||||
|
PrintAndLog("Acquiring data from device failed. Quitting");
|
||||||
|
free(keyBlock);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
found = tryDetectModulation();
|
||||||
|
|
||||||
if (!AquireData(T55x7_PAGE0, T55x7_CONFIGURATION_BLOCK, true, i)) {
|
if (found) break;
|
||||||
PrintAndLog("Aquireing data from device failed. Quitting");
|
if (!try_all_dl_modes) // Exit loop if not trying all downlink modes
|
||||||
free(keyBlock);
|
dl_mode = 4;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
found = tryDetectModulation();
|
|
||||||
|
|
||||||
if (found) break;
|
if (found) break;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLog("");
|
if (found){
|
||||||
|
|
||||||
if (found)
|
|
||||||
PrintAndLog("Found valid password: [%08x]", i);
|
PrintAndLog("Found valid password: [%08x]", i);
|
||||||
else
|
T55xx_Print_DownlinkMode (downlink_mode);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
PrintAndLog("");
|
||||||
PrintAndLog("Password NOT found. Last tried: [%08x]", --i);
|
PrintAndLog("Password NOT found. Last tried: [%08x]", --i);
|
||||||
|
}
|
||||||
|
|
||||||
free(keyBlock);
|
free(keyBlock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// note length of data returned is different for different chips.
|
// 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)
|
// 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...
|
// unfortunately the 64 bits makes this more likely to get a false positive...
|
||||||
|
@ -1558,7 +1646,7 @@ bool tryDetectP1(bool getData) {
|
||||||
bool st = true;
|
bool st = true;
|
||||||
|
|
||||||
if ( getData ) {
|
if ( getData ) {
|
||||||
if ( !AquireData(T55x7_PAGE1, 1, false, 0) )
|
if ( !AquireData(T55x7_PAGE1, 1, false, 0,0) )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1687,7 +1775,7 @@ int CmdT55xxDetectPage1(const char *Cmd){
|
||||||
if (errors) return usage_t55xx_detectP1();
|
if (errors) return usage_t55xx_detectP1();
|
||||||
|
|
||||||
if ( !useGB ) {
|
if ( !useGB ) {
|
||||||
if ( !AquireData(T55x7_PAGE1, 1, usepwd, password) )
|
if ( !AquireData(T55x7_PAGE1, 1, usepwd, password,0) )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool success = tryDetectP1(false);
|
bool success = tryDetectP1(false);
|
||||||
|
@ -1697,7 +1785,7 @@ int CmdT55xxDetectPage1(const char *Cmd){
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
{"help", CmdHelp, 1, "This help"},
|
{"help", CmdHelp, 1, "This help"},
|
||||||
{"bruteforce",CmdT55xxBruteForce,0, "<start password> <end password> [i <*.dic>] Simple bruteforce attack to find password"},
|
{"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)"},
|
{"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."},
|
{"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"},
|
{"p1detect", CmdT55xxDetectPage1,1, "[1] Try detecting if this is a t55xx tag by reading page 1"},
|
||||||
|
|
|
@ -98,7 +98,7 @@ bool tryDetectModulation(void);
|
||||||
extern bool tryDetectP1(bool getData);
|
extern bool tryDetectP1(bool getData);
|
||||||
bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5);
|
bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5);
|
||||||
int special(const char *Cmd);
|
int special(const char *Cmd);
|
||||||
int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password );
|
int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password,uint8_t downlink_mode );
|
||||||
|
|
||||||
void printT55x7Trace( t55x7_tracedata_t data, uint8_t repeat );
|
void printT55x7Trace( t55x7_tracedata_t data, uint8_t repeat );
|
||||||
void printT5555Trace( t5555_tracedata_t data, uint8_t repeat );
|
void printT5555Trace( t5555_tracedata_t data, uint8_t repeat );
|
||||||
|
|
|
@ -34,8 +34,8 @@ extern "C" {
|
||||||
|
|
||||||
bool g_useOverlays = false;
|
bool g_useOverlays = false;
|
||||||
int g_absVMax = 0;
|
int g_absVMax = 0;
|
||||||
int startMax;
|
int startMax; // Maximum offset in the graph (right side of graph)
|
||||||
int PageWidth;
|
int PageWidth; // How many samples are currently visible on this 'page' / graph
|
||||||
int unlockStart = 0;
|
int unlockStart = 0;
|
||||||
|
|
||||||
void ProxGuiQT::ShowGraphWindow(void)
|
void ProxGuiQT::ShowGraphWindow(void)
|
||||||
|
@ -134,8 +134,8 @@ ProxGuiQT::~ProxGuiQT(void)
|
||||||
{
|
{
|
||||||
//if (plotwidget) {
|
//if (plotwidget) {
|
||||||
//plotwidget->destroy(true,true);
|
//plotwidget->destroy(true,true);
|
||||||
// delete plotwidget;
|
// delete plotwidget;
|
||||||
// plotwidget = NULL;
|
// plotwidget = NULL;
|
||||||
//}
|
//}
|
||||||
if (plotapp) {
|
if (plotapp) {
|
||||||
plotapp->quit();
|
plotapp->quit();
|
||||||
|
@ -474,7 +474,7 @@ void Plot::plotGridLines(QPainter* painter,QRect r)
|
||||||
if ((PlotGridX > 0) && ((PlotGridX * GraphPixelsPerPoint) > 1)) {
|
if ((PlotGridX > 0) && ((PlotGridX * GraphPixelsPerPoint) > 1)) {
|
||||||
for(i = (offset * GraphPixelsPerPoint); i < r.right(); i += grid_delta_x) {
|
for(i = (offset * GraphPixelsPerPoint); i < r.right(); i += grid_delta_x) {
|
||||||
painter->drawLine(r.left()+i, r.top(), r.left()+i, r.bottom());
|
painter->drawLine(r.left()+i, r.top(), r.left()+i, r.bottom());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (PlotGridY > 0) {
|
if (PlotGridY > 0) {
|
||||||
for(i = 0; yCoordOf(i,r,g_absVMax) > r.top(); i += grid_delta_y) {
|
for(i = 0; yCoordOf(i,r,g_absVMax) > r.top(); i += grid_delta_y) {
|
||||||
|
@ -509,8 +509,9 @@ void Plot::paintEvent(QPaintEvent *event)
|
||||||
if(CursorDPos > GraphTraceLen)
|
if(CursorDPos > GraphTraceLen)
|
||||||
CursorDPos= 0;
|
CursorDPos= 0;
|
||||||
|
|
||||||
QRect plotRect(WIDTH_AXES, 0, width()-WIDTH_AXES, height()-HEIGHT_INFO);
|
QRect plotRect(WIDTH_AXES, 0, width() - WIDTH_AXES, height() - HEIGHT_INFO);
|
||||||
QRect infoRect(0, height()-HEIGHT_INFO, width(), HEIGHT_INFO);
|
QRect infoRect(0, height() - HEIGHT_INFO, width(), HEIGHT_INFO);
|
||||||
|
PageWidth = plotRect.width() / GraphPixelsPerPoint;
|
||||||
|
|
||||||
//Grey background
|
//Grey background
|
||||||
painter.fillRect(rect(), QColor(60, 60, 60));
|
painter.fillRect(rect(), QColor(60, 60, 60));
|
||||||
|
@ -529,7 +530,7 @@ void Plot::paintEvent(QPaintEvent *event)
|
||||||
|
|
||||||
//Start painting graph
|
//Start painting graph
|
||||||
PlotGraph(GraphBuffer, GraphTraceLen,plotRect,infoRect,&painter,0);
|
PlotGraph(GraphBuffer, GraphTraceLen,plotRect,infoRect,&painter,0);
|
||||||
if (showDemod && DemodBufferLen > 8) {
|
if (showDemod && DemodBufferLen > 8) {
|
||||||
PlotDemod(DemodBuffer, DemodBufferLen,plotRect,infoRect,&painter,2,g_DemodStartIdx);
|
PlotDemod(DemodBuffer, DemodBufferLen,plotRect,infoRect,&painter,2,g_DemodStartIdx);
|
||||||
}
|
}
|
||||||
if (g_useOverlays) {
|
if (g_useOverlays) {
|
||||||
|
@ -564,7 +565,7 @@ void Plot::paintEvent(QPaintEvent *event)
|
||||||
//Draw annotations
|
//Draw annotations
|
||||||
char str[200];
|
char str[200];
|
||||||
sprintf(str, "@%d dt=%d [%2.2f] zoom=%2.2f CursorAPos=%d CursorBPos=%d GridX=%d GridY=%d (%s) GridXoffset=%d",
|
sprintf(str, "@%d dt=%d [%2.2f] zoom=%2.2f CursorAPos=%d CursorBPos=%d GridX=%d GridY=%d (%s) GridXoffset=%d",
|
||||||
GraphStart, CursorBPos - CursorAPos, (CursorBPos - CursorAPos)/CursorScaleFactor,
|
GraphStart, CursorBPos - CursorAPos, (CursorBPos - CursorAPos)/CursorScaleFactor,
|
||||||
GraphPixelsPerPoint,CursorAPos,CursorBPos,PlotGridXdefault,PlotGridYdefault,GridLocked?"Locked":"Unlocked",GridOffset);
|
GraphPixelsPerPoint,CursorAPos,CursorBPos,PlotGridXdefault,PlotGridYdefault,GridLocked?"Locked":"Unlocked",GridOffset);
|
||||||
painter.setPen(QColor(255, 255, 255));
|
painter.setPen(QColor(255, 255, 255));
|
||||||
painter.drawText(20, infoRect.bottom() - 3, str);
|
painter.drawText(20, infoRect.bottom() - 3, str);
|
||||||
|
@ -616,14 +617,14 @@ void Plot::mouseMoveEvent(QMouseEvent *event)
|
||||||
|
|
||||||
void Plot::keyPressEvent(QKeyEvent *event)
|
void Plot::keyPressEvent(QKeyEvent *event)
|
||||||
{
|
{
|
||||||
int offset;
|
int offset; // Left/right movement offset (in sample size)
|
||||||
|
|
||||||
if(event->modifiers() & Qt::ShiftModifier) {
|
if(event->modifiers() & Qt::ShiftModifier) {
|
||||||
if (PlotGridX)
|
if (PlotGridX)
|
||||||
offset= PageWidth - (PageWidth % PlotGridX);
|
offset= PageWidth - (PageWidth % PlotGridX);
|
||||||
else
|
else
|
||||||
offset= PageWidth;
|
offset= PageWidth;
|
||||||
} else
|
} else
|
||||||
if(event->modifiers() & Qt::ControlModifier)
|
if(event->modifiers() & Qt::ControlModifier)
|
||||||
offset= 1;
|
offset= 1;
|
||||||
else
|
else
|
||||||
|
@ -671,20 +672,22 @@ void Plot::keyPressEvent(QKeyEvent *event)
|
||||||
case Qt::Key_H:
|
case Qt::Key_H:
|
||||||
puts("Plot Window Keystrokes:\n");
|
puts("Plot Window Keystrokes:\n");
|
||||||
puts(" Key Action\n");
|
puts(" Key Action\n");
|
||||||
|
puts(" UP Zoom out");
|
||||||
puts(" DOWN Zoom in");
|
puts(" DOWN Zoom in");
|
||||||
puts(" G Toggle grid display");
|
puts(" G Toggle grid display");
|
||||||
puts(" H Show help");
|
puts(" H Show help");
|
||||||
puts(" L Toggle lock grid relative to samples");
|
puts(" L Toggle lock grid relative to samples");
|
||||||
|
puts(" Q Hide window");
|
||||||
|
puts(" HOME Move to the start of the graph");
|
||||||
|
puts(" END Move to the end of the graph");
|
||||||
puts(" LEFT Move left");
|
puts(" LEFT Move left");
|
||||||
puts(" <CTL>LEFT Move left 1 sample");
|
puts(" <CTL>LEFT Move left 1 sample");
|
||||||
puts(" <SHIFT>LEFT Page left");
|
puts(" <SHIFT>LEFT Page left");
|
||||||
puts(" LEFT-MOUSE-CLICK Set yellow cursor");
|
puts(" LEFT-MOUSE-CLICK Set yellow cursor");
|
||||||
puts(" Q Hide window");
|
|
||||||
puts(" RIGHT Move right");
|
puts(" RIGHT Move right");
|
||||||
puts(" <CTL>RIGHT Move right 1 sample");
|
puts(" <CTL>RIGHT Move right 1 sample");
|
||||||
puts(" <SHIFT>RIGHT Page right");
|
puts(" <SHIFT>RIGHT Page right");
|
||||||
puts(" RIGHT-MOUSE-CLICK Set purple cursor");
|
puts(" RIGHT-MOUSE-CLICK Set purple cursor");
|
||||||
puts(" UP Zoom out");
|
|
||||||
puts("");
|
puts("");
|
||||||
puts("Use client window 'data help' for more plot commands\n");
|
puts("Use client window 'data help' for more plot commands\n");
|
||||||
break;
|
break;
|
||||||
|
@ -701,6 +704,14 @@ void Plot::keyPressEvent(QKeyEvent *event)
|
||||||
master->hide();
|
master->hide();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Qt::Key_Home:
|
||||||
|
GraphStart = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Qt::Key_End:
|
||||||
|
GraphStart = startMax;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
QWidget::keyPressEvent(event);
|
QWidget::keyPressEvent(event);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -29,8 +29,8 @@ class Plot: public QWidget
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
QWidget *master;
|
QWidget *master;
|
||||||
int GraphStart;
|
int GraphStart; // Starting point/offset for the left side of the graph
|
||||||
double GraphPixelsPerPoint;
|
double GraphPixelsPerPoint; // How many visual pixels are between each sample point (x axis)
|
||||||
int CursorAPos;
|
int CursorAPos;
|
||||||
int CursorBPos;
|
int CursorBPos;
|
||||||
void PlotGraph(int *buffer, int len, QRect r,QRect r2, QPainter* painter, int graphNum);
|
void PlotGraph(int *buffer, int len, QRect r,QRect r2, QPainter* painter, int graphNum);
|
||||||
|
@ -73,13 +73,13 @@ class ProxWidget : public QWidget
|
||||||
//OpsShow(void);
|
//OpsShow(void);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// void paintEvent(QPaintEvent *event);
|
// void paintEvent(QPaintEvent *event);
|
||||||
void closeEvent(QCloseEvent *event);
|
void closeEvent(QCloseEvent *event);
|
||||||
void showEvent(QShowEvent *event);
|
void showEvent(QShowEvent *event);
|
||||||
void hideEvent(QHideEvent *event);
|
void hideEvent(QHideEvent *event);
|
||||||
// void mouseMoveEvent(QMouseEvent *event);
|
// void mouseMoveEvent(QMouseEvent *event);
|
||||||
// void mousePressEvent(QMouseEvent *event) { mouseMoveEvent(event); }
|
// void mousePressEvent(QMouseEvent *event) { mouseMoveEvent(event); }
|
||||||
// void keyPressEvent(QKeyEvent *event);
|
// void keyPressEvent(QKeyEvent *event);
|
||||||
public slots:
|
public slots:
|
||||||
void applyOperation();
|
void applyOperation();
|
||||||
void stickOperation();
|
void stickOperation();
|
||||||
|
@ -111,7 +111,7 @@ class ProxGuiQT : public QObject
|
||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
char **argv;
|
||||||
WorkerThread *proxmarkThread;
|
WorkerThread *proxmarkThread;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ProxGuiQT(int argc, char **argv, WorkerThread *wthread);
|
ProxGuiQT(int argc, char **argv, WorkerThread *wthread);
|
||||||
~ProxGuiQT(void);
|
~ProxGuiQT(void);
|
||||||
|
|
|
@ -117,9 +117,8 @@ void AddLogCurrentDT(char *fileName) {
|
||||||
AddLogLine(fileName, "\nanticollision: ", buff);
|
AddLogLine(fileName, "\nanticollision: ", buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FillFileNameByUID(char *fileName, uint8_t * uid, char *ext, int byteCount) {
|
void FillFileNameByUID(char *fileName, uint8_t *uid, char *ext, int byteCount) {
|
||||||
char * fnameptr = fileName;
|
char * fnameptr = fileName;
|
||||||
memset(fileName, 0x00, 200);
|
|
||||||
|
|
||||||
for (int j = 0; j < byteCount; j++, fnameptr += 2)
|
for (int j = 0; j < byteCount; j++, fnameptr += 2)
|
||||||
sprintf(fnameptr, "%02x", (unsigned int) uid[j]);
|
sprintf(fnameptr, "%02x", (unsigned int) uid[j]);
|
||||||
|
@ -268,6 +267,10 @@ char *sprint_ascii_ex(const uint8_t *data, const size_t len, const size_t min_st
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *sprint_ascii(const uint8_t *data, const size_t len) {
|
||||||
|
return sprint_ascii_ex(data, len, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest)
|
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest)
|
||||||
{
|
{
|
||||||
while (len--) {
|
while (len--) {
|
||||||
|
@ -319,22 +322,21 @@ uint32_t SwapBits(uint32_t value, int nrbits) {
|
||||||
uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize){
|
uint8_t *SwapEndian64(const uint8_t *src, const size_t len, const uint8_t blockSize){
|
||||||
static uint8_t buf[64];
|
static uint8_t buf[64];
|
||||||
memset(buf, 0x00, 64);
|
memset(buf, 0x00, 64);
|
||||||
uint8_t *tmp = buf;
|
|
||||||
for (uint8_t block=0; block < (uint8_t)(len/blockSize); block++){
|
for (uint8_t block=0; block < (uint8_t)(len/blockSize); block++){
|
||||||
for (size_t i = 0; i < blockSize; i++){
|
for (size_t i = 0; i < blockSize; i++){
|
||||||
tmp[i+(blockSize*block)] = src[(blockSize-1-i)+(blockSize*block)];
|
buf[i+(blockSize*block)] = src[(blockSize-1-i)+(blockSize*block)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return tmp;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
//assumes little endian
|
//assumes little endian
|
||||||
char * printBits(size_t const size, void const * const ptr)
|
char *printBits(size_t const size, void const * const ptr)
|
||||||
{
|
{
|
||||||
unsigned char *b = (unsigned char*) ptr;
|
unsigned char *b = (unsigned char*) ptr;
|
||||||
unsigned char byte;
|
unsigned char byte;
|
||||||
static char buf[1024];
|
static char buf[1024];
|
||||||
char * tmp = buf;
|
char *tmp = buf;
|
||||||
int i, j;
|
int i, j;
|
||||||
|
|
||||||
for (i=size-1;i>=0;i--)
|
for (i=size-1;i>=0;i--)
|
||||||
|
@ -350,7 +352,7 @@ char * printBits(size_t const size, void const * const ptr)
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
char * printBitsPar(const uint8_t *b, size_t len) {
|
char *printBitsPar(const uint8_t *b, size_t len) {
|
||||||
static char buf1[512] = {0};
|
static char buf1[512] = {0};
|
||||||
static char buf2[512] = {0};
|
static char buf2[512] = {0};
|
||||||
static char *buf;
|
static char *buf;
|
||||||
|
@ -515,7 +517,8 @@ int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int param_gethex_ex(const char *line, int paramnum, uint8_t * data, int *hexcnt)
|
|
||||||
|
int param_gethex_ex(const char *line, int paramnum, uint8_t *data, int *hexcnt)
|
||||||
{
|
{
|
||||||
int bg, en, temp, i;
|
int bg, en, temp, i;
|
||||||
|
|
||||||
|
@ -524,6 +527,8 @@ int param_gethex_ex(const char *line, int paramnum, uint8_t * data, int *hexcnt)
|
||||||
|
|
||||||
if (param_getptr(line, &bg, &en, paramnum)) return 1;
|
if (param_getptr(line, &bg, &en, paramnum)) return 1;
|
||||||
|
|
||||||
|
if (en - bg + 1 > *hexcnt) return 1;
|
||||||
|
|
||||||
*hexcnt = en - bg + 1;
|
*hexcnt = en - bg + 1;
|
||||||
if (*hexcnt % 2) //error if not complete hex bytes
|
if (*hexcnt % 2) //error if not complete hex bytes
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -101,6 +101,7 @@ extern char *sprint_hex_inrow_ex(const uint8_t *data, const size_t len, const si
|
||||||
extern char *sprint_bin(const uint8_t * data, const size_t len);
|
extern char *sprint_bin(const uint8_t * data, const size_t len);
|
||||||
extern char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t breaks);
|
extern char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t breaks);
|
||||||
extern char *sprint_ascii_ex(const uint8_t *data, const size_t len, const size_t min_str_len);
|
extern char *sprint_ascii_ex(const uint8_t *data, const size_t len, const size_t min_str_len);
|
||||||
|
extern char *sprint_ascii(const uint8_t *data, const size_t len);
|
||||||
|
|
||||||
extern void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
|
extern void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
|
||||||
extern uint64_t bytes_to_num(uint8_t* src, size_t len);
|
extern uint64_t bytes_to_num(uint8_t* src, size_t len);
|
||||||
|
|
|
@ -105,44 +105,49 @@ NXP/Philips CUSTOM COMMANDS
|
||||||
|
|
||||||
|
|
||||||
#define ISO14443A_CMD_REQA 0x26
|
#define ISO14443A_CMD_REQA 0x26
|
||||||
#define ISO14443A_CMD_READBLOCK 0x30
|
|
||||||
#define ISO14443A_CMD_WUPA 0x52
|
#define ISO14443A_CMD_WUPA 0x52
|
||||||
#define ISO14443A_CMD_ANTICOLL_OR_SELECT 0x93
|
#define ISO14443A_CMD_ANTICOLL_OR_SELECT 0x93
|
||||||
#define ISO14443A_CMD_ANTICOLL_OR_SELECT_2 0x95
|
#define ISO14443A_CMD_ANTICOLL_OR_SELECT_2 0x95
|
||||||
#define ISO14443A_CMD_ANTICOLL_OR_SELECT_3 0x97
|
#define ISO14443A_CMD_ANTICOLL_OR_SELECT_3 0x97
|
||||||
#define ISO14443A_CMD_WRITEBLOCK 0xA0 // or 0xA2 ?
|
|
||||||
#define ISO14443A_CMD_HALT 0x50
|
#define ISO14443A_CMD_HALT 0x50
|
||||||
#define ISO14443A_CMD_RATS 0xE0
|
#define ISO14443A_CMD_RATS 0xE0
|
||||||
|
|
||||||
#define MIFARE_AUTH_KEYA 0x60
|
#define MIFARE_CMD_READBLOCK 0x30
|
||||||
#define MIFARE_AUTH_KEYB 0x61
|
#define MIFARE_CMD_WRITEBLOCK 0xA0
|
||||||
#define MIFARE_MAGICWUPC1 0x40
|
#define MIFARE_AUTH_KEYA 0x60
|
||||||
#define MIFARE_MAGICWUPC2 0x43
|
#define MIFARE_AUTH_KEYB 0x61
|
||||||
#define MIFARE_MAGICWIPEC 0x41
|
#define MIFARE_MAGICWUPC1 0x40
|
||||||
#define MIFARE_CMD_INC 0xC0
|
#define MIFARE_MAGICWUPC2 0x43
|
||||||
#define MIFARE_CMD_DEC 0xC1
|
#define MIFARE_MAGICWIPEC 0x41
|
||||||
#define MIFARE_CMD_RESTORE 0xC2
|
#define MIFARE_CMD_INC 0xC0
|
||||||
#define MIFARE_CMD_TRANSFER 0xB0
|
#define MIFARE_CMD_DEC 0xC1
|
||||||
|
#define MIFARE_CMD_RESTORE 0xC2
|
||||||
|
#define MIFARE_CMD_TRANSFER 0xB0
|
||||||
|
|
||||||
#define MIFARE_EV1_PERSONAL_UID 0x40
|
#define MIFARE_EV1_PERSONAL_UID 0x40
|
||||||
#define MIFARE_EV1_SETMODE 0x43
|
#define MIFARE_EV1_SETMODE 0x43
|
||||||
|
|
||||||
|
#define MIFARE_ULC_WRITE 0xA2
|
||||||
|
#define MIFARE_ULC_COMP_WRITE MIFARE_CMD_WRITEBLOCK
|
||||||
|
#define MIFARE_ULC_AUTH_1 0x1A
|
||||||
|
#define MIFARE_ULC_AUTH_2 0xAF
|
||||||
|
|
||||||
#define MIFARE_ULC_WRITE 0xA2
|
#define MIFARE_ULEV1_AUTH 0x1B
|
||||||
//#define MIFARE_ULC__COMP_WRITE 0xA0
|
#define MIFARE_ULEV1_VERSION 0x60
|
||||||
#define MIFARE_ULC_AUTH_1 0x1A
|
#define MIFARE_ULEV1_FASTREAD 0x3A
|
||||||
#define MIFARE_ULC_AUTH_2 0xAF
|
#define MIFARE_ULEV1_WRITE 0xA2
|
||||||
|
#define MIFARE_ULEV1_COMP_WRITE MIFARE_CMD_WRITEBLOCK
|
||||||
|
#define MIFARE_ULEV1_READ_CNT 0x39
|
||||||
|
#define MIFARE_ULEV1_INCR_CNT 0xA5
|
||||||
|
#define MIFARE_ULEV1_READSIG 0x3C
|
||||||
|
#define MIFARE_ULEV1_CHECKTEAR 0x3E
|
||||||
|
#define MIFARE_ULEV1_VCSL 0x4B
|
||||||
|
|
||||||
|
// mifare 4bit card answers
|
||||||
|
#define CARD_ACK 0x0A // 1010 - ACK
|
||||||
|
#define CARD_NACK_NA 0x04 // 0100 - NACK, not allowed (command not allowed)
|
||||||
|
#define CARD_NACK_TR 0x05 // 0101 - NACK, transmission error
|
||||||
|
|
||||||
#define MIFARE_ULEV1_AUTH 0x1B
|
|
||||||
#define MIFARE_ULEV1_VERSION 0x60
|
|
||||||
#define MIFARE_ULEV1_FASTREAD 0x3A
|
|
||||||
//#define MIFARE_ULEV1_WRITE 0xA2
|
|
||||||
//#define MIFARE_ULEV1_COMP_WRITE 0xA0
|
|
||||||
#define MIFARE_ULEV1_READ_CNT 0x39
|
|
||||||
#define MIFARE_ULEV1_INCR_CNT 0xA5
|
|
||||||
#define MIFARE_ULEV1_READSIG 0x3C
|
|
||||||
#define MIFARE_ULEV1_CHECKTEAR 0x3E
|
|
||||||
#define MIFARE_ULEV1_VCSL 0x4B
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
06 00 = INITIATE
|
06 00 = INITIATE
|
||||||
|
|
|
@ -41,6 +41,7 @@ typedef struct{
|
||||||
bool averaging;
|
bool averaging;
|
||||||
int divisor;
|
int divisor;
|
||||||
int trigger_threshold;
|
int trigger_threshold;
|
||||||
|
int samples_to_skip;
|
||||||
} sample_config;
|
} sample_config;
|
||||||
|
|
||||||
// For the bootloader
|
// For the bootloader
|
||||||
|
@ -116,6 +117,7 @@ typedef struct{
|
||||||
#define CMD_T55XX_WAKEUP 0x0224
|
#define CMD_T55XX_WAKEUP 0x0224
|
||||||
#define CMD_COTAG 0x0225
|
#define CMD_COTAG 0x0225
|
||||||
#define CMD_PARADOX_CLONE_TAG 0x0226
|
#define CMD_PARADOX_CLONE_TAG 0x0226
|
||||||
|
#define CMD_EM4X_PROTECT 0x0228
|
||||||
|
|
||||||
// For the 13.56 MHz tags
|
// For the 13.56 MHz tags
|
||||||
#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 0x0300
|
#define CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693 0x0300
|
||||||
|
@ -130,6 +132,7 @@ typedef struct{
|
||||||
#define CMD_ISO_15693_FIND_AFI 0x0315
|
#define CMD_ISO_15693_FIND_AFI 0x0315
|
||||||
#define CMD_ISO_15693_DEBUG 0x0316
|
#define CMD_ISO_15693_DEBUG 0x0316
|
||||||
#define CMD_LF_SNOOP_RAW_ADC_SAMPLES 0x0317
|
#define CMD_LF_SNOOP_RAW_ADC_SAMPLES 0x0317
|
||||||
|
#define CMD_CSETUID_ISO_15693 0x0318
|
||||||
|
|
||||||
// For Hitag2 transponders
|
// For Hitag2 transponders
|
||||||
#define CMD_SNOOP_HITAG 0x0370
|
#define CMD_SNOOP_HITAG 0x0370
|
||||||
|
|
|
@ -80,7 +80,7 @@ serial_port uart_open(const char* pcPortName)
|
||||||
if (sp == 0) return INVALID_SERIAL_PORT;
|
if (sp == 0) return INVALID_SERIAL_PORT;
|
||||||
|
|
||||||
if (memcmp(pcPortName, "tcp:", 4) == 0) {
|
if (memcmp(pcPortName, "tcp:", 4) == 0) {
|
||||||
struct addrinfo *addr, *rp;
|
struct addrinfo *addr = NULL, *rp;
|
||||||
char *addrstr = strdup(pcPortName + 4);
|
char *addrstr = strdup(pcPortName + 4);
|
||||||
if (addrstr == NULL) {
|
if (addrstr == NULL) {
|
||||||
printf("Error: strdup\n");
|
printf("Error: strdup\n");
|
||||||
|
@ -98,7 +98,13 @@ serial_port uart_open(const char* pcPortName)
|
||||||
} else
|
} else
|
||||||
portstr = "7901";
|
portstr = "7901";
|
||||||
|
|
||||||
int s = getaddrinfo(addrstr, portstr, NULL, &addr);
|
struct addrinfo info;
|
||||||
|
|
||||||
|
memset (&info, 0, sizeof(info));
|
||||||
|
|
||||||
|
info.ai_socktype = SOCK_STREAM;
|
||||||
|
|
||||||
|
int s = getaddrinfo(addrstr, portstr, &info, &addr);
|
||||||
if (s != 0) {
|
if (s != 0) {
|
||||||
printf("Error: getaddrinfo: %s\n", gai_strerror(s));
|
printf("Error: getaddrinfo: %s\n", gai_strerror(s));
|
||||||
return INVALID_SERIAL_PORT;
|
return INVALID_SERIAL_PORT;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue