Merge branch 'master' into allin

update
This commit is contained in:
tharexde 2020-10-03 23:34:23 +02:00
commit b0cfb28d40
232 changed files with 711543 additions and 328556 deletions

View file

@ -3,8 +3,11 @@ All notable changes to this project will be documented in this file.
This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log...
## [unreleased][unreleased]
- Add lf t55xx chk e <EM4100> option. Checks calculated password based on the EM4100 id from some white cloners forumla by paleopterix (@mwalker33)
- Add lf t55xx sniff to allow extracting commands and passwords used be cloners. (@mwalker33)
- Add low level support for 14b' aka Innovatron (@doegox)
- Add doc/cliparser.md (@mwalker33)
- Add `hf 14b apdu` - send APDU over ISO14443B (@iceman1001)
- Add `lf t55xx chk e <EM4100> option` - Checks calculated password based on the EM4100 id from some white cloners forumla by paleopterix (@mwalker33)
- Add `lf t55xx sniff` to allow extracting commands and passwords used be cloners. (@mwalker33)
- Add options to `lf read`, `lf cmdread`, `lf sniff` for repeated acquisitions (@doegox)
- Change options of `lf read` to match `lf cmdread`, this affects historical `d` and `s` options (@doegox)
- Add `hf waveshare` to upload picture to Waveshare NFC-Powered e-Paper (@doegox)

View file

@ -34,7 +34,7 @@
|[Notes on file formats used with Proxmark3](/doc/extensions_notes.md)|[Notes on MFU binary format](/doc/mfu_binary_format_notes.md)|[Notes on FPGA & ARM](/doc/fpga_arm_notes.md)|
|[Developing standalone mode](/armsrc/Standalone/readme.md)|[Wiki about standalone mode](https://github.com/RfidResearchGroup/proxmark3/wiki/Standalone-mode)|[Notes on Magic cards](/doc/magic_cards_notes.md)|
|[Notes on Color usage](/doc/colors_notes.md)|[Makefile vs CMake](/doc/md/Development/Makefile-vs-CMake.md)|[Notes on Cloner guns](/doc/cloner_notes.md)|
|[Notes on cliparser usage](/doc/cliparser.md)|||
## Build for non-RDV4 Proxmark3 platforms

View file

@ -292,6 +292,12 @@ void tosend_reset(void) {
}
void tosend_stuffbit(int b) {
if (toSend.max >= TOSEND_BUFFER_SIZE - 1) {
Dbprintf(_RED_("toSend overflow"));
return;
}
if (toSend.bit >= 8) {
toSend.max++;
toSend.buf[toSend.max] = 0;
@ -299,7 +305,7 @@ void tosend_stuffbit(int b) {
}
if (b)
toSend.buf[ toSend.max] |= (1 << (7 - toSend.bit));
toSend.buf[toSend.max] |= (1 << (7 - toSend.bit));
toSend.bit++;

View file

@ -1138,11 +1138,10 @@ static void PacketReceived(PacketCommandNG *packet) {
break;
}
case CMD_HF_ISO14443B_SIMULATE: {
SimulateIso14443bTag(packet->oldarg[0]);
SimulateIso14443bTag(packet->data.asBytes);
break;
}
case CMD_HF_ISO14443B_COMMAND: {
//SendRawCommand14443B(packet->oldarg[0],packet->oldarg[1],packet->oldarg[2],packet->data.asBytes);
SendRawCommand14443B_Ex(packet);
break;
}

View file

@ -118,7 +118,7 @@ static int EPA_APDU(uint8_t *apdu, size_t length, uint8_t *response, uint16_t re
case 'a':
return iso14_apdu(apdu, (uint16_t) length, false, response, NULL);
case 'b':
return iso14443b_apdu(apdu, length, response, respmaxlen);
return iso14443b_apdu(apdu, length, false, response, respmaxlen, NULL);
default:
return 0;
}
@ -222,14 +222,13 @@ int EPA_Read_CardAccess(uint8_t *buffer, size_t max_length) {
// since the card doesn't always care for the expected length we send it,
// we reserve 262 bytes here just to be safe (256-byte APDU + SW + ISO frame)
uint8_t response_apdu[262];
int rapdu_length = 0;
// select the file EF.CardAccess
rapdu_length = EPA_APDU((uint8_t *)apdu_select_binary_cardaccess,
sizeof(apdu_select_binary_cardaccess),
response_apdu,
sizeof(response_apdu)
);
int rapdu_length = EPA_APDU((uint8_t *)apdu_select_binary_cardaccess,
sizeof(apdu_select_binary_cardaccess),
response_apdu,
sizeof(response_apdu)
);
if (rapdu_length < 6
|| response_apdu[rapdu_length - 4] != 0x90

View file

@ -9,7 +9,7 @@
#include "commonutil.h"
#include "dbprint.h"
#include "ticks.h"
#include "mifare.h"
#include "iso18.h"
// FeliCa timings
// minimum time between the start bits of consecutive transfers from reader to tag: 6800 carrier (13.56MHz) cycles

View file

@ -1747,6 +1747,7 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
// init as reader
lf_init(true, false);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
// Tag specific configuration settings (sof, timings, etc.)
// TODO HTS
@ -1780,9 +1781,10 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
size_t max_nrzs = (8 * HITAG_FRAME_LEN + 5) * 2; // up to 2 nrzs per bit
uint8_t nrz_samples[max_nrzs];
size_t nrzs = 0;
int16_t checked = 0;
uint32_t signal_size = 10000;
bool turn_on = true;
while (bStop == false && BUTTON_PRESS() == false) {
// use malloc
@ -1818,9 +1820,20 @@ void WriterHitag(hitag_function htf, hitag_data *htd, int page) {
}
}
// Wait for t_wait_2 carrier periods after the last tag bit before transmitting,
lf_wait_periods(t_wait_2);
command_start += t_wait_2;
if (bStop) break;
if (turn_on) {
// Wait 50ms with field off to be sure the transponder gets reset
SpinDelay(50);
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
turn_on = false;
// Wait with field on to be in "Wait for START_AUTH" timeframe
lf_wait_periods(HITAG_T_WAIT_POWERUP + HITAG_T_WAIT_START_AUTH_MAX / 4);
command_start += HITAG_T_WAIT_POWERUP + HITAG_T_WAIT_START_AUTH_MAX / 4;
} else {
// Wait for t_wait_2 carrier periods after the last tag bit before transmitting,
lf_wait_periods(t_wait_2);
command_start += t_wait_2;
}
// Transmit the reader frame
command_duration = hitag_reader_send_frame(tx, txlen);

View file

@ -41,15 +41,18 @@
// defaults to 2000ms
#ifndef FWT_TIMEOUT_14B
# define FWT_TIMEOUT_14B 35312
# define FWT_TIMEOUT_14B 35312
#endif
// 1 tick == 1/13.56 mhz
// 1 us = 1.5 tick
// 330/848kHz = 1558us / 4 == 400us,
#define ISO14443B_READER_TIMEOUT 1700 //330
#define ISO14443B_READER_TIMEOUT 10000 //330
// 1024/3.39MHz = 302.1us between end of tag response and next reader cmd
#define DELAY_ISO14443B_VICC_TO_VCD_READER 600 // 1024
#define DELAY_ISO14443B_VCD_TO_VICC_READER 600// 1056
#define DELAY_ISO14443B_VICC_TO_VCD_READER (28*9) // 1024 ( counting from start of PICC EOF 14 ETU's)
#define DELAY_ISO14443B_VCD_TO_VICC_READER (28*9) // 1056
#ifndef RECEIVE_MASK
# define RECEIVE_MASK (DMA_BUFFER_SIZE - 1)
@ -57,7 +60,7 @@
// Guard Time (per 14443-2)
#ifndef TR0
# define TR0 64 // TR0 max is 256/fs = 256/(848kHz) = 302us or 64 samples from FPGA
# define TR0 32 // TR0 max is 151/fs = 151/(848kHz) = 302us or 64 samples from FPGA
#endif
// Synchronization time (per 14443-2)
@ -76,10 +79,9 @@ static void iso14b_set_timeout(uint32_t timeout);
static void iso14b_set_maxframesize(uint16_t size);
// the block number for the ISO14443-4 PCB (used with APDUs)
static uint8_t pcb_blocknum = 0;
static uint8_t iso14b_pcb_blocknum = 0;
static uint32_t iso14b_timeout = FWT_TIMEOUT_14B;
/* ISO 14443 B
*
* Reader to card | ASK - Amplitude Shift Keying Modulation (PCD to PICC for Type B) (NRZ-L encodig)
@ -272,8 +274,7 @@ static struct {
enum {
DEMOD_UNSYNCD,
DEMOD_PHASE_REF_TRAINING,
DEMOD_AWAITING_FALLING_EDGE_OF_SOF,
DEMOD_GOT_FALLING_EDGE_OF_SOF,
WAIT_FOR_RISING_EDGE_OF_SOF,
DEMOD_AWAITING_START_BIT,
DEMOD_RECEIVING_DATA
} state;
@ -306,7 +307,6 @@ static void Demod14bInit(uint8_t *data, uint16_t max_len) {
Demod14bReset();
}
/*
* 9.4395 us = 1 ETU and clock is about 1.5 us
* 13560000Hz
@ -530,7 +530,7 @@ static void TransmitFor14443b_AsTag(uint8_t *response, uint16_t len) {
// Main loop of simulated tag: receive commands from reader, decide what
// response to send, and send it.
//-----------------------------------------------------------------------------
void SimulateIso14443bTag(uint32_t pupi) {
void SimulateIso14443bTag(uint8_t *pupi) {
LED_A_ON();
// the only commands we understand is WUPB, AFI=0, Select All, N=1:
@ -553,15 +553,15 @@ void SimulateIso14443bTag(uint32_t pupi) {
0x5e, 0xd7
};
// response to HLTB and ATTRIB
static const uint8_t respOK[] = {0x00, 0x78, 0xF0};
// ...PUPI/UID supplied from user. Adjust ATQB response accordingly
if (pupi > 0) {
num_to_bytes(pupi, 4, respATQB + 1);
if (memcmp("\x00\x00\x00\x00", pupi, 4) != 0) {
memcpy(respATQB + 1, pupi, 4);
AddCrc14B(respATQB, 12);
}
// response to HLTB and ATTRIB
static const uint8_t respOK[] = {0x00, 0x78, 0xF0};
// setup device.
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
@ -723,6 +723,13 @@ void SimulateIso14443bTag(uint32_t pupi) {
// tag's response, which we leave in the buffer to be demodulated on the
// PC side.
//=============================================================================
// We support both 14b framing and 14b' framing.
// 14b framing looks like:
// xxxxxxxx1111111111111111-000000000011-0........1-0........1-0........1-1-0........1-0........1-1000000000011xxxxxx
// TR1 SOF 10*0+2*1 start-stop ^^^^^^^^byte ^ occasional stuff bit EOF 10*0+N*1
// 14b' framing looks like:
// xxxxxxxxxxxxxxxx111111111111111111111-0........1-0........1-0........1-1-0........1-0........1-000000000000xxxxxxx
// SOF? start-stop ^^^^^^^^byte ^ occasional stuff bit EOF
/*
* Handles reception of a bit from the tag
@ -740,7 +747,7 @@ void SimulateIso14443bTag(uint32_t pupi) {
*/
static RAMFUNC int Handle14443bSamplesFromTag(int ci, int cq) {
int v;
int v = 0;
// The soft decision on the bit uses an estimate of just the
// quadrant of the reference angle, not the exact angle.
@ -757,7 +764,7 @@ static RAMFUNC int Handle14443bSamplesFromTag(int ci, int cq) {
} \
}
#define SUBCARRIER_DETECT_THRESHOLD 8
#define SUBCARRIER_DETECT_THRESHOLD 8
// Subcarrier amplitude v = sqrt(ci^2 + cq^2), approximated here by max(abs(ci),abs(cq)) + 1/2*min(abs(ci),abs(cq)))
#define AMPLITUDE(ci,cq) (MAX(ABS(ci),ABS(cq)) + (MIN(ABS(ci),ABS(cq))/2))
@ -773,57 +780,33 @@ static RAMFUNC int Handle14443bSamplesFromTag(int ci, int cq) {
break;
}
case DEMOD_PHASE_REF_TRAINING: {
if (Demod.posCount < 8) {
if (AMPLITUDE(ci, cq) > SUBCARRIER_DETECT_THRESHOLD) {
// set the reference phase (will code a logic '1') by averaging over 32 1/fs.
// note: synchronization time > 80 1/fs
Demod.sumI += ci;
Demod.sumQ += cq;
Demod.posCount++;
// While we get a constant signal
if (AMPLITUDE(ci, cq) > SUBCARRIER_DETECT_THRESHOLD) {
if (((ABS(Demod.sumI) > ABS(Demod.sumQ)) && (((ci > 0) && (Demod.sumI > 0)) || ((ci < 0) && (Demod.sumI < 0)))) || // signal closer to horizontal, polarity check based on on I
((ABS(Demod.sumI) <= ABS(Demod.sumQ)) && (((cq > 0) && (Demod.sumQ > 0)) || ((cq < 0) && (Demod.sumQ < 0))))) { // signal closer to vertical, polarity check based on on Q
if (Demod.posCount < 10) { // refine signal approximation during first 10 samples
Demod.sumI += ci;
Demod.sumQ += cq;
}
Demod.posCount += 1;
} else {
// subcarrier lost
Demod.state = DEMOD_UNSYNCD;
// transition
if (Demod.posCount < 10) {
// subcarrier lost
Demod.state = DEMOD_UNSYNCD;
break;
} else {
// at this point it can be start of 14b' data or start of 14b SOF
MAKE_SOFT_DECISION();
Demod.posCount = 1; // this was the first half
Demod.thisBit = v;
Demod.shiftReg = 0;
Demod.state = DEMOD_RECEIVING_DATA;
}
}
} else {
Demod.state = DEMOD_AWAITING_FALLING_EDGE_OF_SOF;
}
break;
}
case DEMOD_AWAITING_FALLING_EDGE_OF_SOF: {
MAKE_SOFT_DECISION();
if (v < 0) { // logic '0' detected
Demod.state = DEMOD_GOT_FALLING_EDGE_OF_SOF;
Demod.posCount = 0; // start of SOF sequence
} else {
if (Demod.posCount > 200 / 4) { // maximum length of TR1 = 200 1/fs
Demod.state = DEMOD_UNSYNCD;
}
}
Demod.posCount++;
break;
}
case DEMOD_GOT_FALLING_EDGE_OF_SOF: {
Demod.posCount++;
MAKE_SOFT_DECISION();
if (v > 0) {
if (Demod.posCount < 9 * 2) { // low phase of SOF too short (< 9 etu). Note: spec is >= 10, but FPGA tends to "smear" edges
Demod.state = DEMOD_UNSYNCD;
} else {
LED_C_ON(); // Got SOF
Demod.posCount = 0;
Demod.bitCount = 0;
Demod.len = 0;
Demod.state = DEMOD_AWAITING_START_BIT;
}
} else {
if (Demod.posCount > 14 * 2) { // low phase of SOF too long (> 12 etu)
Demod.state = DEMOD_UNSYNCD;
LED_C_OFF();
}
// subcarrier lost
Demod.state = DEMOD_UNSYNCD;
}
break;
}
@ -831,7 +814,7 @@ static RAMFUNC int Handle14443bSamplesFromTag(int ci, int cq) {
Demod.posCount++;
MAKE_SOFT_DECISION();
if (v > 0) {
if (Demod.posCount > 6 * 2) { // max 19us between characters = 16 1/fs, max 3 etu after low phase of SOF = 24 1/fs
if (Demod.posCount > 3 * 2) { // max 19us between characters = 16 1/fs, max 3 etu after low phase of SOF = 24 1/fs
LED_C_OFF();
if (Demod.bitCount == 0 && Demod.len == 0) { // received SOF only, this is valid for iClass/Picopass
return true;
@ -847,6 +830,28 @@ static RAMFUNC int Handle14443bSamplesFromTag(int ci, int cq) {
}
break;
}
case WAIT_FOR_RISING_EDGE_OF_SOF: {
Demod.posCount++;
MAKE_SOFT_DECISION();
if (v > 0) {
if (Demod.posCount < 9 * 2) { // low phase of SOF too short (< 9 etu). Note: spec is >= 10, but FPGA tends to "smear" edges
Demod.state = DEMOD_UNSYNCD;
} else {
LED_C_ON(); // Got SOF
Demod.posCount = 0;
Demod.bitCount = 0;
Demod.len = 0;
Demod.state = DEMOD_AWAITING_START_BIT;
}
} else {
if (Demod.posCount > 12 * 2) { // low phase of SOF too long (> 12 etu)
Demod.state = DEMOD_UNSYNCD;
LED_C_OFF();
}
}
break;
}
case DEMOD_RECEIVING_DATA: {
MAKE_SOFT_DECISION();
@ -873,12 +878,35 @@ static RAMFUNC int Handle14443bSamplesFromTag(int ci, int cq) {
Demod.bitCount = 0;
Demod.state = DEMOD_AWAITING_START_BIT;
} else {
Demod.state = DEMOD_UNSYNCD;
LED_C_OFF();
if (s == 0x000) {
// This is EOF (start, stop and all data bits == '0'
return true;
if (Demod.len > 0) {
LED_C_OFF();
// This is EOF (start, stop and all data bits == '0'
return true;
} else {
// Zeroes but no data acquired yet?
// => Still in SOF of 14b, wait for raising edge
Demod.posCount = 10 * 2;
Demod.bitCount = 0;
Demod.len = 0;
Demod.state = WAIT_FOR_RISING_EDGE_OF_SOF;
break;
}
}
if (AMPLITUDE(ci, cq) < SUBCARRIER_DETECT_THRESHOLD) {
LED_C_OFF();
// subcarrier lost
Demod.state = DEMOD_UNSYNCD;
if (Demod.len > 0) { // no EOF but no signal anymore and we got data, e.g. ASK CTx
return true;
}
}
// we have still signal but no proper byte or EOF? this shouldn't happen
//Demod.posCount = 10 * 2;
Demod.bitCount = 0;
Demod.len = 0;
Demod.state = WAIT_FOR_RISING_EDGE_OF_SOF;
break;
}
}
Demod.posCount = 0;
@ -894,25 +922,18 @@ static RAMFUNC int Handle14443bSamplesFromTag(int ci, int cq) {
return false;
}
/*
* Demodulate the samples we received from the tag, also log to tracebuffer
*/
static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, int timeout, uint32_t *eof_time) {
int samples = 0, ret = 0;
// Set up the demodulator for tag -> reader responses.
Demod14bInit(response, max_len);
// wait for last transfer to complete
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)) {};
// And put the FPGA in the appropriate mode
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_848_KHZ | FPGA_HF_READER_MODE_RECEIVE_IQ);
// Setup and start DMA.
FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
//FpgaSetupSsc(FPGA_MAJOR_MODE_HF_READER);
// The DMA buffer, used to stream samples from the FPGA
dmabuf16_t *dma = get_dma16();
@ -924,6 +945,9 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, int timeo
uint32_t dma_start_time = 0;
uint16_t *upTo = dma->buf;
// Put FPGA in the appropriate mode
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_SUBCARRIER_848_KHZ | FPGA_HF_READER_MODE_RECEIVE_IQ);
for (;;) {
volatile uint16_t behindBy = ((uint16_t *)AT91C_BASE_PDC_SSC->PDC_RPR - upTo) & (DMA_BUFFER_SIZE - 1);
@ -971,7 +995,7 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, int timeo
if (Handle14443bSamplesFromTag(ci, cq)) {
*eof_time = dma_start_time + (samples * 16) - DELAY_TAG_TO_ARM; // end of EOF
*eof_time = dma_start_time + (samples ) - DELAY_TAG_TO_ARM; // end of EOF
if (Demod.len > Demod.max_len) {
ret = -2; // overflow
@ -986,19 +1010,17 @@ static int Get14443bAnswerFromTag(uint8_t *response, uint16_t max_len, int timeo
}
FpgaDisableSscDma();
if (ret < 0) {
return ret;
}
if (Demod.len > 0) {
uint32_t sof_time = *eof_time
- (Demod.len * 8 * 8 * 16) // time for byte transfers
- (32 * 16) // time for SOF transfer
- 0; // time for EOF transfer
- (Demod.len * (8 + 2)) // time for byte transfers
- (12) // time for SOF transfer
- (12); // time for EOF transfer
LogTrace(Demod.output, Demod.len, (sof_time * 4), (*eof_time * 4), NULL, false);
}
return Demod.len;
}
@ -1011,6 +1033,7 @@ static void TransmitFor14443b_AsReader(uint32_t *start_time) {
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_READER | FPGA_HF_READER_MODE_SEND_SHALLOW_MOD);
// TR2 minimum 14 ETUs
if (*start_time < DELAY_ARM_TO_TAG) {
*start_time = DELAY_ARM_TO_TAG;
}
@ -1018,21 +1041,20 @@ static void TransmitFor14443b_AsReader(uint32_t *start_time) {
*start_time = (*start_time - DELAY_ARM_TO_TAG) & 0xfffffff0;
if (GetCountSspClk() > *start_time) { // we may miss the intended time
*start_time = (GetCountSspClk() + 16) & 0xfffffff0; // next possible time
*start_time = (GetCountSspClk() + 32) & 0xfffffff0; // next possible time
}
// wait
while (GetCountSspClk() < *start_time) ;
while (GetCountSspClk() < *start_time);
LED_B_ON();
for (int c = 0; c < ts->max; c++) {
volatile uint8_t data = ts->buf[c];
for (int i = 0; i < 8; i++) {
uint16_t send_word = (data & 0x80) ? 0x0000 : 0xffff;
for (uint8_t i = 0; i < 8; i++) {
volatile uint16_t send_word = (data & 0x80) ? 0x0000 : 0xFFFF;
while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ;
AT91C_BASE_SSC->SSC_THR = send_word;
while (!(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY))) ;
@ -1045,6 +1067,9 @@ static void TransmitFor14443b_AsReader(uint32_t *start_time) {
LED_B_OFF();
*start_time += DELAY_ARM_TO_TAG;
// wait for last transfer to complete
while (!(AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXEMPTY)) {};
}
//-----------------------------------------------------------------------------
@ -1061,32 +1086,38 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len) {
* - no modulation ONES
*
* 1 ETU == 1 BIT!
* TR0 - 8 ETUS minimum.
* TR0 - 8 ETU's minimum.
* TR0 - 32 ETU's maximum for ATQB only
* TR0 - FWT for all other commands
*
* QUESTION: how long is a 1 or 0 in pulses in the xcorr_848 mode?
* 1 "stuffbit" = 1ETU (9us)
*
* TR2 - After the PICC response, the PCD is required to wait the Frame Delay Time (TR2)
before transmission of the next command. The minimum frame delay time required for
all commands is 14 ETUs
*
*/
int i;
tosend_reset();
// Send SOF
// 10-11 ETUs of ZERO
for (int i = 0; i < 10; i++)
for (i = 0; i < 10; i++) {
tosend_stuffbit(0);
}
// 2-3 ETUs of ONE
tosend_stuffbit(1);
tosend_stuffbit(1);
// Sending cmd, LSB
// from here we add BITS
for (int i = 0; i < len; i++) {
for (i = 0; i < len; i++) {
// Start bit
tosend_stuffbit(0);
// Data bits
uint8_t b = cmd[i];
// Data bits
volatile uint8_t b = cmd[i];
tosend_stuffbit(b & 1);
tosend_stuffbit((b >> 1) & 1);
tosend_stuffbit((b >> 2) & 1);
@ -1098,31 +1129,29 @@ static void CodeIso14443bAsReader(const uint8_t *cmd, int len) {
// Stop bit
tosend_stuffbit(1);
// EGT extra guard time
// For PCD it ranges 0-57us (1etu = 9us)
// tosend_stuffbit(1);
// tosend_stuffbit(1);
// tosend_stuffbit(1);
// EGT extra guard time 1 ETU = 9us
// For PCD it ranges 0-57us === 0 - 6 ETU
// FOR PICC it ranges 0-19us == 0 - 2 ETU
}
// Send EOF
// 10-11 ETUs of ZERO
for (int i = 0; i < 10; i++)
for (i = 0; i < 10; i++) {
tosend_stuffbit(0);
}
// Transition time. TR0 - guard time
// 8ETUS minum?
// Per specification, Subcarrier must be stopped no later than 2 ETUs after EOF.
// I'm guessing this is for the FPGA to be able to send all bits before we switch to listening mode
tosend_stuffbit(1);
/* Transition time. TR0 - guard time
* TR0 - 8 ETU's minimum.
* TR0 - 32 ETU's maximum for ATQB only
* TR0 - FWT for all other commands
* 32,64,128,256,512, ... , 262144, 524288 ETU
*/
int pad = (12 + (len * 10) + 11) & 0x7;
// ensure that last byte is filled up
for (int i = 0; i < 8 ; ++i)
for (i = 0; i < 16 - pad; ++i)
tosend_stuffbit(1);
// TR1 - Synchronization time
// Convert from last character reference to length
tosend_t *ts = get_tosend();
ts->max++;
}
/*
@ -1132,56 +1161,175 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len, uint32_t
tosend_t *ts = get_tosend();
CodeIso14443bAsReader(cmd, len);
TransmitFor14443b_AsReader(start_time);
*eof_time = *start_time + (32 * (8 * ts->max));
*eof_time = *start_time + (10 * ts->max) + 10 + 2 + 10;
LogTrace(cmd, len, *start_time, *eof_time, NULL, true);
}
/* Sends an APDU to the tag
* TODO: check CRC and preamble
*/
int iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response, uint16_t respmaxlen) {
int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void *rxdata, uint16_t rxmaxlen, uint8_t *res) {
LED_A_ON();
uint8_t message_frame[message_length + 4];
// PCB
message_frame[0] = 0x0A | pcb_blocknum;
pcb_blocknum ^= 1;
// CID
message_frame[1] = 0;
// INF
memcpy(message_frame + 2, message, message_length);
// EDC (CRC)
AddCrc14B(message_frame, message_length + 2);
uint8_t real_cmd[msg_len + 4];
if (msg_len) {
// ISO 14443 APDU frame: PCB [CID] [NAD] APDU CRC PCB=0x02
real_cmd[0] = 0x02; // bnr, nad, cid, chn=0; i-block(0x00)
if (send_chaining) {
real_cmd[0] |= 0x10;
}
// put block number into the PCB
real_cmd[0] |= iso14b_pcb_blocknum;
memcpy(real_cmd + 1, msg, msg_len);
} else {
// R-block. ACK
real_cmd[0] = 0xA2; // r-block + ACK
real_cmd[0] |= iso14b_pcb_blocknum;
}
AddCrc14B(real_cmd, msg_len + 1);
// send
uint32_t start_time = 0;
uint32_t eof_time = 0;
CodeAndTransmit14443bAsReader(message_frame, sizeof(message_frame), &start_time, &eof_time);
// Get response?
if (response == NULL) {
LED_A_OFF();
return 0;
}
CodeAndTransmit14443bAsReader(real_cmd, msg_len + 3, &start_time, &eof_time);
eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER;
int retlen = Get14443bAnswerFromTag(response, respmaxlen, ISO14443B_READER_TIMEOUT, &eof_time);
int len = Get14443bAnswerFromTag(rxdata, rxmaxlen, ISO14443B_READER_TIMEOUT, &eof_time);
FpgaDisableTracing();
if (retlen < 3) {
LED_A_OFF();
return -1;
uint8_t *data_bytes = (uint8_t *) rxdata;
if (len <= 0) {
return 0; //DATA LINK ERROR
} else {
// S-Block WTX
while (len && ((data_bytes[0] & 0xF2) == 0xF2)) {
uint32_t save_iso14b_timeout = iso14b_timeout;
// temporarily increase timeout
iso14b_set_timeout(MAX((data_bytes[1] & 0x3f) * save_iso14b_timeout, ISO14443B_READER_TIMEOUT));
// Transmit WTX back
// byte1 - WTXM [1..59]. command FWT = FWT * WTXM
data_bytes[1] = data_bytes[1] & 0x3f; // 2 high bits mandatory set to 0b
// now need to fix CRC.
AddCrc14B(data_bytes, len - 2);
// transmit S-Block
CodeAndTransmit14443bAsReader(data_bytes, len, &start_time, &eof_time);
// retrieve the result again (with increased timeout)
eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER;
len = Get14443bAnswerFromTag(rxdata, rxmaxlen, ISO14443B_READER_TIMEOUT, &eof_time);
FpgaDisableTracing();
data_bytes = rxdata;
// restore timeout
iso14b_set_timeout(save_iso14b_timeout);
}
// if we received an I- or R(ACK)-Block with a block number equal to the
// current block number, toggle the current block number
if (len >= 3 // PCB + CRC = 3 bytes
&& ((data_bytes[0] & 0xC0) == 0 // I-Block
|| (data_bytes[0] & 0xD0) == 0x80) // R-Block with ACK bit set to 0
&& (data_bytes[0] & 0x01) == iso14b_pcb_blocknum) { // equal block numbers
iso14b_pcb_blocknum ^= 1;
}
// if we received I-block with chaining we need to send ACK and receive another block of data
if (res)
*res = data_bytes[0];
// crc check
if (len >= 3 && !check_crc(CRC_14443_B, data_bytes, len)) {
return -1;
}
}
// VALIDATE CRC
if (!check_crc(CRC_14443_B, response, retlen)) {
if (DBGLEVEL > DBG_DEBUG) DbpString("CRC fail");
if (len) {
// cut frame byte
len -= 1;
// memmove(data_bytes, data_bytes + 1, len);
for (int i = 0; i < len; i++)
data_bytes[i] = data_bytes[i + 1];
}
return len;
}
/**
* ASK CTS initialise.
*/
static int iso14443b_select_cts_card(iso14b_cts_card_select_t *card) {
// INITIATE command: wake up the tag using the INITIATE
uint8_t cmdINIT[] = {ASK_REQT, 0xF9, 0xE0};
uint8_t cmdMSBUID[] = {ASK_SELECT, 0xFF, 0xFF, 0x00, 0x00};
uint8_t cmdLSBUID[] = {0xC4, 0x00, 0x00};
AddCrc14B(cmdMSBUID, 3);
AddCrc14B(cmdLSBUID, 1);
uint8_t r[8];
uint32_t start_time = 0;
uint32_t eof_time = 0;
CodeAndTransmit14443bAsReader(cmdINIT, sizeof(cmdINIT), &start_time, &eof_time);
eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER;
int retlen = Get14443bAnswerFromTag(r, sizeof(r), ISO14443B_READER_TIMEOUT, &eof_time);
FpgaDisableTracing();
if (retlen != 4) {
return -1;
}
if (check_crc(CRC_14443_B, r, retlen) == false) {
return -2;
}
return retlen;
}
if (card) {
// pc. fc Product code, Facility code
card->pc = r[0];
card->fc = r[1];
}
start_time = eof_time + DELAY_ISO14443B_VICC_TO_VCD_READER;
CodeAndTransmit14443bAsReader(cmdMSBUID, sizeof(cmdMSBUID), &start_time, &eof_time);
eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER;
retlen = Get14443bAnswerFromTag(r, sizeof(r), ISO14443B_READER_TIMEOUT, &eof_time);
FpgaDisableTracing();
if (retlen != 4) {
return -1;
}
if (check_crc(CRC_14443_B, r, retlen) == false) {
return -2;
}
if (card) {
memcpy(card->uid, r, 2);
}
start_time = eof_time + DELAY_ISO14443B_VICC_TO_VCD_READER;
CodeAndTransmit14443bAsReader(cmdLSBUID, sizeof(cmdLSBUID), &start_time, &eof_time);
eof_time += DELAY_ISO14443B_VCD_TO_VICC_READER;
retlen = Get14443bAnswerFromTag(r, sizeof(r), ISO14443B_READER_TIMEOUT, &eof_time);
FpgaDisableTracing();
if (retlen != 4) {
return -1;
}
if (check_crc(CRC_14443_B, r, retlen) == false) {
return -2;
}
if (card) {
memcpy(card->uid + 2, r, 2);
}
return 0;
}
/**
* SRx Initialise.
*/
@ -1200,8 +1348,9 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) {
int retlen = Get14443bAnswerFromTag(r_init, sizeof(r_init), ISO14443B_READER_TIMEOUT, &eof_time);
FpgaDisableTracing();
if (retlen <= 0)
if (retlen <= 0) {
return -1;
}
// Randomly generated Chip ID
if (card) {
@ -1224,8 +1373,6 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) {
if (retlen != 3) {
return -1;
}
// Check the CRC of the answer:
if (!check_crc(CRC_14443_B, r_select, retlen)) {
return -2;
}
@ -1250,8 +1397,6 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) {
if (retlen != 10) {
return -1;
}
// The check the CRC of the answer
if (!check_crc(CRC_14443_B, r_papid, retlen)) {
return -2;
}
@ -1272,7 +1417,10 @@ static int iso14443b_select_srx_card(iso14b_card_select_t *card) {
int iso14443b_select_card(iso14b_card_select_t *card) {
// WUPB command (including CRC)
// Note: WUPB wakes up all tags, REQB doesn't wake up tags in HALT state
static const uint8_t wupb[] = { ISO14443B_REQB, 0x00, 0x08, 0x39, 0x73 };
// WUTB or REQB is denoted in the third byte, lower nibble. 0 vs 8
//static const uint8_t wupb[] = { ISO14443B_REQB, 0x00, 0x08, 0x39, 0x73 };
static const uint8_t wupb[] = { ISO14443B_REQB, 0x00, 0x00, 0x71, 0xff };
// ATTRIB command (with space for CRC)
uint8_t attrib[] = { ISO14443B_ATTRIB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00};
@ -1350,7 +1498,7 @@ int iso14443b_select_card(iso14b_card_select_t *card) {
}
}
// reset PCB block number
pcb_blocknum = 0;
iso14b_pcb_blocknum = 0;
return 0;
}
@ -1641,7 +1789,7 @@ void SniffIso14443b(void) {
expect_tag_answer = false;
tag_is_active = false;
} else {
tag_is_active = (Demod.state > DEMOD_GOT_FALLING_EDGE_OF_SOF);
tag_is_active = (Demod.state > WAIT_FOR_RISING_EDGE_OF_SOF);
}
}
}
@ -1683,6 +1831,7 @@ void SendRawCommand14443B_Ex(PacketCommandNG *c) {
size_t len = c->oldarg[1] & 0xffff;
uint32_t timeout = c->oldarg[2];
uint8_t *cmd = c->data.asBytes;
uint8_t buf[PM3_CMD_DATA_SIZE] = {0x00};
if (DBGLEVEL > DBG_DEBUG) Dbprintf("14b raw: param, %04x", param);
@ -1718,10 +1867,20 @@ void SendRawCommand14443B_Ex(PacketCommandNG *c) {
if (status > 0) goto out;
}
if ((param & ISO14B_SELECT_CTS) == ISO14B_SELECT_CTS) {
iso14b_cts_card_select_t cts;
sendlen = sizeof(iso14b_cts_card_select_t);
status = iso14443b_select_cts_card(&cts);
reply_mix(CMD_HF_ISO14443B_COMMAND, status, sendlen, 0, (uint8_t *)&cts, sendlen);
// 0: OK 2: demod fail, 3:crc fail,
if (status > 0) goto out;
}
if ((param & ISO14B_APDU) == ISO14B_APDU) {
uint8_t buf[100] = {0};
status = iso14443b_apdu(cmd, len, buf, sizeof(buf));
reply_mix(CMD_HF_ISO14443B_COMMAND, status, status, 0, buf, status);
uint8_t res;
status = iso14443b_apdu(cmd, len, (param & ISO14B_SEND_CHAINING), buf, sizeof(buf), &res);
sendlen = MIN(Demod.len, PM3_CMD_DATA_SIZE);
reply_mix(CMD_HF_ISO14443B_COMMAND, status, res, 0, buf, sendlen);
}
if ((param & ISO14B_RAW) == ISO14B_RAW) {
@ -1729,8 +1888,6 @@ void SendRawCommand14443B_Ex(PacketCommandNG *c) {
AddCrc14B(cmd, len);
len += 2;
}
uint8_t buf[100] = {0};
uint32_t start_time = 0;
uint32_t eof_time = 0;
CodeAndTransmit14443bAsReader(cmd, len, &start_time, &eof_time);

View file

@ -15,7 +15,7 @@
#include "common.h"
#include "mifare.h"
#include "iso14b.h"
#include "pm3_cmd.h"
#ifndef AddCrc14A
@ -27,12 +27,12 @@
#endif
void iso14443b_setup(void);
int iso14443b_apdu(uint8_t const *message, size_t message_length, uint8_t *response, uint16_t respmaxlen);
int iso14443b_apdu(uint8_t const *msg, size_t msg_len, bool send_chaining, void *rxdata, uint16_t rxmaxlen, uint8_t *res);
int iso14443b_select_card(iso14b_card_select_t *card);
int iso14443b_select_card_srx(iso14b_card_select_t *card);
void SimulateIso14443bTag(uint32_t pupi);
void SimulateIso14443bTag(uint8_t *pupi);
void AcquireRawAdcSamplesIso14443b(uint32_t parameter);
void ReadSTMemoryIso14443b(uint16_t numofblocks);
void SniffIso14443b(void);

View file

@ -465,7 +465,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint16_t period_0, uint
} else if (*command == '1') {
TurnReadLFOn(period_1);
} else {
for (uint8_t i=0; i < LF_CMDREAD_MAX_EXTRA_SYMBOLS; i++) {
for (uint8_t i = 0; i < LF_CMDREAD_MAX_EXTRA_SYMBOLS; i++) {
if (*command == symbol_extra[i]) {
TurnReadLFOn(period_extra[i]);
break;

View file

@ -332,7 +332,7 @@ uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, in
if (verbose) {
if (checked == -1) {
Dbprintf("lf sampling aborted");
} else if ((cancel_counter == cancel_after) && (cancel_after > 0)){
} else if ((cancel_counter == cancel_after) && (cancel_after > 0)) {
Dbprintf("lf sampling cancelled after %u", cancel_counter);
}

View file

@ -253,6 +253,7 @@ set (TARGET_SOURCES
${PM3_ROOT}/client/src/cmdlfguard.c
${PM3_ROOT}/client/src/cmdlfhid.c
${PM3_ROOT}/client/src/cmdlfhitag.c
${PM3_ROOT}/client/src/cmdlfidteck.c
${PM3_ROOT}/client/src/cmdlfindala.c
${PM3_ROOT}/client/src/cmdlfio.c
${PM3_ROOT}/client/src/cmdlfjablotron.c

View file

@ -447,6 +447,7 @@ SRCS = aidsearch.c \
cmdlfgallagher.c \
cmdlfhid.c \
cmdlfhitag.c \
cmdlfidteck.c \
cmdlfindala.c \
cmdlfio.c \
cmdlfjablotron.c \

View file

@ -132,6 +132,7 @@ add_library(pm3rrg_rdv4 SHARED
${PM3_ROOT}/client/src/cmdlfguard.c
${PM3_ROOT}/client/src/cmdlfhid.c
${PM3_ROOT}/client/src/cmdlfhitag.c
${PM3_ROOT}/client/src/cmdlfidteck.c
${PM3_ROOT}/client/src/cmdlfindala.c
${PM3_ROOT}/client/src/cmdlfio.c
${PM3_ROOT}/client/src/cmdlfjablotron.c
@ -209,4 +210,4 @@ target_link_libraries(pm3rrg_rdv4
pm3rrg_rdv4_reveng
pm3rrg_rdv4_whereami
android
log)
log)

View file

@ -1,6 +1,6 @@
#!/usr/bin/env -S pm3 -s
mem load f mfc_default_keys m
mem load f t55xx_default_pwds t
mem load f iclass_default_keys i
mem load -f mfc_default_keys --mfc
mem load -f t55xx_default_pwds --t55xx
mem load -f iclass_default_keys --iclass
lf t55xx deviceconfig z p

View file

@ -4195,7 +4195,8 @@ static void arg_cat_option(char *dest,
#endif
if (datatype) {
arg_cat(&dest, "=", &ndest);
// arg_cat(&dest, "=", &ndest);
arg_cat(&dest, " ", &ndest);
if (optvalue) {
arg_cat(&dest, "[", &ndest);
arg_cat(&dest, datatype, &ndest);
@ -4270,10 +4271,15 @@ static void arg_cat_optionv(char *dest,
}
if (datatype) {
if (longopts)
/* if (longopts)
arg_cat(&dest, "=", &ndest);
else if (shortopts)
arg_cat(&dest, " ", &ndest);
*/
if (longopts)
arg_cat(&dest, " ", &ndest);
else if (shortopts)
arg_cat(&dest, " ", &ndest);
if (optvalue) {
arg_cat(&dest, "[", &ndest);

View file

@ -11,10 +11,25 @@
#include "cliparser.h"
#include <string.h>
#include <stdlib.h>
#include <util.h> // Get color constants
#include <ui.h> // get PrintAndLogEx
#ifndef ARRAYLEN
# define ARRAYLEN(x) (sizeof(x)/sizeof((x)[0]))
#endif
// Custom Colors
// To default the color return s
#define _SectionTagColor_(s) _GREEN_(s)
#define _ExampleColor_(s) _YELLOW_(s)
#define _CommandColor_(s) _RED_(s)
#define _DescriptionColor_(s) _CYAN_(s)
#define _ArgColor_(s) s
#define _ArgHelpColor_(s) s
// End Custom Colors
// Option width set to 30 to allow option descriptions to align. approx line 74
// Example width set to 50 to allow help descriptions to align. approx line 93
int CLIParserInit(CLIParserContext **ctx, const char *vprogramName, const char *vprogramHint, const char *vprogramHelp) {
*ctx = malloc(sizeof(CLIParserContext));
if (!*ctx) {
@ -40,7 +55,7 @@ int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargta
/* verify the argtable[] entries were allocated sucessfully */
if (arg_nullcheck(ctx->argtable) != 0) {
/* NULL entries were detected, some allocations must have failed */
printf("ERROR: Insufficient memory\n");
PrintAndLogEx(ERR, "ERROR: Insufficient memory\n");
fflush(stdout);
return 2;
}
@ -49,14 +64,50 @@ int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargta
/* special case: '--help' takes precedence over error reporting */
if ((argc < 2 && !allowEmptyExec) || ((struct arg_lit *)(ctx->argtable)[0])->count > 0) { // help must be the first record
printf("Usage: %s", ctx->programName);
arg_print_syntaxv(stdout, ctx->argtable, "\n");
if (ctx->programHint)
printf("%s\n\n", ctx->programHint);
arg_print_glossary(stdout, ctx->argtable, " %-20s %s\n");
printf("\n");
if (ctx->programHelp)
printf("%s \n", ctx->programHelp);
PrintAndLogEx(NORMAL, "\n"_DescriptionColor_("%s"), ctx->programHint);
PrintAndLogEx(NORMAL, "\n"_SectionTagColor_("usage:"));
PrintAndLogEx(NORMAL, " "_CommandColor_("%s")NOLF, ctx->programName);
arg_print_syntax(stdout, ctx->argtable, "\n\n");
PrintAndLogEx(NORMAL, _SectionTagColor_("options:"));
arg_print_glossary(stdout, ctx->argtable, " "_ArgColor_("%-30s")" "_ArgHelpColor_("%s")"\n");
PrintAndLogEx(NORMAL, "");
if (ctx->programHelp) {
PrintAndLogEx(NORMAL, _SectionTagColor_("examples/notes:"));
char *buf = NULL;
int idx = 0;
buf = realloc(buf, strlen(ctx->programHelp) + 1); // more then enough as we are splitting
char *p2; // pointer to split example from comment.
int egWidth = 30;
for (int i = 0; i <= strlen(ctx->programHelp); i++) { // <= so to get string terminator.
buf[idx++] = ctx->programHelp[i];
if ((ctx->programHelp[i] == '\n') || (ctx->programHelp[i] == 0x00)) {
buf[idx - 1] = 0x00;
p2 = strstr(buf, "->"); // See if the example has a comment.
if (p2 != NULL) {
*(p2 - 1) = 0x00;
if (strlen(buf) > 28)
egWidth = strlen(buf) + 5;
else
egWidth = 30;
PrintAndLogEx(NORMAL, " "_ExampleColor_("%-*s")" %s", egWidth, buf, p2);
} else {
PrintAndLogEx(NORMAL, " "_ExampleColor_("%-*s"), egWidth, buf);
}
idx = 0;
}
}
PrintAndLogEx(NORMAL, "");
free(buf);
}
fflush(stdout);
return 1;
@ -66,7 +117,7 @@ int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargta
if (nerrors > 0) {
/* Display the error details contained in the arg_end struct.*/
arg_print_errors(stdout, ((struct arg_end *)(ctx->argtable)[vargtableLen - 1]), ctx->programName);
printf("Try '%s --help' for more information.\n", ctx->programName);
PrintAndLogEx(WARNING, "Try '%s --help' for more information.\n", ctx->programName);
fflush(stdout);
return 3;
}
@ -74,6 +125,7 @@ int CLIParserParseArg(CLIParserContext *ctx, int argc, char **argv, void *vargta
return 0;
}
enum ParserState {
PS_FIRST,
PS_ARGUMENT,
@ -152,7 +204,7 @@ int CLIParamHexToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int
*datalen = 0;
int ibuf = 0;
uint8_t tmp_buf[256] = {0};
uint8_t tmp_buf[512] = {0};
int res = CLIParamStrToBuf(argstr, tmp_buf, maxdatalen * 2, &ibuf); // *2 because here HEX
if (res) {
printf("Parameter error: buffer overflow.\n");
@ -186,7 +238,7 @@ int CLIParamStrToBuf(struct arg_str *argstr, uint8_t *data, int maxdatalen, int
if (!argstr->count)
return 0;
uint8_t tmp_buf[256] = {0};
uint8_t tmp_buf[512] = {0};
int ibuf = 0;
for (int i = 0; i < argstr->count; i++) {

View file

@ -14,7 +14,7 @@
#include <stdlib.h>
#include "util.h"
#define arg_param_begin arg_lit0("hH", "help", "This help")
#define arg_param_begin arg_lit0("h", "help", "This help")
#define arg_param_end arg_end(20)
#define arg_getsize(a) (sizeof(a) / sizeof(a[0]))

View file

@ -93,8 +93,10 @@ Command = {
o.data = data
return o
end,
parse = function (packet)
local count, cmd, arg1, arg2, arg3, data = bin.unpack('LLLLH511', packet)
parse = function(packet)
local count, cmd, arg1, arg2, arg3, data = bin.unpack('LLLL', packet)
local length = #packet - count + 1
count, data = bin.unpack('H'..length, packet, count)
return Command:new{cmd = cmd, arg1 = arg1, arg2 = arg2, arg3 = arg3, data = data}
end
}
@ -121,26 +123,28 @@ end
-- @param command - the usb packet to send
-- @param ignoreresponse - if set to true, we don't read the device answer packet
-- which is usually recipe for fail. If not sent, the host will wait 2s for a
-- response of type CMD_ACK
-- response of type CMD_ACK or like NG use the CMD as ack..
-- @return packet,nil if successful
-- nil, errormessage if unsuccessful
function Command:sendMIX( ignore_response, timeout )
function Command:sendMIX( ignore_response, timeout, use_cmd_ack)
if timeout == nil then timeout = TIMEOUT end
local data = self.data
local cmd = self.cmd
local arg1, arg2, arg3 = self.arg1, self.arg2, self.arg3
local err, msg = core.SendCommandMIX(cmd, arg1, arg2, arg3, data)
if err == nil then return err, msg end
if ignore_response then return true, nil end
if timeout == nil then timeout = TIMEOUT end
local ack = _commands.CMD_ACK
if use_cmd_ack then
ack = cmd
end
local response, msg = core.WaitForResponseTimeout(_commands.CMD_ACK, timeout)
local response, msg = core.WaitForResponseTimeout(ack, timeout)
if response == nil then
return nil, 'Error, waiting for response timed out :: '..msg
end
-- lets digest
data = nil
cmd = nil
@ -157,15 +161,13 @@ function Command:sendMIX( ignore_response, timeout )
return packed, nil;
end
function Command:sendNG( ignore_response, timeout )
if timeout == nil then timeout = TIMEOUT end
local data = self.data
local cmd = self.cmd
local err, msg = core.SendCommandNG(cmd, data)
if err == nil then return nil, msg end
if ignore_response then return true, nil end
if timeout == nil then timeout = TIMEOUT end
local response, msg = core.WaitForResponseTimeout(cmd, timeout)
if response == nil then
return nil, 'Error, waiting for response timed out :: '..msg

View file

@ -15,17 +15,18 @@ local cmds = require('commands')
local utils = require('utils')
-- Shouldn't take longer than 2.5 seconds
local TIMEOUT = 2500
local TIMEOUT = 2000
local ISO14B_COMMAND = {
ISO14B_CONNECT = 1,
ISO14B_DISCONNECT = 2,
ISO14B_APDU = 4,
ISO14B_RAW = 8,
ISO14B_CONNECT = 0x1,
ISO14B_DISCONNECT = 0x2,
ISO14B_APDU = 0x4,
ISO14B_RAW = 0x8,
ISO14B_REQUEST_TRIGGER = 0x10,
ISO14B_APPEND_CRC = 0x20,
ISO14B_SELECT_STD = 0x40,
ISO14B_SELECT_SR = 0x80,
ISO14B_SET_TIMEOUT = 0x100,
}
local function parse14443b(data)
@ -74,9 +75,11 @@ local function read14443b(disconnect)
arg1 = flags
}
local result, err = command:sendMIX()
info = nil
local result, err = command:sendMIX(false, TIMEOUT, true)
if result then
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL',result)
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL', result)
if arg0 == 0 then
data = string.sub(result, count)
info, err = parse14443b(data)
@ -88,12 +91,10 @@ local function read14443b(disconnect)
end
if err then
print(err)
return nil, err
end
return info
return info, nil
end
---
-- Waits for a mifare card to be placed within the vicinity of the reader.
-- @return if successful: an table containing card info
@ -102,12 +103,11 @@ local function waitFor14443b()
print('Waiting for card... press Enter to quit')
while not core.kbd_enter_pressed() do
res, err = read14443b(false)
if res then return res end
if res then return res, err end
-- err means that there was no response from card
end
return nil, 'Aborted by user'
end
---
-- turns on the HF field.
local function connect14443b()

View file

@ -11,10 +11,10 @@ This is a script to allow raw 14443a commands to be sent and received.
]]
example = [[
# 1. Connect and don't disconnect
script run hf_14a_raw -p
script run hf_14a_raw -k
# 2. Send mf auth, read response (nonce)
script run hf_14a_raw -o -x 6000F57b -p
script run hf_14a_raw -o -x 6000F57b -k
# 3. disconnect
script run hf_14a_raw -o
@ -26,10 +26,10 @@ usage = [[
script run hf_14a_raw -x 6000F57b
]]
arguments = [[
-o do not connect - use this only if you previously used -p to stay connected
-o do not connect - use this only if you previously used -k to stay connected
-r do not read response
-c calculate and append CRC
-p stay connected - dont inactivate the field
-k stay connected - dont inactivate the field
-x <payload> Data to send (NO SPACES!)
-d Debug flag
-t Topaz mode
@ -187,8 +187,8 @@ function selftest()
DEBUG = true
dbg('Performing test')
main()
main('-p')
main(' -o -x 6000F57b -p')
main('-k')
main(' -o -x 6000F57b -k')
main('-o')
main('-x 6000F57b')
dbg('Tests done')

View file

@ -135,13 +135,13 @@ function main(args)
end
-- Original loop
-- core.console("hf 14a raw -a -p -b 7 45")
-- local cmd_select = string.format("hf 14a raw -c -p 9370%s", serial_number)
-- core.console("hf 14a raw -a -k -b 7 45")
-- local cmd_select = string.format("hf 14a raw -c -k 9370%s", serial_number)
-- core.console(cmd_select)
-- for i = 0, 254 do
-- local cmd_rd_blk = string.format("hf 14a raw -c -p 30 %02x", i)
-- local cmd_rd_blk = string.format("hf 14a raw -c -k 30 %02x", i)
-- core.console(cmd_rd_blk)
-- core.console("hf 14a raw -p 80")
-- core.console("hf 14a raw -k 80")
-- end
-- core.console("hf 14a raw -r")

View file

@ -7,7 +7,7 @@ local ansicolors = require('ansicolors')
copyright = ''
author = 'Iceman'
version = 'v1.0.2'
version = 'v1.0.4'
desc = [[
This is a script to communicate with a CALYSPO / 14443b tag using the '14b raw' commands
]]
@ -31,11 +31,12 @@ device-side.
local function calypso_parse(result)
local r = Command.parse(result)
local len = r.arg2 * 2
r.data = string.sub(r.data, 0, len);
print('GOT:', r.data)
if r.arg1 == 0 then
return r, nil
if r.arg1 >= 0 then
local len = r.arg2 * 2
if len > 0 then
r.data = string.sub(r.data, 0, len);
return r, nil
end
end
return nil,nil
end
@ -123,12 +124,19 @@ local function calypso_send_cmd_raw(data, ignoreresponse )
arg2 = #data/2, -- LEN of data, half the length of the ASCII-string hex string
data = data} -- data bytes (commands etc)
result, err = command:sendMIX(ignoreresponse)
local use_cmd_ack = true
result, err = command:sendMIX(ignoreresponse, 2000, use_cmd_ack)
if result then
local r = calypso_parse(result)
return r, nil
local count,cmd,arg0,arg1,arg2 = bin.unpack('LLLL', result)
if arg0 >= 0 then
return calypso_parse(result)
else
err = 'card response failed'
end
else
err = 'No response from card'
end
return respone, err
return result, err
end
---
-- calypso_card_num : Reads card number from ATR and
@ -136,23 +144,22 @@ end
local function calypso_card_num(card)
if not card then return end
local card_num = tonumber( card.uid:sub(1,8),16 )
print('Card UID', card.uid)
print('Card Number', card_num)
print('')
print('Card UID ' ..ansicolors.green..card.uid:format('%x')..ansicolors.reset)
print('Card Number ' ..ansicolors.green..string.format('%u', card_num)..ansicolors.reset)
print('-----------------------')
end
---
-- analyse CALYPSO apdu status bytes.
local function calypso_apdu_status(apdu)
-- last two is CRC
-- next two is APDU status bytes.
local status = false
local mess = 'FAIL'
local sw = apdu:sub( #apdu-7, #apdu-4)
desc, err = iso7816.tostring(sw)
print ('SW', sw, desc, err )
status = ( sw == '9000' )
return status
--print ('SW', sw, desc, err )
local status = ( sw == '9000' )
return status, desc, err
end
local _calypso_cmds = {
@ -215,7 +222,7 @@ function main(args)
if o == 'b' then bytes = a end
end
lib14b.connect()
-- lib14b.connect()
-- Select 14b tag.
card, err = lib14b.waitFor14443b()
@ -241,14 +248,23 @@ function main(args)
--for i = 1,10 do
--result, err = calypso_send_cmd_raw('0294a40800043f000002',false) --select ICC file
for i, apdu in spairs(_calypso_cmds) do
print('>>', i )
print('>> '..ansicolors.yellow..i..ansicolors.reset)
apdu = apdu:gsub('%s+', '')
result, err = calypso_send_cmd_raw(apdu , false)
if result then
calypso_apdu_status(result.data)
print('<<', result.data )
if err then
print('<< '..err)
else
print('<< no answer')
if result then
local status, desc, err = calypso_apdu_status(result.data)
local d = result.data:sub(3, (#result.data - 8))
if status then
print('<< '..d..' ('..ansicolors.green..'ok'..ansicolors.reset..')')
else
print('<< '..d..' '..ansicolors.red..err..ansicolors.reset )
end
else
print('<< no answer')
end
end
end
lib14b.disconnect()

View file

@ -59,24 +59,24 @@ end
local function cmdUltralight()
return {
[0] = 'hf 14a raw -p -a -b 7 40',
[1] = 'hf 14a raw -p -a 43',
[0] = 'hf 14a raw -k -a -b 7 40',
[1] = 'hf 14a raw -k -a 43',
[2] = 'hf 14a raw -c -a A2005380712A',
[3] = 'hf 14a raw -p -a -b 7 40',
[4] = 'hf 14a raw -p -a 43',
[3] = 'hf 14a raw -k -a -b 7 40',
[4] = 'hf 14a raw -k -a 43',
[5] = 'hf 14a raw -c -a A2010200D980',
[6] = 'hf 14a raw -p -a -b 7 40',
[7] = 'hf 14a raw -p -a 43',
[6] = 'hf 14a raw -k -a -b 7 40',
[7] = 'hf 14a raw -k -a 43',
[8] = 'hf 14a raw -c -a A2025B480000',
[9] = 'hf 14a raw -c -a 5000',
}
end
local function cmdClassic()
return {
[0] = 'hf 14a raw -p -a -b 7 40',
[1] = 'hf 14a raw -p -a 43',
[2] = 'hf 14a raw -c -p -a A000',
[3] = 'hf 14a raw -c -p -a 01020304049802000000000000001001',
[0] = 'hf 14a raw -k -a -b 7 40',
[1] = 'hf 14a raw -k -a 43',
[2] = 'hf 14a raw -c -k -a A000',
[3] = 'hf 14a raw -c -k -a 01020304049802000000000000001001',
[4] = 'hf 14a raw -c -a 5000',
}
end

View file

@ -70,18 +70,18 @@ function magicUID(b0, b1, b2)
print('Using backdoor Magic tag function')
-- write block 0
core.console('hf 14a raw -p -a -b 7 40')
core.console('hf 14a raw -p -a 43')
core.console('hf 14a raw -k -a -b 7 40')
core.console('hf 14a raw -k -a 43')
core.console('hf 14a raw -c -a A200'..b0)
-- write block 1
core.console('hf 14a raw -p -a -b 7 40')
core.console('hf 14a raw -p -a 43')
core.console('hf 14a raw -k -a -b 7 40')
core.console('hf 14a raw -k -a 43')
core.console('hf 14a raw -c -a A201'..b1)
-- write block 2
core.console('hf 14a raw -p -a -b 7 40')
core.console('hf 14a raw -p -a 43')
core.console('hf 14a raw -k -a -b 7 40')
core.console('hf 14a raw -k -a 43')
core.console('hf 14a raw -c -a A202'..b2)
end
--
@ -90,16 +90,16 @@ function brickableUID(b0, b1, b2)
print('Using BRICKABLE Magic tag function')
core.console('hf 14a raw -p -s -3')
core.console('hf 14a raw -k -s -3')
-- write block 0
core.console('hf 14a raw -p -c A200'..b0)
core.console('hf 14a raw -k -c A200'..b0)
-- write block 1
core.console('hf 14a raw -p -c A201'..b1)
core.console('hf 14a raw -k -c A201'..b1)
-- write block 2
core.console('hf 14a raw -p -c A202'..b2)
core.console('hf 14a raw -k -c A202'..b2)
end
---
-- The main entry point

View file

@ -74,9 +74,9 @@ function main(args)
-- Upload dictionaries
print('Uploading dictionaries to RDV4 flashmemory')
print(dash)
core.console('mem load f mfc_default_keys m')
core.console('mem load f t55xx_default_pwds t')
core.console('mem load f iclass_default_keys i')
core.console('mem load -f mfc_default_keys --mfc')
core.console('mem load -f t55xx_default_pwds --t55xx')
core.console('mem load -f iclass_default_keys --iclass')
print(dash)
-- T55x7 Device configuration

View file

@ -557,27 +557,11 @@ static int CmdConvertBitStream(const char *Cmd) {
//verbose will print results and demoding messages
//emSearch will auto search for EM410x format in bitstream
//askType switches decode: ask/raw = 0, ask/manchester = 1
int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, bool *stCheck) {
int invert = 0;
int clk = 0;
int maxErr = 100;
size_t maxLen = 0;
int ASKDemod_ext(int clk, int invert, int maxErr, size_t maxLen, bool amplify, bool verbose, bool emSearch, uint8_t askType, bool *stCheck) {
uint8_t askamp = 0;
char amp = tolower(param_getchar(Cmd, 0));
sscanf(Cmd, "%i %i %i %zu %c", &clk, &invert, &maxErr, &maxLen, &amp);
if (!maxLen) maxLen = pm3_capabilities.bigbuf_size;
if (invert != 0 && invert != 1) {
PrintAndLogEx(WARNING, "Invalid argument: %s", Cmd);
return PM3_EINVARG;
}
if (clk == 1) {
invert = 1;
clk = 0;
}
uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t));
if (bits == NULL) {
return PM3_EMALLOC;
@ -597,7 +581,7 @@ int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType,
int foundclk = 0;
//amplify signal before ST check
if (amp == 'a') {
if (amplify) {
askAmp(bits, BitLen);
}
@ -658,9 +642,9 @@ int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType,
free(bits);
return PM3_SUCCESS;
}
int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType) {
int ASKDemod(int clk, int invert, int maxErr, size_t maxLen, bool amplify, bool verbose, bool emSearch, uint8_t askType) {
bool st = false;
return ASKDemod_ext(Cmd, verbose, emSearch, askType, &st);
return ASKDemod_ext(clk, invert, maxErr, maxLen, amplify, verbose, emSearch, askType, &st);
}
//by marshmellow
@ -670,19 +654,36 @@ int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType) {
static int Cmdaskmandemod(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) > 45 || cmdp == 'h') return usage_data_rawdemod_am();
bool st = true;
if (Cmd[0] == 's')
return ASKDemod_ext(Cmd++, true, true, 1, &st);
else if (Cmd[1] == 's')
return ASKDemod_ext(Cmd += 2, true, true, 1, &st);
return ASKDemod(Cmd, true, true, 1);
bool st = false;
if (Cmd[0] == 's') {
st = true;
Cmd++;
} else if (Cmd[1] == 's') {
st = true;
Cmd += 2;
}
int clk = 0;
int invert = 0;
int maxErr = 100;
size_t maxLen = 0;
bool amplify = false;
char amp = tolower(param_getchar(Cmd, 0));
sscanf(Cmd, "%i %i %i %zu %c", &clk, &invert, &maxErr, &maxLen, &amp);
amplify = amp == 'a';
if (clk == 1) {
invert = 1;
clk = 0;
}
if (invert != 0 && invert != 1) {
PrintAndLogEx(WARNING, "Invalid value for invert: %i", invert);
return PM3_EINVARG;
}
return ASKDemod_ext(clk, invert, maxErr, maxLen, amplify, true, true, 1, &st);
}
//by marshmellow
//manchester decode
//stricktly take 10 and 01 and convert to 0 and 1
//strictly take 10 and 01 and convert to 0 and 1
static int Cmdmandecoderaw(const char *Cmd) {
size_t size = 0;
int high = 0, low = 0;
@ -785,10 +786,8 @@ static int CmdBiphaseDecodeRaw(const char *Cmd) {
//by marshmellow
// - ASK Demod then Biphase decode GraphBuffer samples
int ASKbiphaseDemod(const char *Cmd, bool verbose) {
int ASKbiphaseDemod(int offset, int clk, int invert, int maxErr, bool verbose) {
//ask raw demod GraphBuffer first
int offset = 0, clk = 0, invert = 0, maxErr = 50;
sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr);
uint8_t BitStream[MAX_DEMOD_BUF_LEN];
size_t size = getFromGraphBuf(BitStream);
@ -828,16 +827,33 @@ int ASKbiphaseDemod(const char *Cmd, bool verbose) {
static int Cmdaskbiphdemod(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) > 25 || cmdp == 'h') return usage_data_rawdemod_ab();
return ASKbiphaseDemod(Cmd, true);
int offset = 0, clk = 0, invert = 0, maxErr = 50;
sscanf(Cmd, "%i %i %i %i", &offset, &clk, &invert, &maxErr);
return ASKbiphaseDemod(offset, clk, invert, maxErr, true);
}
//by marshmellow - see ASKDemod
static int Cmdaskrawdemod(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) > 25 || cmdp == 'h') return usage_data_rawdemod_ar();
return ASKDemod(Cmd, true, false, 0);
bool st = false;
int clk = 0;
int invert = 0;
int maxErr = 100;
size_t maxLen = 0;
bool amplify = false;
char amp = tolower(param_getchar(Cmd, 0));
sscanf(Cmd, "%i %i %i %zu %c", &clk, &invert, &maxErr, &maxLen, &amp);
amplify = amp == 'a';
if (clk == 1) {
invert = 1;
clk = 0;
}
if (invert != 0 && invert != 1) {
PrintAndLogEx(WARNING, "Invalid value for invert: %i", invert);
return PM3_EINVARG;
}
return ASKDemod_ext(clk, invert, maxErr, maxLen, amplify, true, false, 0, &st);
}
int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveGrph, bool verbose) {
@ -1140,24 +1156,8 @@ static char *GetFSKType(uint8_t fchigh, uint8_t fclow, uint8_t invert) {
//fsk raw demod and print binary
//takes 4 arguments - Clock, invert, fchigh, fclow
//defaults: clock = 50, invert=1, fchigh=10, fclow=8 (RF/10 RF/8 (fsk2a))
int FSKrawDemod(const char *Cmd, bool verbose) {
int FSKrawDemod(uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow, bool verbose) {
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
uint8_t rfLen, invert, fchigh, fclow;
//set defaults
//set options from parameters entered with the command
rfLen = param_get8(Cmd, 0);
invert = param_get8(Cmd, 1);
fchigh = param_get8(Cmd, 2);
fclow = param_get8(Cmd, 3);
if (strlen(Cmd) > 0 && strlen(Cmd) <= 2) {
if (rfLen == 1) {
invert = 1; //if invert option only is used
rfLen = 0;
}
}
if (getSignalProperties()->isnoise)
return PM3_ESOFT;
@ -1218,26 +1218,27 @@ out:
static int CmdFSKrawdemod(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) > 20 || cmdp == 'h') return usage_data_rawdemod_fs();
uint8_t rfLen, invert, fchigh, fclow;
return FSKrawDemod(Cmd, true);
//set defaults
//set options from parameters entered with the command
rfLen = param_get8(Cmd, 0);
invert = param_get8(Cmd, 1);
fchigh = param_get8(Cmd, 2);
fclow = param_get8(Cmd, 3);
if (strlen(Cmd) > 0 && strlen(Cmd) <= 2) {
if (rfLen == 1) {
invert = 1; //if invert option only is used
rfLen = 0;
}
}
return FSKrawDemod(rfLen, invert, fchigh, fclow, true);
}
//by marshmellow
//attempt to psk1 demod graph buffer
int PSKDemod(const char *Cmd, bool verbose) {
int invert = 0, clk = 0, maxErr = 100;
sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
if (clk == 1) {
invert = 1;
clk = 0;
}
if (invert != 0 && invert != 1) {
if (g_debugMode || verbose) PrintAndLogEx(WARNING, "Invalid argument: %s", Cmd);
return PM3_EINVARG;
}
int PSKDemod(int clk, int invert, int maxErr, bool verbose) {
if (getSignalProperties()->isnoise)
return PM3_ESOFT;
@ -1276,91 +1277,13 @@ int PSKDemod(const char *Cmd, bool verbose) {
return PM3_SUCCESS;
}
int demodIdteck(void) {
if (PSKDemod("", false) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck PSKDemod failed");
return PM3_ESOFT;
}
size_t size = DemodBufferLen;
//get binary from PSK1 wave
int idx = detectIdteck(DemodBuffer, &size);
if (idx < 0) {
if (idx == -1)
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: not enough samples");
else if (idx == -2)
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: just noise");
else if (idx == -3)
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: preamble not found");
else if (idx == -4)
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: size not correct: %zu", size);
else
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: idx: %d", idx);
// if didn't find preamble try again inverting
if (PSKDemod("1", false) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck PSKDemod failed");
return PM3_ESOFT;
}
idx = detectIdteck(DemodBuffer, &size);
if (idx < 0) {
if (idx == -1)
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: not enough samples");
else if (idx == -2)
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: just noise");
else if (idx == -3)
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: preamble not found");
else if (idx == -4)
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: size not correct: %zu", size);
else
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: idx: %d", idx);
return PM3_ESOFT;
}
}
setDemodBuff(DemodBuffer, 64, idx);
//got a good demod
uint32_t id = 0;
uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32);
uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32);
//parity check (TBD)
//checksum check (TBD)
//output
PrintAndLogEx(SUCCESS, "IDTECK Tag Found: Card ID %u , Raw: %08X%08X", id, raw1, raw2);
return PM3_SUCCESS;
}
/*
static int CmdIdteckDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodIdteck();
}
*/
// by marshmellow
// takes 3 arguments - clock, invert, maxErr as integers
// attempts to demodulate nrz only
// prints binary found and saves in demodbuffer for further commands
int NRZrawDemod(const char *Cmd, bool verbose) {
int NRZrawDemod(int clk, int invert, int maxErr, bool verbose) {
int errCnt = 0, clkStartIdx = 0;
int invert = 0, clk = 0, maxErr = 100;
sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
if (clk == 1) {
invert = 1;
clk = 0;
}
if (invert != 0 && invert != 1) {
PrintAndLogEx(WARNING, "(NRZrawDemod) Invalid argument: %s", Cmd);
return PM3_EINVARG;
}
if (getSignalProperties()->isnoise)
return PM3_ESOFT;
@ -1409,8 +1332,18 @@ int NRZrawDemod(const char *Cmd, bool verbose) {
static int CmdNRZrawDemod(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) > 16 || cmdp == 'h') return usage_data_rawdemod_nr();
int invert = 0, clk = 0, maxErr = 100;
sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
if (clk == 1) {
invert = 1;
clk = 0;
}
return NRZrawDemod(Cmd, true);
if (invert != 0 && invert != 1) {
PrintAndLogEx(WARNING, "(NRZrawDemod) Invalid argument: %s", Cmd);
return PM3_EINVARG;
}
return NRZrawDemod(clk, invert, maxErr, true);
}
// by marshmellow
@ -1420,8 +1353,17 @@ static int CmdNRZrawDemod(const char *Cmd) {
int CmdPSK1rawDemod(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) > 16 || cmdp == 'h') return usage_data_rawdemod_p1();
int ans = PSKDemod(Cmd, true);
int clk = 0, invert = 0, maxErr = 100;
sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
if (clk == 1) {
invert = 1;
clk = 0;
}
if (invert != 0 && invert != 1) {
PrintAndLogEx(WARNING, "Invalid value for invert: %i", invert);
return PM3_EINVARG;
}
int ans = PSKDemod(clk, invert, maxErr, true);
//output
if (ans != PM3_SUCCESS) {
if (g_debugMode) PrintAndLogEx(ERR, "Error demoding: %d", ans);
@ -1438,8 +1380,17 @@ int CmdPSK1rawDemod(const char *Cmd) {
static int CmdPSK2rawDemod(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) > 16 || cmdp == 'h') return usage_data_rawdemod_p2();
int ans = PSKDemod(Cmd, true);
int clk = 0, invert = 0, maxErr = 100;
sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
if (clk == 1) {
invert = 1;
clk = 0;
}
if (invert != 0 && invert != 1) {
PrintAndLogEx(WARNING, "Invalid value for invert: %i", invert);
return PM3_EINVARG;
}
int ans = PSKDemod(clk, invert, maxErr, true);
if (ans != PM3_SUCCESS) {
if (g_debugMode) PrintAndLogEx(ERR, "Error demoding: %d", ans);
return PM3_ESOFT;
@ -2313,15 +2264,14 @@ static int CmdDataNDEF(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "data ndef",
"Decode and print NFC Data Exchange Format (NDEF)",
"Samples:\n"
_YELLOW_("\tdata ndef -d 9101085402656e48656c6c6f5101085402656e576f726c64\n")
_YELLOW_("\tdata ndef -d 0103d020240203e02c040300fe\n")
"data ndef -d 9101085402656e48656c6c6f5101085402656e576f726c64\n"
"data ndef -d 0103d020240203e02c040300fe\n"
);
void *argtable[] = {
arg_param_begin,
arg_strx0("dD", "data", "<hex>", "NDEF data to decode"),
arg_lit0("vV", "verbose", "verbose mode"),
arg_strx0("d", "data", "<hex>", "NDEF data to decode"),
arg_lit0("v", "verbose", "verbose mode"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);

View file

@ -59,12 +59,13 @@ int CmdNorm(const char *Cmd);
int CmdPlot(const char *Cmd); // used by cmd lf cotag
int CmdSave(const char *Cmd); // used by cmd auto
int CmdTuneSamples(const char *Cmd); // used by cmd lf hw
int ASKbiphaseDemod(const char *Cmd, bool verbose); // used by cmd lf em4x, lf fdx, lf guard, lf jablotron, lf nedap, lf t55xx
int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType); // used by cmd lf em4x, lf t55xx, lf viking
int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, bool *stCheck); // used by cmd lf, lf em4x, lf noralsy, le presco, lf securekey, lf t55xx, lf visa2k
int FSKrawDemod(const char *Cmd, bool verbose); // used by cmd lf, lf em4x, lf t55xx
int PSKDemod(const char *Cmd, bool verbose); // used by cmd lf em4x, lf indala, lf keri, lf nexwatch, lf t55xx
int NRZrawDemod(const char *Cmd, bool verbose); // used by cmd lf pac, lf t55xx
int ASKbiphaseDemod(int offset, int clk, int invert, int maxErr, bool verbose); // used by cmd lf em4x, lf fdx, lf guard, lf jablotron, lf nedap, lf t55xx
int ASKDemod(int clk, int invert, int maxErr, size_t maxLen, bool amplify, bool verbose, bool emSearch, uint8_t askType); // used by cmd lf em4x, lf t55xx, lf viking
int ASKDemod_ext(int clk, int invert, int maxErr, size_t maxLen, bool amplify, bool verbose, bool emSearch, uint8_t askType, bool *stCheck); // used by cmd lf, lf em4x, lf noralsy, le presco, lf securekey, lf t55xx, lf visa2k
int FSKrawDemod(uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow, bool verbose); // used by cmd lf, lf em4x, lf t55xx
int PSKDemod(int clk, int invert, int maxErr, bool verbose); // used by cmd lf em4x, lf indala, lf keri, lf nexwatch, lf t55xx
int NRZrawDemod(int clk, int invert, int maxErr, bool verbose); // used by cmd lf pac, lf t55xx
void printDemodBuff(void);
@ -79,7 +80,6 @@ int getSamplesEx(uint32_t start, uint32_t end, bool verbose);
void setClockGrid(uint32_t clk, int offset);
int directionalThreshold(const int *in, int *out, size_t len, int8_t up, int8_t down);
int AskEdgeDetect(const int *in, int *out, int len, int threshold);
int demodIdteck(void);
#define MAX_DEMOD_BUF_LEN (1024*128)
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];

View file

@ -8,16 +8,13 @@
// Proxmark3 RDV40 Flash memory commands
//-----------------------------------------------------------------------------
#include "cmdflashmem.h"
#include <ctype.h>
#include "cmdparser.h" // command_t
#include "cmdparser.h" // command_t
#include "cliparser.h"
#include "pmflash.h"
#include "fileutils.h" //saveFile
#include "comms.h" //getfromdevice
#include "fileutils.h" // saveFile
#include "comms.h" // getfromdevice
#include "cmdflashmemspiffs.h" // spiffs commands
#include "rsa.h"
#include "sha1.h"
@ -29,90 +26,34 @@
static int CmdHelp(const char *Cmd);
static int usage_flashmem_spibaud(void) {
PrintAndLogEx(NORMAL, "Usage: mem spibaud [h] <baudrate>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h this help");
PrintAndLogEx(NORMAL, " <baudrate> SPI baudrate in MHz [24|48]");
PrintAndLogEx(NORMAL, " ");
PrintAndLogEx(NORMAL, " If >= 24MHz, FASTREADS instead of READS instruction will be used.");
PrintAndLogEx(NORMAL, " Reading Flash ID will virtually always fail under 48MHz setting");
PrintAndLogEx(NORMAL, " Unless you know what you are doing, please stay at 24MHz");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " mem spibaud 48");
return PM3_SUCCESS;
}
static int usage_flashmem_load(void) {
PrintAndLogEx(NORMAL, "Loads binary file into flash memory on device");
PrintAndLogEx(NORMAL, "Usage: mem load [o <offset>] f <file name> [m|t|i]");
PrintAndLogEx(NORMAL, "Warning: mem area to be written must have been wiped first");
PrintAndLogEx(NORMAL, "(this is already taken care when loading dictionaries)");
PrintAndLogEx(NORMAL, " o <offset> : offset in memory");
PrintAndLogEx(NORMAL, " f <filename> : file name");
PrintAndLogEx(NORMAL, " m : upload 6 bytes keys (mifare key dictionary)");
PrintAndLogEx(NORMAL, " i : upload 8 bytes keys (iClass key dictionary)");
PrintAndLogEx(NORMAL, " t : upload 4 bytes keys (pwd dictionary)");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " mem load f myfile"); // upload file myfile at default offset 0
PrintAndLogEx(NORMAL, " mem load f myfile o 1024"); // upload file myfile at offset 1024
PrintAndLogEx(NORMAL, " mem load f mfc_default_keys m");
PrintAndLogEx(NORMAL, " mem load f t55xx_default_pwds t");
PrintAndLogEx(NORMAL, " mem load f iclass_default_keys i");
return PM3_SUCCESS;
}
static int usage_flashmem_dump(void) {
PrintAndLogEx(NORMAL, "Dumps flash memory on device into a file or in console");
PrintAndLogEx(NORMAL, " Usage: mem dump [o <offset>] [l <length>] [f <file name>] [p]");
PrintAndLogEx(NORMAL, " o <offset> : offset in memory");
PrintAndLogEx(NORMAL, " l <length> : length");
PrintAndLogEx(NORMAL, " f <filename> : file name");
PrintAndLogEx(NORMAL, " p : print dump in console");
PrintAndLogEx(NORMAL, " You must specify at lease option f or option p, both if you wish");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " mem dump f myfile"); // download whole flashmem to file myfile
PrintAndLogEx(NORMAL, " mem dump p o 262015 l 128"); // display 128 bytes from offset 262015 (RSA sig)
PrintAndLogEx(NORMAL, " mem dump p f myfile o 241664 l 58"); // download and display 58 bytes from offset 241664 to file myfile
return PM3_SUCCESS;
}
static int usage_flashmem_wipe(void) {
PrintAndLogEx(WARNING, "[OBS] use with caution.");
PrintAndLogEx(NORMAL, "Wipe flash memory on device, which fills memory with 0xFF\n");
PrintAndLogEx(NORMAL, " Usage: mem wipe p <page>");
PrintAndLogEx(NORMAL, " p <page> : 0,1,2 page memory");
// PrintAndLogEx(NORMAL, " i : inital total wipe");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " mem wipe p 0"); // wipes first page.
return PM3_SUCCESS;
}
static int usage_flashmem_info(void) {
PrintAndLogEx(NORMAL, "Collect signature and verify it from flash memory\n");
PrintAndLogEx(NORMAL, " Usage: mem info");
// PrintAndLogEx(NORMAL, " s : create a signature");
// PrintAndLogEx(NORMAL, " w : write signature to flash memory");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " mem info");
// PrintAndLogEx(NORMAL, " mem info s");
return PM3_SUCCESS;
}
static int CmdFlashmemSpiBaudrate(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "mem baudrate",
"Set the baudrate for the SPI flash memory communications.\n"
"Reading Flash ID will virtually always fail under 48MHz setting.\n"
"Unless you know what you are doing, please stay at 24MHz.\n"
"If >= 24MHz, FASTREADS instead of READS instruction will be used.",
"mem baudrate --mhz 48"
);
void *argtable[] = {
arg_param_begin,
arg_int1(NULL, "mhz", "<24|48>", "SPI baudrate in MHz"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
int br = arg_get_int_def(ctx, 1, -1);
CLIParserFree(ctx);
char ctmp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) < 1 || ctmp == 'h') {
return usage_flashmem_spibaud();
if (br == -1) {
PrintAndLogEx(ERR, "failed to get baudrate");
return PM3_EINVARG;
}
uint32_t baudrate = param_get32ex(Cmd, 0, 0, 10);
baudrate = baudrate * 1000000;
uint32_t baudrate = br * 1000000;
if (baudrate != FLASH_BAUD && baudrate != FLASH_MINBAUD) {
usage_flashmem_spibaud();
PrintAndLogEx(ERR, "wrong baudrate. Only 24 or 48 is allowed");
return PM3_EINVARG;
}
SendCommandNG(CMD_FLASHMEM_SET_SPIBAUDRATE, (uint8_t *)&baudrate, sizeof(uint32_t));
@ -121,52 +62,50 @@ static int CmdFlashmemSpiBaudrate(const char *Cmd) {
static int CmdFlashMemLoad(const char *Cmd) {
uint32_t start_index = 0;
CLIParserContext *ctx;
CLIParserInit(&ctx, "mem load",
"Loads binary file into flash memory on device\n"
"Warning: mem area to be written must have been wiped first\n"
"( this is already taken care when loading dictionaries )",
"mem load -f myfile -> upload file myfile values at default offset 0\n"
"mem load -f myfile -o 1024 -> upload file myfile values at offset 1024\n"
"mem load -f mfc_default_keys -m -> upload MFC keys\n"
"mem load -f t55xx_default_pwds -t -> upload T55XX passwords\n"
"mem load -f iclass_default_keys -i -> upload iCLASS keys\n"
);
void *argtable[] = {
arg_param_begin,
arg_int0("o", "offset", "<dec>", "offset in memory"),
arg_lit0("m", "mifare,mfc", "upload 6 bytes keys (mifare key dictionary)"),
arg_lit0("i", "iclass", "upload 8 bytes keys (iClass key dictionary)"),
arg_lit0("t", "t55xx", "upload 4 bytes keys (password dictionary)"),
arg_strx0("f", "file", "<filename>", "file name"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
int offset = arg_get_int_def(ctx, 1, 0);
bool is_mfc = arg_get_lit(ctx, 2);
bool is_iclass = arg_get_lit(ctx, 3);
bool is_t55xx = arg_get_lit(ctx, 4);
int fnlen = 0;
char filename[FILE_PATH_SIZE] = {0};
bool errors = false;
uint8_t cmdp = 0;
CLIParamStrToBuf(arg_get_str(ctx, 5), (uint8_t*)filename, FILE_PATH_SIZE, &fnlen);
CLIParserFree(ctx);
Dictionary_t d = DICTIONARY_NONE;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_flashmem_load();
case 'f':
if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) {
PrintAndLogEx(FAILED, "Filename too long");
errors = true;
break;
}
cmdp += 2;
break;
case 'o':
start_index = param_get32ex(Cmd, cmdp + 1, 0, 10);
cmdp += 2;
break;
case 'm':
d = DICTIONARY_MIFARE;
cmdp++;
break;
case 't':
d = DICTIONARY_T55XX;
cmdp++;
break;
case 'i':
d = DICTIONARY_ICLASS;
cmdp++;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
if (is_mfc) {
d = DICTIONARY_MIFARE;
PrintAndLogEx(INFO, "treating file as MIFARE Classic keys");
} else if (is_iclass) {
d = DICTIONARY_ICLASS;
PrintAndLogEx(INFO, "treating file as iCLASS keys");
} else if (is_t55xx) {
d = DICTIONARY_T55XX;
PrintAndLogEx(INFO, "treating file as T55xx passwords");
}
//Validations
if (errors || cmdp == 0) {
usage_flashmem_load();
return PM3_EINVARG;
}
size_t datalen = 0;
uint32_t keycount = 0;
int res = 0;
@ -174,7 +113,7 @@ static int CmdFlashMemLoad(const char *Cmd) {
switch (d) {
case DICTIONARY_MIFARE:
start_index = DEFAULT_MF_KEYS_OFFSET;
offset = DEFAULT_MF_KEYS_OFFSET;
res = loadFileDICTIONARY(filename, data + 2, &datalen, 6, &keycount);
if (res || !keycount) {
free(data);
@ -189,7 +128,7 @@ static int CmdFlashMemLoad(const char *Cmd) {
datalen += 2;
break;
case DICTIONARY_T55XX:
start_index = DEFAULT_T55XX_KEYS_OFFSET;
offset = DEFAULT_T55XX_KEYS_OFFSET;
res = loadFileDICTIONARY(filename, data + 2, &datalen, 4, &keycount);
if (res || !keycount) {
free(data);
@ -204,7 +143,7 @@ static int CmdFlashMemLoad(const char *Cmd) {
datalen += 2;
break;
case DICTIONARY_ICLASS:
start_index = DEFAULT_ICLASS_KEYS_OFFSET;
offset = DEFAULT_ICLASS_KEYS_OFFSET;
res = loadFileDICTIONARY(filename, data + 2, &datalen, 8, &keycount);
if (res || !keycount) {
free(data);
@ -253,13 +192,13 @@ static int CmdFlashMemLoad(const char *Cmd) {
clearCommandBuffer();
SendCommandOLD(CMD_FLASHMEM_WRITE, start_index + bytes_sent, bytes_in_packet, 0, data + bytes_sent, bytes_in_packet);
SendCommandOLD(CMD_FLASHMEM_WRITE, offset + bytes_sent, bytes_in_packet, 0, data + bytes_sent, bytes_in_packet);
bytes_remaining -= bytes_in_packet;
bytes_sent += bytes_in_packet;
PacketResponseNG resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000) == false) {
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
conn.block_after_ACK = false;
free(data);
@ -276,54 +215,37 @@ static int CmdFlashMemLoad(const char *Cmd) {
conn.block_after_ACK = false;
free(data);
PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%zu")" bytes to offset "_GREEN_("%u"), datalen, start_index);
PrintAndLogEx(SUCCESS, "Wrote "_GREEN_("%zu")" bytes to offset "_GREEN_("%u"), datalen, offset);
return PM3_SUCCESS;
}
static int CmdFlashMemDump(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "mem dump",
"Dumps flash memory on device into a file or view in console",
"mem dump -f myfile -> download all flashmem to file\n"
"mem dump --view -o 262015 --len 128 -> display 128 bytes from offset 262015 (RSA sig)\n"
"mem dump --view -f myfile -o 241664 --len 58 -> display 58 bytes from offset 241664 and save to file"
);
void *argtable[] = {
arg_param_begin,
arg_int0("o", "offset", "<dec>", "offset in memory"),
arg_int0("l", "len", "<dec>", "length"),
arg_lit0("v", "view", "view dump"),
arg_strx0("f", "file", "<filename>", "file name"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
int offset = arg_get_int_def(ctx, 1, 0);
int len = arg_get_int_def(ctx, 2, FLASH_MEM_MAX_SIZE);
bool view = arg_get_lit(ctx, 3);
int fnlen = 0;
char filename[FILE_PATH_SIZE] = {0};
uint8_t cmdp = 0;
bool errors = false;
bool print = false;
uint32_t start_index = 0, len = FLASH_MEM_MAX_SIZE;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_flashmem_dump();
case 'l':
len = param_get32ex(Cmd, cmdp + 1, FLASH_MEM_MAX_SIZE, 10);
cmdp += 2;
break;
case 'o':
start_index = param_get32ex(Cmd, cmdp + 1, 0, 10);
cmdp += 2;
break;
case 'p':
print = true;
cmdp += 1;
break;
case 'f':
//File handling
if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) {
PrintAndLogEx(FAILED, "Filename too long");
errors = true;
break;
}
cmdp += 2;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
//Validations
if (errors || cmdp == 0) {
usage_flashmem_dump();
return PM3_EINVARG;
}
CLIParamStrToBuf(arg_get_str(ctx, 4), (uint8_t*)filename, FILE_PATH_SIZE, &fnlen);
CLIParserFree(ctx);
uint8_t *dump = calloc(len, sizeof(uint8_t));
if (!dump) {
@ -331,14 +253,15 @@ static int CmdFlashMemDump(const char *Cmd) {
return PM3_EMALLOC;
}
PrintAndLogEx(INFO, "downloading "_YELLOW_("%u")" bytes from flashmem", len);
if (!GetFromDevice(FLASH_MEM, dump, len, start_index, NULL, 0, NULL, -1, true)) {
PrintAndLogEx(FAILED, "ERROR; downloading from flashmemory");
PrintAndLogEx(INFO, "downloading "_YELLOW_("%u")" bytes from flash memory", len);
if (!GetFromDevice(FLASH_MEM, dump, len, offset, NULL, 0, NULL, -1, true)) {
PrintAndLogEx(FAILED, "ERROR; downloading from flash memory");
free(dump);
return PM3_EFLASH;
}
if (print) {
if (view) {
PrintAndLogEx(INFO, "---- " _CYAN_("data") " ---------------");
print_hex_break(dump, len, 32);
}
@ -350,39 +273,32 @@ static int CmdFlashMemDump(const char *Cmd) {
free(dump);
return PM3_SUCCESS;
}
static int CmdFlashMemWipe(const char *Cmd) {
uint8_t cmdp = 0;
bool errors = false;
bool initalwipe = false;
uint8_t page = 0;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_flashmem_wipe();
case 'p':
page = param_get8ex(Cmd, cmdp + 1, 0, 10);
if (page > 2) {
PrintAndLogEx(WARNING, "page must be 0, 1 or 2");
errors = true;
break;
}
cmdp += 2;
break;
case 'i':
initalwipe = true;
cmdp++;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
CLIParserContext *ctx;
CLIParserInit(&ctx, "mem wipe",
"Wipe flash memory on device, which fills it with 0xFF\n"
_WHITE_("[ ") _RED_("!!! OBS") " ] use with caution",
"mem wipe -p 0 -> wipes first page"
// "mem wipe -i -> inital total wipe"
);
//Validations
if (errors || cmdp == 0) {
usage_flashmem_wipe();
void *argtable[] = {
arg_param_begin,
arg_int0("p", NULL, "<dec>", "0,1,2 page memory"),
// arg_lit0("i", NULL, "inital total wipe"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
bool initalwipe = false;
int page = arg_get_int_def(ctx, 1, -1);
// initalwipe = arg_get_lit(ctx, 2);
CLIParserFree(ctx);
if (page < 0 || page > 2 ) {
PrintAndLogEx(WARNING, "page must be 0, 1 or 2");
return PM3_EINVARG;
}
@ -393,59 +309,51 @@ static int CmdFlashMemWipe(const char *Cmd) {
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
return PM3_ETIMEOUT;
}
const char* msg = "Flash WIPE ";
uint8_t isok = resp.oldarg[0] & 0xFF;
if (isok)
PrintAndLogEx(SUCCESS, "Flash WIPE ok");
PrintAndLogEx(SUCCESS, "%s ( " _GREEN_("ok")" )", msg);
else {
PrintAndLogEx(FAILED, "Flash WIPE failed");
PrintAndLogEx(FAILED, "%s ( " _RED_("failed") " )", msg);
return PM3_EFLASH;
}
return PM3_SUCCESS;
}
static int CmdFlashMemInfo(const char *Cmd) {
uint8_t sha_hash[20] = {0};
mbedtls_rsa_context rsa;
CLIParserContext *ctx;
CLIParserInit(&ctx, "mem info",
"Collect signature and verify it from flash memory",
"mem info"
// "mem info -s"
);
uint8_t cmdp = 0;
bool errors = false, shall_write = false, shall_sign = false;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_flashmem_info();
case 's': {
shall_sign = true;
cmdp++;
break;
}
case 'w':
shall_write = true;
cmdp++;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
void *argtable[] = {
arg_param_begin,
// arg_lit0("s", NULL, "create a signature"),
// arg_lit0("w", NULL, "write signature to flash memory"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
//Validations
if (errors) {
usage_flashmem_info();
return PM3_EINVARG;
}
bool shall_sign = false, shall_write = false;
// shall_sign = arg_get_lit(ctx, 1);
// shall_write = arg_get_lit(ctx, 2);
CLIParserFree(ctx);
clearCommandBuffer();
SendCommandNG(CMD_FLASHMEM_INFO, NULL, 0);
PacketResponseNG resp;
if (!WaitForResponseTimeout(CMD_ACK, &resp, 2500)) {
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
if (WaitForResponseTimeout(CMD_ACK, &resp, 2500) == false) {
PrintAndLogEx(WARNING, "timeout while waiting for reply");
return PM3_ETIMEOUT;
}
uint8_t isok = resp.oldarg[0] & 0xFF;
if (!isok) {
if (isok == false) {
PrintAndLogEx(FAILED, "failed");
return PM3_EFLASH;
}
@ -455,15 +363,20 @@ static int CmdFlashMemInfo(const char *Cmd) {
memcpy(&mem, (rdv40_validation_t *)resp.data.asBytes, sizeof(rdv40_validation_t));
// Flash ID hash (sha1)
uint8_t sha_hash[20] = {0};
mbedtls_sha1(mem.flashid, sizeof(mem.flashid), sha_hash);
// print header
PrintAndLogEx(INFO, "\n--- Flash memory Information ---------");
PrintAndLogEx(INFO, "-------------------------------------------------------------");
PrintAndLogEx(INFO, "ID | %s", sprint_hex(mem.flashid, sizeof(mem.flashid)));
PrintAndLogEx(INFO, "SHA1 | %s", sprint_hex(sha_hash, sizeof(sha_hash)));
PrintAndLogEx(INFO, "RSA SIGNATURE |");
print_hex_break(mem.signature, sizeof(mem.signature), 32);
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "--- " _CYAN_("Flash memory Information") " ---------");
// PrintAndLogEx(INFO, "-----------------------------------------------------------------");
PrintAndLogEx(INFO, "ID................... %s", sprint_hex_inrow(mem.flashid, sizeof(mem.flashid)));
PrintAndLogEx(INFO, "SHA1................. %s", sprint_hex_inrow(sha_hash, sizeof(sha_hash)));
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "--- " _CYAN_("RDV4 RSA signature") " ---------------");
for (int i = 0; i < (sizeof(mem.signature) / 32); i++) {
PrintAndLogEx(INFO, " %s", sprint_hex_inrow(mem.signature + (i * 32), 32));
}
//-------------------------------------------------------------------------------
// RRG Public RSA Key
@ -473,7 +386,10 @@ static int CmdFlashMemInfo(const char *Cmd) {
#define RSA_E "010001"
// public key modulus N
#define RSA_N "E28D809BF323171D11D1ACA4C32A5B7E0A8974FD171E75AD120D60E9B76968FF4B0A6364AE50583F9555B8EE1A725F279E949246DF0EFCE4C02B9F3ACDCC623F9337F21C0C066FFB703D8BFCB5067F309E056772096642C2B1A8F50305D5EC33DB7FB5A3C8AC42EB635AE3C148C910750ABAA280CE82DC2F180F49F30A1393B5"
#define RSA_N "E28D809BF323171D11D1ACA4C32A5B7E0A8974FD171E75AD120D60E9B76968FF" \
"4B0A6364AE50583F9555B8EE1A725F279E949246DF0EFCE4C02B9F3ACDCC623F" \
"9337F21C0C066FFB703D8BFCB5067F309E056772096642C2B1A8F50305D5EC33" \
"DB7FB5A3C8AC42EB635AE3C148C910750ABAA280CE82DC2F180F49F30A1393B5"
//-------------------------------------------------------------------------------
// Example RSA-1024 keypair, for test purposes (from common/polarssl/rsa.c)
@ -516,9 +432,9 @@ static int CmdFlashMemInfo(const char *Cmd) {
"F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
"A74206CEC169D74BF5A8C50D6F48EA08"
#define KEY_LEN 128
mbedtls_rsa_context rsa;
mbedtls_rsa_init(&rsa, MBEDTLS_RSA_PKCS_V15, 0);
rsa.len = KEY_LEN;
@ -532,13 +448,31 @@ static int CmdFlashMemInfo(const char *Cmd) {
mbedtls_mpi_read_string(&rsa.DQ, 16, RSA_DQ);
mbedtls_mpi_read_string(&rsa.QP, 16, RSA_QP);
PrintAndLogEx(INFO, "KEY length | %d", KEY_LEN);
bool is_keyok = (mbedtls_rsa_check_pubkey(&rsa) == 0 || mbedtls_rsa_check_privkey(&rsa) == 0);
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO, "--- " _CYAN_("RDV4 RSA Public key") " --------------");
char str_exp[10];
char str_pk[261];
size_t exlen = 0, pklen = 0;
mbedtls_mpi_write_string(&rsa.E, 16, str_exp, sizeof(str_exp), &exlen);
mbedtls_mpi_write_string(&rsa.N, 16, str_pk, sizeof(str_pk), &pklen);
PrintAndLogEx(INFO, "Len.................. %u", rsa.len);
PrintAndLogEx(INFO, "Exponent............. %s", str_exp);
PrintAndLogEx(INFO, "Public key modulus N");
PrintAndLogEx(INFO, " %.64s", str_pk);
PrintAndLogEx(INFO, " %.64s", str_pk + 64);
PrintAndLogEx(INFO, " %.64s", str_pk + 128);
PrintAndLogEx(INFO, " %.64s", str_pk + 192);
PrintAndLogEx(NORMAL, "");
const char *msgkey = "RSA key validation... ";
if (is_keyok)
PrintAndLogEx(SUCCESS, "RSA key validation ok");
PrintAndLogEx(SUCCESS, "%s( " _GREEN_("ok") " )", msgkey);
else
PrintAndLogEx(FAILED, "RSA key validation failed");
PrintAndLogEx(FAILED, "%s( " _RED_("failed") " )", msgkey);
//
uint8_t from_device[KEY_LEN];
@ -554,10 +488,11 @@ static int CmdFlashMemInfo(const char *Cmd) {
if (shall_sign) {
int is_signed = mbedtls_rsa_pkcs1_sign(&rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA1, 20, sha_hash, sign);
const char *msgsign = "RSA signing.......... ";
if (is_signed == 0)
PrintAndLogEx(SUCCESS, "RSA Signing ok");
PrintAndLogEx(SUCCESS, "%s( " _GREEN_("ok") " )", msgsign);
else
PrintAndLogEx(FAILED, "RSA Signing failed");
PrintAndLogEx(FAILED, "%s( " _RED_("failed") " )", msgsign);
if (shall_write) {
// save to mem
@ -574,29 +509,33 @@ static int CmdFlashMemInfo(const char *Cmd) {
}
}
PrintAndLogEx(INFO, "Signed | ");
print_hex_break(sign, sizeof(sign), 32);
PrintAndLogEx(INFO, "Signed");
for (int i = 0; i < (sizeof(sign) / 32); i++) {
PrintAndLogEx(INFO, " %s", sprint_hex_inrow(sign + (i * 32), 32));
}
}
// Verify (public key)
int is_verified = mbedtls_rsa_pkcs1_verify(&rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, MBEDTLS_MD_SHA1, 20, sha_hash, from_device);
const char *msgverify = "RSA verification..... ";
if (is_verified == 0)
PrintAndLogEx(SUCCESS, "RSA Verification ok");
PrintAndLogEx(SUCCESS, "%s( " _GREEN_("ok") " )", msgverify);
else
PrintAndLogEx(FAILED, "RSA Verification failed");
PrintAndLogEx(FAILED, "%s( " _RED_("failed") " )", msgverify);
PrintAndLogEx(NORMAL, "");
mbedtls_rsa_free(&rsa);
return PM3_SUCCESS;
}
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"spiffs", CmdFlashMemSpiFFS, IfPm3Flash, "High level SPI FileSystem Flash manipulation [rdv40]"},
{"spibaud", CmdFlashmemSpiBaudrate, IfPm3Flash, "Set Flash memory Spi baudrate [rdv40]"},
{"info", CmdFlashMemInfo, IfPm3Flash, "Flash memory information [rdv40]"},
{"load", CmdFlashMemLoad, IfPm3Flash, "Load data into flash memory [rdv40]"},
{"dump", CmdFlashMemDump, IfPm3Flash, "Dump data from flash memory [rdv40]"},
{"wipe", CmdFlashMemWipe, IfPm3Flash, "Wipe data from flash memory [rdv40]"},
{"baudrate", CmdFlashmemSpiBaudrate, IfPm3Flash, "Set Flash memory Spi baudrate"},
{"spiffs", CmdFlashMemSpiFFS, IfPm3Flash, "High level SPI FileSystem Flash manipulation"},
{"info", CmdFlashMemInfo, IfPm3Flash, "Flash memory information"},
{"load", CmdFlashMemLoad, IfPm3Flash, "Load data into flash memory"},
{"dump", CmdFlashMemDump, IfPm3Flash, "Dump data from flash memory"},
{"wipe", CmdFlashMemWipe, IfPm3Flash, "Wipe data from flash memory"},
{NULL, NULL, NULL, NULL}
};

View file

@ -236,8 +236,8 @@ static int usage_hf_14a_sim(void) {
return PM3_SUCCESS;
}
static int usage_hf_14a_sniff(void) {
PrintAndLogEx(NORMAL, "It get data from the field and saves it into command buffer.");
PrintAndLogEx(NORMAL, "Buffer accessible from command 'hf list 14a'");
PrintAndLogEx(NORMAL, "Collect data from the field and save into command buffer.");
PrintAndLogEx(NORMAL, "Buffer accessible from command 'hf 14a list'");
PrintAndLogEx(NORMAL, "Usage: hf 14a sniff [c][r]");
PrintAndLogEx(NORMAL, "c - triggered by first data from card");
PrintAndLogEx(NORMAL, "r - triggered by first 7-bit request from reader (REQ,WUP,...)");
@ -246,11 +246,11 @@ static int usage_hf_14a_sniff(void) {
return PM3_SUCCESS;
}
static int usage_hf_14a_raw(void) {
PrintAndLogEx(NORMAL, "Usage: hf 14a raw [-h] [-r] [-c] [-p] [-a] [-T] [-t] <milliseconds> [-b] <number of bits> <0A 0B 0C ... hex>");
PrintAndLogEx(NORMAL, "Usage: hf 14a raw [-h] [-r] [-c] [-k] [-a] [-T] [-t] <milliseconds> [-b] <number of bits> <0A 0B 0C ... hex>");
PrintAndLogEx(NORMAL, " -h this help");
PrintAndLogEx(NORMAL, " -r do not read response");
PrintAndLogEx(NORMAL, " -c calculate and append CRC");
PrintAndLogEx(NORMAL, " -p leave the signal field ON after receive");
PrintAndLogEx(NORMAL, " -k keep signal field ON after receive");
PrintAndLogEx(NORMAL, " -a active signal field ON without select");
PrintAndLogEx(NORMAL, " -s active signal field ON with select");
PrintAndLogEx(NORMAL, " -b number of bits to send. Useful for send partial byte");
@ -563,13 +563,13 @@ static int CmdHF14AInfo(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 14a info",
"This command makes more extensive tests against a ISO14443a tag in order to collect information",
"Sample:\n\thf 14a info -nsv - shows full information about the card\n");
"hf 14a info -nsv -> shows full information about the card\n");
void *argtable[] = {
arg_param_begin,
arg_lit0("vV", "verbose", "adds some information to results"),
arg_lit0("nN", "nacktest", "test for nack bug"),
arg_lit0("sS", "aidsearch", "checks if AIDs from aidlist.json is present on the card and prints information about found AIDs"),
arg_lit0("v", "verbose", "adds some information to results"),
arg_lit0("n", "nacktest", "test for nack bug"),
arg_lit0("s", "aidsearch", "checks if AIDs from aidlist.json is present on the card and prints information about found AIDs"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -1080,20 +1080,20 @@ static int CmdHF14AAPDU(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 14a apdu",
"Sends an ISO 7816-4 APDU via ISO 14443-4 block transmission protocol (T=CL). works with all apdu types from ISO 7816-4:2013",
"Sample:\n\thf 14a apdu -st 00A404000E325041592E5359532E444446303100\n"
"\thf 14a apdu -sd 00A404000E325041592E5359532E444446303100 - decode apdu\n"
"\thf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -l 256 - encode standard apdu\n"
"\thf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -el 65536 - encode extended apdu\n");
"hf 14a apdu -st 00A404000E325041592E5359532E444446303100\n"
"hf 14a apdu -sd 00A404000E325041592E5359532E444446303100 -> decode apdu\n"
"hf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -l 256 -> encode standard apdu\n"
"hf 14a apdu -sm 00A40400 325041592E5359532E4444463031 -el 65536 -> encode extended apdu\n");
void *argtable[] = {
arg_param_begin,
arg_lit0("sS", "select", "activate field and select card"),
arg_lit0("kK", "keep", "leave the signal field ON after receive response"),
arg_lit0("tT", "tlv", "executes TLV decoder if it possible"),
arg_lit0("dD", "decapdu", "decode apdu request if it possible"),
arg_str0("mM", "make", "<head (CLA INS P1 P2) hex>", "make apdu with head from this field and data from data field. Must be 4 bytes length: <CLA INS P1 P2>"),
arg_lit0("eE", "extended", "make extended length apdu if `m` parameter included"),
arg_int0("lL", "le", "<Le (int)>", "Le apdu parameter if `m` parameter included"),
arg_lit0("s", "select", "activate field and select card"),
arg_lit0("k", "keep", "leave the signal field ON after receive response"),
arg_lit0("t", "tlv", "executes TLV decoder if it possible"),
arg_lit0("d", "decapdu", "decode apdu request if it possible"),
arg_str0("m", "make", "<head (CLA INS P1 P2) hex>", "make apdu with head from this field and data from data field. Must be 4 bytes length: <CLA INS P1 P2>"),
arg_lit0("e", "extended", "make extended length apdu if `m` parameter included"),
arg_int0("l", "le", "<Le (int)>", "Le apdu parameter if `m` parameter included"),
arg_strx1(NULL, NULL, "<APDU (hex) | data (hex)>", "data if `m` parameter included"),
arg_param_end
};
@ -1186,7 +1186,7 @@ static int CmdHF14AAPDU(const char *Cmd) {
static int CmdHF14ACmdRaw(const char *Cmd) {
bool reply = 1;
bool crc = false;
bool power = false;
bool keep_field_on = false;
bool active = false;
bool active_select = false;
bool no_rats = false;
@ -1218,8 +1218,8 @@ static int CmdHF14ACmdRaw(const char *Cmd) {
case 'c':
crc = true;
break;
case 'p':
power = true;
case 'k':
keep_field_on = true;
break;
case 'a':
active = true;
@ -1306,7 +1306,7 @@ static int CmdHF14ACmdRaw(const char *Cmd) {
argtimeout = 13560000 / 1000 / (8 * 16) * timeout; // timeout in ETUs (time to transfer 1 bit, approx. 9.4 us)
}
if (power) {
if (keep_field_on) {
flags |= ISO14A_NO_DISCONNECT;
}
@ -1369,8 +1369,7 @@ static int CmdHF14AAntiFuzz(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 14a antifuzz",
"Tries to fuzz the ISO14443a anticollision phase",
"Usage:\n"
"\thf 14a antifuzz -4\n");
"hf 14a antifuzz -4\n");
void *argtable[] = {
arg_param_begin,
@ -1398,9 +1397,8 @@ static int CmdHF14AChaining(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf 14a chaining",
"Enable/Disable ISO14443a input chaining. Maximum input length goes from ATS.",
"Usage:\n"
"\thf 14a chaining disable -> disable chaining\n"
"\thf 14a chaining -> show chaining enable/disable state\n");
"hf 14a chaining disable -> disable chaining\n"
"hf 14a chaining -> show chaining enable/disable state\n");
void *argtable[] = {
arg_param_begin,
@ -1425,38 +1423,10 @@ static int CmdHF14AChaining(const char *Cmd) {
return 0;
}
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"list", CmdHF14AList, AlwaysAvailable, "List ISO 14443-a history"},
{"info", CmdHF14AInfo, IfPm3Iso14443a, "Tag information"},
{"reader", CmdHF14AReader, IfPm3Iso14443a, "Act like an ISO14443-a reader"},
{"cuids", CmdHF14ACUIDs, IfPm3Iso14443a, "<n> Collect n>0 ISO14443-a UIDs in one go"},
{"sim", CmdHF14ASim, IfPm3Iso14443a, "<UID> -- Simulate ISO 14443-a tag"},
{"sniff", CmdHF14ASniff, IfPm3Iso14443a, "sniff ISO 14443-a traffic"},
{"apdu", CmdHF14AAPDU, IfPm3Iso14443a, "Send ISO 14443-4 APDU to tag"},
{"chaining", CmdHF14AChaining, IfPm3Iso14443a, "Control ISO 14443-4 input chaining"},
{"raw", CmdHF14ACmdRaw, IfPm3Iso14443a, "Send raw hex data to tag"},
{"antifuzz", CmdHF14AAntiFuzz, IfPm3Iso14443a, "Fuzzing the anticollision phase. Warning! Readers may react strange"},
{"config", CmdHf14AConfig, IfPm3Iso14443a, "Configure 14a settings (use with caution)"},
{NULL, NULL, NULL, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return PM3_SUCCESS;
}
int CmdHF14A(const char *Cmd) {
clearCommandBuffer();
return CmdsParse(CommandTable, Cmd);
}
static void printTag(const char *tag) {
PrintAndLogEx(SUCCESS, " " _YELLOW_("%s"), tag);
}
typedef enum {
MTNONE = 0,
MTCLASSIC = 1,
@ -2032,3 +2002,30 @@ int infoHF14A(bool verbose, bool do_nack_test, bool do_aid_search) {
DropField();
return select_status;
}
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"list", CmdHF14AList, AlwaysAvailable, "List ISO 14443-a history"},
{"info", CmdHF14AInfo, IfPm3Iso14443a, "Tag information"},
{"reader", CmdHF14AReader, IfPm3Iso14443a, "Act like an ISO14443-a reader"},
{"cuids", CmdHF14ACUIDs, IfPm3Iso14443a, "<n> Collect n>0 ISO14443-a UIDs in one go"},
{"sim", CmdHF14ASim, IfPm3Iso14443a, "<UID> -- Simulate ISO 14443-a tag"},
{"sniff", CmdHF14ASniff, IfPm3Iso14443a, "sniff ISO 14443-a traffic"},
{"apdu", CmdHF14AAPDU, IfPm3Iso14443a, "Send ISO 14443-4 APDU to tag"},
{"chaining", CmdHF14AChaining, IfPm3Iso14443a, "Control ISO 14443-4 input chaining"},
{"raw", CmdHF14ACmdRaw, IfPm3Iso14443a, "Send raw hex data to tag"},
{"antifuzz", CmdHF14AAntiFuzz, IfPm3Iso14443a, "Fuzzing the anticollision phase. Warning! Readers may react strange"},
{"config", CmdHf14AConfig, IfPm3Iso14443a, "Configure 14a settings (use with caution)"},
{NULL, NULL, NULL, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return PM3_SUCCESS;
}
int CmdHF14A(const char *Cmd) {
clearCommandBuffer();
return CmdsParse(CommandTable, Cmd);
}

File diff suppressed because it is too large Load diff

View file

@ -315,10 +315,10 @@ static int usage_15_raw(void) {
{"-r", "do not read response" },
{"-2", "use slower '1 out of 256' mode" },
{"-c", "calculate and append CRC" },
{"-p", "leave the signal field ON" },
{"-k", "keep signal field ON after receive" },
{"", "Tip: turn on debugging for verbose output"},
};
PrintAndLogEx(NORMAL, "Usage: hf 15 raw [-r] [-2] [-c] <0A 0B 0C ... hex>\n");
PrintAndLogEx(NORMAL, "Usage: hf 15 raw [-r] [-2] [-k] [-c] <0A 0B 0C ... hex>\n");
PrintAndLogOptions(options, 4, 3);
return PM3_SUCCESS;
}
@ -381,7 +381,7 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) {
{"NXP Ultralight Ev1", "0490933BDCD6E99B4E255E3DA55389A827564E11718E017292FAF23226A96614B8"},
{"NXP NTAG21x (2013)", "04494E1A386D3D3CFE3DC10E5DE68A499B1C202DB5B132393E89ED19FE5BE8BC61"},
{"MIKRON Public key", "04f971eda742a4a80d32dcf6a814a707cc3dc396d35902f72929fdcd698b3468f2"},
{"Spark1 Public key", "04d64bb732c0d214e7ec580736acf847284b502c25c0f7f2fa86aace1dada4387a"},
{"VivoKey Spark1 Public key", "04d64bb732c0d214e7ec580736acf847284b502c25c0f7f2fa86aace1dada4387a"},
};
/*
uint8_t nxp_15693_public_keys[][PUBLIC_ECDA_KEYLEN] = {
@ -431,7 +431,7 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) {
for (i = 0; i < sizeof(revsign); i++) {
revsign[i] = signature[31 - i];
}
int reason = 0;
bool is_valid = false;
for (i = 0; i < ARRAYLEN(nxp_15693_public_keys); i++) {
@ -446,7 +446,7 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) {
reason = 1;
break;
}
// try with sha256
res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, uid, 8, signature, 32, true);
is_valid = (res == 0);
@ -463,7 +463,7 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) {
break;
}
// try with sha256
res = ecdsa_signature_r_s_verify(MBEDTLS_ECP_DP_SECP128R1, key, revuid, sizeof(revuid), revsign, sizeof(revsign), true);
is_valid = (res == 0);
@ -487,7 +487,7 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) {
PrintAndLogEx(INFO, " Elliptic curve parameters: NID_secp128r1");
PrintAndLogEx(INFO, " TAG IC Signature: %s", sprint_hex_inrow(signature, 32));
PrintAndLogEx(SUCCESS, " Signature verification: " _GREEN_("successful"));
switch(reason) {
switch (reason) {
case 1:
PrintAndLogEx(INFO, " Params used: UID and signature, plain");
break;
@ -497,7 +497,7 @@ static int nxp_15693_print_signature(uint8_t *uid, uint8_t *signature) {
case 3:
PrintAndLogEx(INFO, " Params used: reversed UID and signature, plain");
break;
case 4:
case 4:
PrintAndLogEx(INFO, " Params used: reversed UID and signature, SHA256");
break;
}
@ -1353,7 +1353,7 @@ static int CmdHF15Raw(const char *Cmd) {
if (strlen(Cmd) < 3 || cmdp == 'h') return usage_15_raw();
int reply = 1, fast = 1, i = 0;
bool crc = false, leaveSignalON = false;
bool crc = false, keep_field_on = false;
char buf[5] = "";
uint8_t data[100];
uint32_t datalen = 0, temp;
@ -1364,21 +1364,18 @@ static int CmdHF15Raw(const char *Cmd) {
while (Cmd[i] != '\0') {
if (Cmd[i] == ' ' || Cmd[i] == '\t') { i++; continue; }
if (Cmd[i] == '-') {
switch (Cmd[i + 1]) {
switch (tolower(Cmd[i + 1])) {
case 'r':
case 'R':
reply = 0;
break;
case '2':
fast = 0;
break;
case 'c':
case 'C':
crc = true;
break;
case 'p':
case 'P':
leaveSignalON = true;
case 'k':
keep_field_on = true;
break;
default:
PrintAndLogEx(WARNING, "Invalid option");
@ -1429,7 +1426,7 @@ static int CmdHF15Raw(const char *Cmd) {
}
}
if (leaveSignalON == false)
if (keep_field_on == false)
DropField();
return PM3_SUCCESS;

View file

@ -19,6 +19,7 @@
#include "crc16.h"
#include "cmdhf14a.h"
#include "protocols.h" // definitions of ISO14B protocol
#include "iso14b.h"
#define TIMEOUT 2000
static int CmdHelp(const char *Cmd);

View file

@ -21,7 +21,7 @@
#include "crc16.h"
#include "util.h"
#include "ui.h"
#include "mifare.h" // felica_card_select_t struct
#include "iso18.h" // felica_card_select_t struct
#include "des.h"
#define AddCrc(data, len) compute_crc(CRC_FELICA, (data), (len), (data)+(len)+1, (data)+(len))
@ -84,11 +84,11 @@ static int usage_hf_felica_dumplite(void) {
}
static int usage_hf_felica_raw(void) {
PrintAndLogEx(NORMAL, "Usage: hf felica raw [-h] [-r] [-c] [-p] [-a] <0A 0B 0C ... hex>");
PrintAndLogEx(NORMAL, "Usage: hf felica raw [-h] [-r] [-c] [-k] [-a] <0A 0B 0C ... hex>");
PrintAndLogEx(NORMAL, " -h this help");
PrintAndLogEx(NORMAL, " -r do not read response");
PrintAndLogEx(NORMAL, " -c calculate and append CRC");
PrintAndLogEx(NORMAL, " -p leave the signal field ON after receive");
PrintAndLogEx(NORMAL, " -k keep signal field ON after receive");
PrintAndLogEx(NORMAL, " -a active signal field ON without select");
PrintAndLogEx(NORMAL, " -s active signal field ON with select");
return PM3_SUCCESS;
@ -1687,7 +1687,7 @@ static int CmdHFFelicaDumpLite(const char *Cmd) {
static int CmdHFFelicaCmdRaw(const char *Cmd) {
bool reply = 1;
bool crc = false;
bool power = false;
bool keep_field_on = false;
bool active = false;
bool active_select = false;
uint16_t numbits = 0;
@ -1714,8 +1714,8 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) {
case 'c':
crc = true;
break;
case 'p':
power = true;
case 'k':
keep_field_on = true;
break;
case 'a':
active = true;
@ -1771,7 +1771,7 @@ static int CmdHFFelicaCmdRaw(const char *Cmd) {
flags |= FELICA_NO_SELECT;
}
if (power) {
if (keep_field_on) {
flags |= FELICA_NO_DISCONNECT;
}

View file

@ -12,7 +12,7 @@
#define CMDHFFELICA_H__
#include "common.h"
#include "mifare.h"
#include "iso18.h"
int CmdHFFelica(const char *Cmd);
int readFelicaUid(bool verbose);

View file

@ -160,17 +160,17 @@ static int CmdHFFidoRegister(const char *cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf fido reg",
"Initiate a U2F token registration. Needs two 32-byte hash numbers. \nchallenge parameter (32b) and application parameter (32b).",
"Usage:\n\thf fido reg -> execute command with 2 parameters, filled 0x00\n"
"\thf fido reg 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with parameters"
"\thf fido reg -p s0 s1 -> execute command with plain parameters");
"hf fido reg -> execute command with 2 parameters, filled 0x00\n"
"hf fido reg 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with parameters\n"
"hf fido reg -p s0 s1 -> execute command with plain parameters");
void *argtable[] = {
arg_param_begin,
arg_lit0("aA", "apdu", "show APDU requests and responses"),
arg_litn("vV", "verbose", 0, 2, "show technical data. vv - show full certificates data"),
arg_lit0("pP", "plain", "send plain ASCII to challenge and application parameters instead of HEX"),
arg_lit0("tT", "tlv", "Show DER certificate contents in TLV representation"),
arg_str0("jJ", "json", "fido.json", "JSON input / output file name for parameters."),
arg_lit0("a", "apdu", "show APDU requests and responses"),
arg_litn("v", "verbose", 0, 2, "show technical data. vv - show full certificates data"),
arg_lit0("p", "plain", "send plain ASCII to challenge and application parameters instead of HEX"),
arg_lit0("t", "tlv", "Show DER certificate contents in TLV representation"),
arg_str0("j", "json", "fido.json", "JSON input / output file name for parameters."),
arg_str0(NULL, NULL, "<HEX/ASCII challenge parameter (32b HEX/1..16 chars)>", NULL),
arg_str0(NULL, NULL, "<HEX/ASCII application parameter (32b HEX/1..16 chars)>", NULL),
arg_param_end
@ -397,20 +397,20 @@ static int CmdHFFidoAuthenticate(const char *cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf fido auth",
"Initiate a U2F token authentication. Needs key handle and two 32-byte hash numbers. \nkey handle(var 0..255), challenge parameter (32b) and application parameter (32b).",
"Usage:\n\thf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with 2 parameters, filled 0x00 and key handle\n"
"\thf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f "
"hf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with 2 parameters, filled 0x00 and key handle\n"
"hf fido auth 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f "
"000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f 000102030405060708090a0b0c0d0e0f000102030405060708090a0b0c0d0e0f -> execute command with parameters");
void *argtable[] = {
arg_param_begin,
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_lit0("vV", "verbose", "show technical data"),
arg_lit0("pP", "plain", "send plain ASCII to challenge and application parameters instead of HEX"),
arg_lit0("a", "apdu", "show APDU reqests and responses"),
arg_lit0("v", "verbose", "show technical data"),
arg_lit0("p", "plain", "send plain ASCII to challenge and application parameters instead of HEX"),
arg_rem("default mode:", "dont-enforce-user-presence-and-sign"),
arg_lit0("uU", "user", "mode: enforce-user-presence-and-sign"),
arg_lit0("cC", "check", "mode: check-only"),
arg_str0("jJ", "json", "fido.json", "JSON input / output file name for parameters."),
arg_str0("kK", "key", "public key to verify signature", NULL),
arg_lit0("u", "user", "mode: enforce-user-presence-and-sign"),
arg_lit0("c", "check", "mode: check-only"),
arg_str0("j", "json", "fido.json", "JSON input / output file name for parameters."),
arg_str0("k", "key", "public key to verify signature", NULL),
arg_str0(NULL, NULL, "<HEX key handle (var 0..255b)>", NULL),
arg_str0(NULL, NULL, "<HEX/ASCII challenge parameter (32b HEX/1..16 chars)>", NULL),
arg_str0(NULL, NULL, "<HEX/ASCII application parameter (32b HEX/1..16 chars)>", NULL),
@ -658,16 +658,16 @@ static int CmdHFFido2MakeCredential(const char *cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf fido make",
"Execute a FIDO2 Make Credential command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") " in `resources/`.",
"Usage:\n\thf fido make -> execute command with default parameters file `fido2.json`\n"
"\thf fido make test.json -> execute command with parameters file `text.json`");
"Execute a FIDO2 Make Credential command. Needs json file with parameters. Sample file `fido2.json` in `resources/`.",
"hf fido make -> execute command with default parameters file `fido2.json`\n"
"hf fido make test.json -> execute command with parameters file `text.json`");
void *argtable[] = {
arg_param_begin,
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_litn("vV", "verbose", 0, 2, "show technical data. vv - show full certificates data"),
arg_lit0("tT", "tlv", "Show DER certificate contents in TLV representation"),
arg_lit0("cC", "cbor", "show CBOR decoded data"),
arg_lit0("a", "apdu", "show APDU reqests and responses"),
arg_litn("v", "verbose", 0, 2, "show technical data. vv - show full certificates data"),
arg_lit0("t", "tlv", "Show DER certificate contents in TLV representation"),
arg_lit0("c", "cbor", "show CBOR decoded data"),
arg_str0(NULL, NULL, "<json file name>", "JSON input / output file name for parameters. Default `fido2.json`"),
arg_param_end
};
@ -783,16 +783,16 @@ static int CmdHFFido2GetAssertion(const char *cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf fido assert",
"Execute a FIDO2 Get Assertion command. Needs json file with parameters. Sample file " _YELLOW_("`fido2.json`") " in `resources/`.",
"Usage:\n\thf fido assert -> execute command with default parameters file `fido2.json`\n"
"\thf fido assert test.json -l -> execute command with parameters file `text.json` and add to request CredentialId");
"Execute a FIDO2 Get Assertion command. Needs json file with parameters. Sample file `fido2.json` in `resources/`.",
"hf fido assert -> execute command with default parameters file `fido2.json`\n"
"hf fido assert test.json -l -> execute command with parameters file `text.json` and add to request CredentialId");
void *argtable[] = {
arg_param_begin,
arg_lit0("aA", "apdu", "show APDU reqests and responses"),
arg_litn("vV", "verbose", 0, 2, "show technical data. vv - show full certificates data"),
arg_lit0("cC", "cbor", "show CBOR decoded data"),
arg_lit0("lL", "list", "add CredentialId from json to allowList. Needs if `rk` option is `false` (authenticator doesn't store credential to its memory)"),
arg_lit0("a", "apdu", "show APDU reqests and responses"),
arg_litn("v", "verbose", 0, 2, "show technical data. vv - show full certificates data"),
arg_lit0("c", "cbor", "show CBOR decoded data"),
arg_lit0("l", "list", "add CredentialId from json to allowList. Needs if `rk` option is `false` (authenticator doesn't store credential to its memory)"),
arg_str0(NULL, NULL, "<json file name>", "JSON input / output file name for parameters. Default `fido2.json`"),
arg_param_end
};

View file

@ -641,9 +641,8 @@ static int CmdHFiClassSniff(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf iclass sniff",
"Sniff the communication reader and tag",
"Usage:\n"
_YELLOW_("\thf iclass sniff") "\n"
_YELLOW_("\thf iclass sniff -j") " -> jam e-purse updates\n"
"hf iclass sniff\n"
"hf iclass sniff -j -> jam e-purse updates\n"
);
void *argtable[] = {

View file

@ -4120,15 +4120,14 @@ static int CmdHF14AMfCWipe(const char *cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mf cwipe",
"Wipe gen1 magic chinese card. Set UID/ATQA/SAK/Data/Keys/Access to default values.",
"Usage:\n"
_YELLOW_("\thf mf cwipe") " -> wipe card\n"
_YELLOW_("\thf mf cwipe -u 09080706 -a 0004 -s 18") " -- set UID, ATQA and SAK and wipe card");
"hf mf cwipe -> wipe card\n"
"hf mf cwipe -u 09080706 -a 0004 -s 18 -> set UID, ATQA and SAK and wipe card");
void *argtable[] = {
arg_param_begin,
arg_str0("uU", "uid", "<UID (hex 4b)>", "UID for card"),
arg_str0("aA", "atqa", "<ATQA (hex 2b)>", "ATQA for card"),
arg_str0("sS", "sak", "<SAK (hex 1b)>", "SAK for card"),
arg_str0("u", "uid", "<UID (hex 4b)>", "UID for card"),
arg_str0("a", "atqa", "<ATQA (hex 2b)>", "ATQA for card"),
arg_str0("s", "sak", "<SAK (hex 1b)>", "SAK for card"),
arg_param_end
};
CLIExecWithReturn(ctx, cmd, argtable, true);
@ -4799,9 +4798,8 @@ static int CmdHF14AMfAuth4(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mf auth4",
"Executes AES authentication command in ISO14443-4",
"Usage:\n"
_YELLOW_("\thf mf auth4 4000 000102030405060708090a0b0c0d0e0f") " -> executes authentication\n"
_YELLOW_("\thf mf auth4 9003 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF") " -> executes authentication\n");
"hf mf auth4 4000 000102030405060708090a0b0c0d0e0f -> executes authentication\n"
"hf mf auth4 9003 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -> executes authentication\n");
void *argtable[] = {
arg_param_begin,
@ -4834,19 +4832,18 @@ static int CmdHF14AMfMAD(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mf mad",
"Checks and prints MIFARE Application Directory (MAD)",
"Usage:\n"
_YELLOW_("\thf mf mad") " -> shows MAD if exists\n"
_YELLOW_("\thf mf mad --aid e103 -k ffffffffffff -b") " -> shows NDEF data if exists. read card with custom key and key B\n"
_YELLOW_("\thf mf mad --dch -k ffffffffffff") " -> decode CardHolder information\n");
"hf mf mad -> shows MAD if exists\n"
"hf mf mad --aid e103 -k ffffffffffff -b -> shows NDEF data if exists. read card with custom key and key B\n"
"hf mf mad --dch -k ffffffffffff -> decode CardHolder information\n");
void *argtable[] = {
arg_param_begin,
arg_lit0("vV", "verbose", "show technical data"),
arg_str0("", "aid", "<aid>", "print all sectors with specified aid"),
arg_str0("kK", "key", "<key>", "key for printing sectors"),
arg_lit0("bB", "keyb", "use key B for access printing sectors (by default: key A)"),
arg_lit0("", "be", "(optional, BigEndian)"),
arg_lit0("", "dch", "decode Card Holder information"),
arg_lit0("v", "verbose", "show technical data"),
arg_str0(NULL, "aid", "<aid>", "print all sectors with specified aid"),
arg_str0("k", "key", "<key>", "key for printing sectors"),
arg_lit0("b", "keyb", "use key B for access printing sectors (by default: key A)"),
arg_lit0(NULL, "be", "(optional, BigEndian)"),
arg_lit0(NULL, "dch", "decode Card Holder information"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -4976,17 +4973,16 @@ static int CmdHFMFNDEF(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mf ndef",
"Prints NFC Data Exchange Format (NDEF)",
"Usage:\n"
_YELLOW_("\thf mf ndef") " -> shows NDEF parsed data\n"
_YELLOW_("\thf mf ndef -vv") " -> shows NDEF parsed and raw data\n"
_YELLOW_("\thf mf ndef --aid e103 -k ffffffffffff -b") " -> shows NDEF data with custom AID, key and with key B\n");
"hf mf ndef -> shows NDEF parsed data\n"
"hf mf ndef -vv -> shows NDEF parsed and raw data\n"
"hf mf ndef --aid e103 -k ffffffffffff -b -> shows NDEF data with custom AID, key and with key B\n");
void *argtable[] = {
arg_param_begin,
arg_litn("vV", "verbose", 0, 2, "show technical data"),
arg_str0("", "aid", "<aid>", "replace default aid for NDEF"),
arg_str0("kK", "key", "<key>", "replace default key for NDEF"),
arg_lit0("bB", "keyb", "use key B for access sectors (by default: key A)"),
arg_litn("v", "verbose", 0, 2, "show technical data"),
arg_str0(NULL, "aid", "<aid>", "replace default aid for NDEF"),
arg_str0("k", "key", "<key>", "replace default key for NDEF"),
arg_lit0("b", "keyb", "use key B for access sectors (by default: key A)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -5092,17 +5088,16 @@ static int CmdHFMFPersonalize(const char *cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mf personalize",
"Personalize the UID of a MIFARE Classic EV1 card. This is only possible if it is a 7Byte UID card and if it is not already personalized.",
"Usage:\n"
_YELLOW_("\thf mf personalize UIDF0") " -> double size UID according to ISO/IEC14443-3\n"
_YELLOW_("\thf mf personalize UIDF1") " -> double size UID according to ISO/IEC14443-3, optional usage of selection process shortcut\n"
_YELLOW_("\thf mf personalize UIDF2") " -> single size random ID according to ISO/IEC14443-3\n"
_YELLOW_("\thf mf personalize UIDF3") " -> single size NUID according to ISO/IEC14443-3\n"
_YELLOW_("\thf mf personalize -t B -k B0B1B2B3B4B5 UIDF3") " -> use key B = 0xB0B1B2B3B4B5 instead of default key A\n");
"hf mf personalize UIDF0 -> double size UID according to ISO/IEC14443-3\n"
"hf mf personalize UIDF1 -> double size UID according to ISO/IEC14443-3, optional usage of selection process shortcut\n"
"hf mf personalize UIDF2 -> single size random ID according to ISO/IEC14443-3\n"
"hf mf personalize UIDF3 -> single size NUID according to ISO/IEC14443-3\n"
"hf mf personalize -t B -k B0B1B2B3B4B5 UIDF3 -> use key B = 0xB0B1B2B3B4B5 instead of default key A");
void *argtable[] = {
arg_param_begin,
arg_str0("tT", "keytype", "<A|B>", "key type (A or B) to authenticate sector 0 (default: A)"),
arg_str0("kK", "key", "<key (hex 6 Bytes)>", "key to authenticate sector 0 (default: FFFFFFFFFFFF)"),
arg_str0("t", "keytype", "<A|B>", "key type (A or B) to authenticate sector 0 (default: A)"),
arg_str0("k", "key", "<key (hex 6 Bytes)>", "key to authenticate sector 0 (default: FFFFFFFFFFFF)"),
arg_str1(NULL, NULL, "<UIDF0|UIDF1|UIDF2|UIDF3>", "Personalization Option"),
arg_param_end
};
@ -5276,7 +5271,7 @@ static command_t CommandTable[] = {
{"ecfill", CmdHF14AMfECFill, IfPm3Iso14443a, "Fill simulator memory with help of keys from simulator"},
{"eclr", CmdHF14AMfEClear, IfPm3Iso14443a, "Clear simulator memory"},
{"egetblk", CmdHF14AMfEGetBlk, IfPm3Iso14443a, "Get simulator memory block"},
{"egetsc", CmdHF14AMfEGetSc, IfPm3Iso14443a, "Get simulator memory sector"},
{"egetsc", CmdHF14AMfEGetSc, IfPm3Iso14443a, "Get simulator memory sector"},
{"ekeyprn", CmdHF14AMfEKeyPrn, IfPm3Iso14443a, "Print keys from simulator memory"},
{"eload", CmdHF14AMfELoad, IfPm3Iso14443a, "Load from file emul dump"},
{"esave", CmdHF14AMfESave, IfPm3Iso14443a, "Save to file emul dump"},

View file

@ -488,7 +488,7 @@ static const char *getstatus(uint16_t *sw) {
return "Current authentication status does not allow the requested command";
case MFDES_E_BOUNDARY:
return "Attempted to read/write data from/to beyong the file's/record's limit";
return "Attempted to read/write data from/to beyond the file's/record's limit";
case MFDES_E_PICC_INTEGRITY:
return "PICC integrity error, PICC will be disabled";
@ -653,7 +653,7 @@ static nxp_cardtype_t getCardType(uint8_t major, uint8_t minor) {
return DESFIRE_EV3;
if (major == 0x30 && minor == 0x00)
return DESFIRE_LIGHT;
if (major == 0x11 && minor == 0x00)
if (major == 0x11 && minor == 0x00)
return PLUS_EV1;
if (major == 0x10 && minor == 0x00)
return NTAG413DNA;
@ -2079,12 +2079,12 @@ static int CmdHF14ADesSelectApp(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes selectaid",
"Select Application ID",
"Usage:\n\thf mfdes selectaid -a 123456\n"
"hf mfdes selectaid -a 123456"
);
void *argtable[] = {
arg_param_begin,
arg_strx0("aA", "aid", "<aid>", "App ID to select as hex bytes (3 bytes,big endian)"),
arg_strx0("a", "aid", "<aid>", "App ID to select as hex bytes (3 bytes,big endian)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -2114,16 +2114,16 @@ static int CmdHF14ADesCreateApp(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes createaid",
"Create Application ID",
"Usage:\n\thf mfdes createaid -a 123456 -f 1111 -k 0E -l 2E -n Test\n"
"hf mfdes createaid -a 123456 -f 1111 -k 0E -l 2E -n Test"
);
void *argtable[] = {
arg_param_begin,
arg_strx0("aA", "aid", "<aid>", "App ID to create as hex bytes ("),
arg_strx0("fF", "fid", "<fid>", "File ID to create (optional)"),
arg_strx0("kK", "keysetting1", "<keysetting1>", "Key Setting 1 (Application Master Key Settings)"),
arg_strx0("lL", "keysetting2", "<keysetting2>", "Key Setting 2"),
arg_str0("nN", "name", "<name>", "App ISO-4 Name (optional)"),
arg_strx0("a", "aid", "<aid>", "App ID to create as hex bytes (3 hex bytes)"),
arg_strx0("f", "fid", "<fid>", "File ID to create (optional)"),
arg_strx0("k", "ks1", "<keysetting1>", "Key Setting 1 (Application Master Key Settings)"),
arg_strx0("l", "ks2", "<keysetting2>", "Key Setting 2"),
arg_str0("n", "name", "<name>", "App ISO-4 Name (optional)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -2242,13 +2242,13 @@ static int CmdHF14ADesDeleteApp(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes deleteaid",
"Delete Application ID",
"Usage:\n\t-a aid (3 hex bytes, big endian)\n\n"
"Example:\n\thf mfdes deleteaid -a 123456\n"
// "Usage:\n\t-a aid (3 hex bytes, big endian)\n\n"
"hf mfdes deleteaid -a 123456"
);
void *argtable[] = {
arg_param_begin,
arg_strx0("aA", "aid", "<aid>", "App ID to delete"),
arg_strx0("a", "aid", "<aid>", "App ID (3 hex bytes, big endian) to delete"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -2305,17 +2305,15 @@ static int selectfile(uint8_t *aid, uint32_t fileno, uint8_t *cs) {
static int CmdHF14ADesClearRecordFile(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes clearrecord",
"Clear record file",
"Usage:\n\t"
"hf mfdes clearrecord -n 01\n"
"Make sure to select aid or authenticate aid before running this command.\n"
CLIParserInit(&ctx, "hf mfdes clearfile",
"Clear record file\nMake sure to select aid or authenticate aid before running this command.",
"hf mfdes clearfile -n 01"
);
void *argtable[] = {
arg_param_begin,
arg_strx0("nN", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
arg_strx0("aA", "aid", "<aid>", "App ID to select as hex bytes (3 bytes,big endian,optional)"),
arg_strx0("n", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
arg_strx0("a", "aid", "<aid>", "App ID to select as hex bytes (3 bytes, big endian, optional)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -2369,15 +2367,13 @@ static int CmdHF14ADesDeleteFile(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes deletefile",
"Delete File",
"Usage:\n\t"
"hf mfdes deletefile -n 01\n"
"Make sure to select aid or authenticate aid before running this command.\n"
"hf mfdes deletefile -n 01 -> Make sure to select aid or authenticate aid before running this command."
);
void *argtable[] = {
arg_param_begin,
arg_strx0("nN", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
arg_strx0("aA", "aid", "<aid>", "App ID to select as hex bytes (3 bytes,big endian,optional)"),
arg_strx0("n", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
arg_strx0("a", "aid", "<aid>", "App ID to select as hex bytes (3 bytes,big endian,optional)"),
arg_param_end
};
@ -2431,19 +2427,19 @@ static int CmdHF14ADesCreateFile(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes createfile",
"Create Standard/Backup File",
"Usage:"
"\n\thf mfdes createfile -f 0001 -n 01 -c 0 -r EEEE -s 000100 -a 123456\n"
"hf mfdes createfile -f 0001 -n 01 -c 0 -r EEEE -s 000100 -a 123456"
);
void *argtable[] = {
arg_param_begin,
arg_strx0("nN", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
arg_strx0("fF", "fileid", "<fileid>", "ISO FID (2 hex bytes, big endian)"),
arg_int0("cC", "com.set", "<comset>", "Communication setting (0=Plain,1=Plain+MAC,3=Enciphered)"),
arg_strx0("rR", "accessrights", "<accessrights>", "Access rights (2 hex bytes -> RW/Chg/R/W, 0-D Key, E Free, F Denied)"),
arg_strx0("sS", "filesize", "<filesize>", "File size (3 hex bytes, big endian)"),
arg_lit0("bB", "backup", "Create backupfile instead of standard file"),
arg_strx0("aA", "aid", "<aid>", "App ID to select as hex bytes (3 bytes,big endian)"),
arg_strx0("n", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
arg_strx0("f", "fileid", "<fileid>", "ISO FID (2 hex bytes, big endian)"),
arg_int0("c", "com.set", "<comset>", "Communication setting (0=Plain,1=Plain+MAC,3=Enciphered)"),
// arg_strx0("r", "accessrights", "<accessrights>", "Access rights (2 hex bytes -> RW/Chg/R/W, 0-D Key, E Free, F Denied)"),
arg_strx0("r", "rights", "<accessrights>", "Access rights (2 hex bytes -> RW/Chg/R/W, 0-D Key, E Free, F Denied)"),
arg_strx0("s", "filesize", "<filesize>", "File size (3 hex bytes, big endian)"),
arg_lit0("b", "backup", "Create backupfile instead of standard file"),
arg_strx0("a", "aid", "<aid>", "App ID to select as hex bytes (3 bytes,big endian)"),
arg_param_end
};
@ -2548,16 +2544,15 @@ static int CmdHF14ADesCreateFile(const char *Cmd) {
static int CmdHF14ADesGetValueData(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes getvalue",
"Get value from value file",
"Usage:"
"\n\thf mfdes getvalue -n 03\n"
"Make sure to select aid or authenticate aid before running this command.\n"
"Get value from value file\n"
"Make sure to select aid or authenticate aid before running this command.",
"hf mfdes getvalue -n 03"
);
void *argtable[] = {
arg_param_begin,
arg_strx0("nN", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
arg_strx0("aA", "aid", "<aid>", "App ID to select as hex bytes (3 bytes,big endian)"),
arg_strx0("n", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
arg_strx0("a", "aid", "<aid>", "App ID to select as hex bytes (3 bytes,big endian)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -2620,21 +2615,19 @@ static int CmdHF14ADesGetValueData(const char *Cmd) {
static int CmdHF14ADesReadData(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes readdata",
"Read data from File",
"Usage:"
"\n\thf mfdes readdata -n 01 -t 0 -o 000000 -l 000000 -a 123456\n"
"\thf mfdes readdata -n 01 -t 0 (Read all data from standard file, fileno 01)\n"
"Make sure to select aid or authenticate aid before running this command.\n"
"Read data from File\n"
"Make sure to select aid or authenticate aid before running this command.",
"hf mfdes readdata -n 01 -t 0 -o 000000 -l 000000 -a 123456\n"
"hf mfdes readdata -n 01 -t 0 -> Read all data from standard file, fileno 01"
);
void *argtable[] = {
arg_param_begin,
arg_strx0("nN", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
arg_strx0("oO", "offset", "<offset>", "File Offset (3 hex bytes, big endian), optional"),
arg_strx0("lL", "length", "<length>",
"Length to read (3 hex bytes, big endian -> 000000 = Read all data),optional"),
arg_int0("tT", "type", "<type>", "File Type (0=Standard/Backup, 1=Record)"),
arg_strx0("aA", "aid", "<aid>", "App ID to select as hex bytes (3 bytes,big endian,optional)"),
arg_strx0("n", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
arg_strx0("o", "offset", "<offset>", "File Offset (3 hex bytes, big endian), optional"),
arg_strx0("l", "length", "<length>", "Length to read (3 hex bytes, big endian -> 000000 = Read all data),optional"),
arg_int0("t", "type", "<type>", "File Type (0=Standard/Backup, 1=Record)"),
arg_strx0("a", "aid", "<aid>", "App ID to select as hex bytes (3 bytes,big endian,optional)"),
arg_param_end
};
@ -2743,18 +2736,17 @@ static int CmdHF14ADesReadData(const char *Cmd) {
static int CmdHF14ADesChangeValue(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes changevalue",
"Change value (credit/limitedcredit/debit)",
"Usage:"
"\n\thf mfdes changevalue -n 03 -m 0 -d 00000001\n"
"Make sure to select aid or authenticate aid before running this command.\n"
"Change value (credit/limitedcredit/debit)\n"
"Make sure to select aid or authenticate aid before running this command.",
"hf mfdes changevalue -n 03 -m 0 -d 00000001"
);
void *argtable[] = {
arg_param_begin,
arg_strx0("nN", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
arg_strx0("dD", "value", "<value>", "Value to increase (4 hex bytes, big endian)"),
arg_int0("mM", "mode", "<mode>", "Mode (0=Credit, 1=LimitedCredit, 2=Debit)"),
arg_strx0("aA", "aid", "<aid>", "App ID to select as hex bytes (3 bytes,big endian)"),
arg_strx0("n", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
arg_strx0("d", "value", "<value>", "Value to increase (4 hex bytes, big endian)"),
arg_int0("m", "mode", "<mode>", "Mode (0=Credit, 1=LimitedCredit, 2=Debit)"),
arg_strx0("a", "aid", "<aid>", "App ID to select as hex bytes (3 bytes,big endian)"),
arg_param_end
};
@ -2841,19 +2833,18 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes writedata",
"Write data to File",
"Usage:"
"\n\thf mfdes writedata -n 01 -t 0 -o 000000 -d 3132333435363738\n"
"Make sure to select aid or authenticate aid before running this command.\n"
"Write data to File\n"
"Make sure to select aid or authenticate aid before running this command.",
"hf mfdes writedata -n 01 -t 0 -o 000000 -d 3132333435363738"
);
void *argtable[] = {
arg_param_begin,
arg_strx0("nN", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
arg_strx0("oO", "offset", "<offset>", "File Offset (3 hex bytes, big endian), optional"),
arg_strx0("dD", "data", "<data>", "Data to write (hex bytes, 0xFFFF bytes max.)"),
arg_int0("type", "type", "<type>", "File Type (0=Standard/Backup, 1=Record)"),
arg_strx0("aA", "aid", "<aid>", "App ID to select as hex bytes (3 bytes,big endian, optional)"),
arg_strx0("n", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
arg_strx0("o", "offset", "<offset>", "File Offset (3 hex bytes, big endian), optional"),
arg_strx0("d", "data", "<data>", "Data to write (hex bytes, 256 bytes max)"),
arg_int0("t", "type", "<type>", "File Type (0=Standard/Backup, 1=Record)"),
arg_strx0("a", "aid", "<aid>", "App ID to select as hex bytes (3 bytes, big endian, optional)"),
arg_param_end
};
@ -2947,22 +2938,23 @@ static int CmdHF14ADesWriteData(const char *Cmd) {
static int CmdHF14ADesCreateRecordFile(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes createrecordfile",
"Create Linear/Cyclic Record File",
"Usage:"
"\n\thf mfdes createrecordfile -f 1122 -n 02 -c 0 -r EEEE -s 000010 -m 000005 -a 123456\n"
"Make sure to select aid or authenticate aid before running this command.\n"
"Create Linear/Cyclic Record File\n"
"Make sure to select aid or authenticate aid before running this command.",
"hf mfdes createrecordfile -f 1122 -n 02 -c 0 -r EEEE -s 000010 -m 000005 -a 123456"
);
void *argtable[] = {
arg_param_begin,
arg_strx0("nN", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
arg_strx0("fF", "fileid", "<fileid>", "ISO FID (2 hex bytes, big endian)"),
arg_int0("cC", "com.set", "<comset>", "Communication setting (0=Plain,1=Plain+MAC,3=Enciphered)"),
arg_strx0("rR", "accessrights", "<accessrights>", "Access rights (2 hex bytes -> RW/Chg/R/W, 0-D Key, E Free, F Denied)"),
arg_strx0("sS", "recordsize", "<recordsize>", "Record size (3 hex bytes, big endian, 000001 to FFFFFF)"),
arg_strx0("mM", "maxnumrecord", "<maxnumrecord>", "Max. Number of Records (3 hex bytes, big endian)"),
arg_lit0("bB", "cyclic", "Create cyclic record file instead of linear record file"),
arg_strx0("aA", "aid", "<aid>", "App ID to select as hex bytes (3 bytes,big endian,optional)"),
arg_strx0("n", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
arg_strx0("f", "fileid", "<fileid>", "ISO FID (2 hex bytes, big endian)"),
arg_int0("c", "com.set", "<comset>", "Communication setting (0=Plain,1=Plain+MAC,3=Enciphered)"),
// arg_strx0("r", "accessrights", "<accessrights>", "Access rights (2 hex bytes -> RW/Chg/R/W, 0-D Key, E Free, F Denied)"),
// arg_strx0("s", "recordsize", "<recordsize>", "Record size (3 hex bytes, big endian, 000001 to FFFFFF)"),
arg_strx0("r", "rights", "<accessrights>", "Access rights (2 hex bytes -> RW/Chg/R/W, 0-D Key, E Free, F Denied)"),
arg_strx0("s", "size", "<recordsize>", "Record size (3 hex bytes, big endian, 000001 to FFFFFF)"),
arg_strx0("m", "maxrecord", "<maxrecord>", "Max. Number of Records (3 hex bytes, big endian)"),
arg_lit0("b", "cyclic", "Create cyclic record file instead of linear record file"),
arg_strx0("a", "aid", "<aid>", "App ID to select as hex bytes (3 bytes,big endian,optional)"),
arg_param_end
};
@ -3082,22 +3074,21 @@ static int CmdHF14ADesCreateRecordFile(const char *Cmd) {
static int CmdHF14ADesCreateValueFile(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes createvaluefile",
"Create Value File",
"Usage:"
"\n\thf mfdes createvaluefile -n 03 -c 0 -r EEEE -l 00000000 -u 00002000 -v 00000001 -m 02 -a 123456\n"
"Make sure to select aid or authenticate aid before running this command.\n"
"Create Value File\n"
"Make sure to select aid or authenticate aid before running this command.",
"hf mfdes createvaluefile -n 03 -c 0 -r EEEE -l 00000000 -u 00002000 -v 00000001 -m 02 -a 123456\n"
);
void *argtable[] = {
arg_param_begin,
arg_strx0("nN", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
arg_int0("cC", "com.set", "<comset>", "Communication setting (0=Plain,1=Plain+MAC,3=Enciphered)"),
arg_strx0("rR", "accessrights", "<accessrights>", "Access rights (2 hex bytes -> RW/Chg/R/W, 0-D Key, E Free, F Denied)"),
arg_strx0("lL", "lowerlimit", "<lowerlimit>", "Lower limit (4 hex bytes, big endian)"),
arg_strx0("uU", "upperlimit", "<upperlimit>", "Upper limit (4 hex bytes, big endian)"),
arg_strx0("vV", "value", "<value>", "Value (4 hex bytes, big endian)"),
arg_strx0("mM", "limitcredit", "<limitcredit>", "Limited Credit enabled (1 hex byte [Bit 0=LimitedCredit, 1=FreeValue])"),
arg_strx0("aA", "aid", "<aid>", "App ID to select as hex bytes (3 bytes,big endian,optional)"),
arg_strx0("n", "fileno", "<fileno>", "File Number (1 hex byte, 0x00 - 0x1F)"),
arg_int0("c", "com.set", "<comset>", "Communication setting (0=Plain,1=Plain+MAC,3=Enciphered)"),
arg_strx0("r", "rights", "<accessrights>", "Access rights (2 hex bytes -> RW/Chg/R/W, 0-D Key, E Free, F Denied)"),
arg_strx0("l", "lowerlimit", "<lowerlimit>", "Lower limit (4 hex bytes, big endian)"),
arg_strx0("u", "upperlimit", "<upperlimit>", "Upper limit (4 hex bytes, big endian)"),
arg_strx0("v", "value", "<value>", "Value (4 hex bytes, big endian)"),
arg_strx0("m", "limitcredit", "<limitcredit>", "Limited Credit enabled (1 hex byte [Bit 0=LimitedCredit, 1=FreeValue])"),
arg_strx0("a", "aid", "<aid>", "App ID to select as hex bytes (3 bytes,big endian,optional)"),
arg_param_end
};
@ -3215,11 +3206,15 @@ static int CmdHF14ADesCreateValueFile(const char *Cmd) {
static int CmdHF14ADesFormatPICC(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes formatpicc",
"Formats MIFARE DESFire PICC to factory state",
"Usage:"
"\n\thf mfdes formatpicc\n"
"Make sure to authenticate picc before running this command.\n"
"Formats MIFARE DESFire PICC to factory state\n"
"Make sure to authenticate picc before running this command.",
"hf mfdes formatpicc"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
sAPDU apdu = {0x90, MFDES_FORMAT_PICC, 0x00, 0x00, 0, NULL}; // 0xDF
uint16_t sw = 0;
@ -3324,10 +3319,10 @@ static int CmdHF14ADesInfo(const char *Cmd) {
if (major == 0 && minor == 2)
PrintAndLogEx(INFO, "\t0.2 - DESFire Light, Originality check, ");
if (cardtype == DESFIRE_EV2 ||
cardtype == DESFIRE_LIGHT ||
cardtype == DESFIRE_EV3 ||
cardtype == NTAG413DNA) {
if (cardtype == DESFIRE_EV2 ||
cardtype == DESFIRE_LIGHT ||
cardtype == DESFIRE_EV3 ||
cardtype == NTAG413DNA) {
// Signature originality check
uint8_t signature[56] = {0};
size_t signature_len = 0;
@ -3761,20 +3756,19 @@ static int CmdHF14ADesChangeKey(const char *Cmd) {
uint8_t newkeylength = 8;
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes changekey",
"Changes Mifare DESFire Key",
"Usage:"
"\n\thf mfdes changekey -n 0 -t 1 -k 0000000000000000 -u 1 -j 0102030405060708 (DES,keynumber 0)\n"
"Make sure to select aid or authenticate aid before running this command.\n"
"Changes Mifare DESFire Key\n"
"Make sure to select aid or authenticate aid before running this command.",
"hf mfdes changekey -n 0 -t 1 -k 0000000000000000 -u 1 -j 0102030405060708 -> DES,keynumber 0"
);
void *argtable[] = {
arg_param_begin,
arg_int0("nN", "keyno", "<keyno>", "Key number used for authentification"),
arg_int0("tT", "algo", "<algo>", "Current key algo (1=DES, 2=3DES(2K2DES), 3=3K3DES, 4=AES)"),
arg_str0("kK", "key", "<Key>", "Current Key (HEX 8-24 bytes)"),
arg_int0("uU", "newalgo", "<newalgo>", "New key algo (1=DES, 2=3DES(2K2DES), 3=3K3DES, 4=AES)"),
arg_str0("jJ", "newkey", "<newkey>", "New Key (HEX 8-24 bytes)"),
arg_int0("vV", "aesversion", "<aesversion>", "Aes version (if aes is used)"),
arg_int0("n", "keyno", "<keyno>", "Key number used for authentification"),
arg_int0("t", "algo", "<algo>", "Current key algo (1=DES, 2=3DES(2K2DES), 3=3K3DES, 4=AES)"),
arg_str0("k", "key", "<Key>", "Current Key (HEX 8-24 bytes)"),
arg_int0("u", "newalgo", "<newalgo>", "New key algo (1=DES, 2=3DES(2K2DES), 3=3K3DES, 4=AES)"),
arg_str0("j", "newkey", "<newkey>", "New Key (HEX 8-24 bytes)"),
arg_int0("v", "aesversion", "<aesversion>", "Aes version (if aes is used)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -3860,23 +3854,22 @@ static int CmdHF14ADesAuth(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes auth",
"Authenticates Mifare DESFire using Key",
"Usage:"
"\n\thf mfdes auth -m 3 -t 4 -a 808301 -n 0 -k 00000000000000000000000000000000 (AES,keynumber 0, aid 0x803201)"
"\n\thf mfdes auth -m 2 -t 2 -a 000000 -n 1 -k 00000000000000000000000000000000 (3DES,keynumber 1, aid 0x000000)"
"\n\thf mfdes auth -m 1 -t 1 -a 000000 -n 2 -k 0000000000000000 (DES,keynumber 2, aid 0x000000)"
"\n\thf mfdes auth -m 1 -t 1 -a 000000 -n 0 (DES, defaultkey, aid 0x000000)"
"\n\thf mfdes auth -m 2 -t 2 -a 000000 -n 0 (3DES, defaultkey, aid 0x000000)"
"\n\thf mfdes auth -m 3 -t 4 -a 000000 -n 0 (3K3DES, defaultkey, aid 0x000000)"
"\n\thf mfdes auth -m 3 -t 4 -a 000000 -n 0 (AES, defaultkey, aid 0x000000)"
"hf mfdes auth -m 3 -t 4 -a 808301 -n 0 -k 00000000000000000000000000000000 -> AES,keynumber 0, aid 0x803201\n"
"hf mfdes auth -m 2 -t 2 -a 000000 -n 1 -k 00000000000000000000000000000000 -> 3DES,keynumber 1, aid 0x000000\n"
"hf mfdes auth -m 1 -t 1 -a 000000 -n 2 -k 0000000000000000 -> DES,keynumber 2, aid 0x000000\n"
"hf mfdes auth -m 1 -t 1 -a 000000 -n 0 -> DES, defaultkey, aid 0x000000\n"
"hf mfdes auth -m 2 -t 2 -a 000000 -n 0 -> 3DES, defaultkey, aid 0x000000\n"
"hf mfdes auth -m 3 -t 4 -a 000000 -n 0 -> 3K3DES, defaultkey, aid 0x000000\n"
"hf mfdes auth -m 3 -t 4 -a 000000 -n 0 -> AES, defaultkey, aid 0x000000"
);
void *argtable[] = {
arg_param_begin,
arg_int0("mM", "type", "<type>", "Auth type (1=normal, 2=iso, 3=aes)"),
arg_int0("tT", "algo", "<algo>", "Crypt algo (1=DES, 2=3DES(2K2DES), 3=3K3DES, 4=AES)"),
arg_strx0("aA", "aid", "<aid>", "AID used for authentification (HEX 3 bytes)"),
arg_int0("nN", "keyno", "<keyno>", "Key number used for authentification"),
arg_str0("kK", "key", "<Key>", "Key for checking (HEX 8-24 bytes)"),
arg_int0("m", "type", "<type>", "Auth type (1=normal, 2=iso, 3=aes)"),
arg_int0("t", "algo", "<algo>", "Crypt algo (1=DES, 2=3DES(2K2DES), 3=3K3DES, 4=AES)"),
arg_strx0("a", "aid", "<aid>", "AID used for authentification (HEX 3 bytes)"),
arg_int0("n", "keyno", "<keyno>", "Key number used for authentification"),
arg_str0("k", "key", "<Key>", "Key for checking (HEX 8-24 bytes)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -4222,23 +4215,22 @@ static int CmdHF14aDesChk(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes chk",
"Checks keys with Mifare Desfire card.",
"Usage:\n"
" hf mfdes chk -a 123456 -k 000102030405060708090a0b0c0d0e0f -> check key on aid 0x123456\n"
" hf mfdes chk -d mfdes_default_keys -> check keys from dictionary against all existing aid on card\n"
" hf mfdes chk -d mfdes_default_keys -a 123456 -> check keys from dictionary against aid 0x123456\n"
" hf mfdes chk -a 123456 --pattern1b -j keys -> check all 1-byte keys pattern on aid 0x123456 and save found keys to json\n"
" hf mfdes chk -a 123456 --pattern2b --startp2b FA00 -> check all 2-byte keys pattern on aid 0x123456. Start from key FA00FA00...FA00\n");
"hf mfdes chk -a 123456 -k 000102030405060708090a0b0c0d0e0f -> check key on aid 0x123456\n"
"hf mfdes chk -d mfdes_default_keys -> check keys from dictionary against all existing aid on card\n"
"hf mfdes chk -d mfdes_default_keys -a 123456 -> check keys from dictionary against aid 0x123456\n"
"hf mfdes chk -a 123456 --pattern1b -j keys -> check all 1-byte keys pattern on aid 0x123456 and save found keys to json\n"
"hf mfdes chk -a 123456 --pattern2b --startp2b FA00 -> check all 2-byte keys pattern on aid 0x123456. Start from key FA00FA00...FA00");
void *argtable[] = {
arg_param_begin,
arg_strx0("aA", "aid", "<aid>", "Use specific AID (3 hex bytes, big endian)"),
arg_str0("kK", "key", "<Key>", "Key for checking (HEX 16 bytes)"),
arg_str0("dD", "dict", "<file>", "File with keys dictionary"),
arg_strx0("a", "aid", "<aid>", "Use specific AID (3 hex bytes, big endian)"),
arg_str0("k", "key", "<Key>", "Key for checking (HEX 16 bytes)"),
arg_str0("d", "dict", "<file>", "File with keys dictionary"),
arg_lit0(NULL, "pattern1b", "Check all 1-byte combinations of key (0000...0000, 0101...0101, 0202...0202, ...)"),
arg_lit0(NULL, "pattern2b", "Check all 2-byte combinations of key (0000...0000, 0001...0001, 0002...0002, ...)"),
arg_str0(NULL, "startp2b", "<Pattern>", "Start key (2-byte HEX) for 2-byte search (use with `--pattern2b`)"),
arg_str0("jJ", "json", "<file>", "Json file to save keys"),
arg_lit0("vV", "verbose", "Verbose mode."),
arg_str0("j", "json", "<file>", "Json file to save keys"),
arg_lit0("v", "verbose", "Verbose mode."),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -4489,17 +4481,16 @@ static int CmdHF14aDesNDEF(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfdes ndef",
"Prints NFC Data Exchange Format (NDEF)",
"Usage:\n"
_YELLOW_("\thf mfdes ndef") " -> shows NDEF data\n"
_YELLOW_("\thf mfdes ndef -vv") " -> shows NDEF parsed and raw data\n"
_YELLOW_("\thf mfdes ndef -a e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7") " -> shows NDEF data with custom AID and key\n");
"hf mfdes ndef -> shows NDEF data\n"
"hf mfdes ndef -v -> shows NDEF parsed and raw data\n"
"hf mfdes ndef -a e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data with custom AID and key");
void *argtable[] = {
arg_param_begin,
arg_litn("vV", "verbose", 0, 2, "show technical data"),
arg_litn("v", "verbose", 0, 2, "show technical data"),
arg_str0("", "aid", "<aid>", "replace default aid for NDEF"),
arg_str0("kK", "key", "<key>", "replace default key for NDEF"),
arg_lit0("bB", "keyb", "use key B for access sectors (by default: key A)"),
arg_str0("k", "key", "<key>", "replace default key for NDEF"),
arg_lit0("b", "keyb", "use key B for access sectors (by default: key A)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);

View file

@ -371,19 +371,22 @@ static int CmdHFMFPInfo(const char *Cmd) {
int res = ExchangeRAW14a(cmd, sizeof(cmd), true, false, data, sizeof(data), &datalen, false);
// DESFire answers 0x1C or 67 00
// Plus answers 0x0B, 0x09
if ( data[0] != 0x0b && data[0] != 0x09 && data[0] != 0x1C && data[0] != 0x67) {
// Plus answers 0x0B, 0x09, 0x06
// Which tag answers 6D 00 ??
if (data[0] != 0x0b && data[0] != 0x09 && data[0] != 0x1C && data[0] != 0x67) {
PrintAndLogEx(INFO, _RED_("Send copy to iceman of this command output!"));
PrintAndLogEx(INFO, "data: %s", sprint_hex(data, datalen));
}
if ((memcmp(data, "\x67\x00", 2) == 0) ||
(memcmp(data, "\x1C\x83\x0C", 3) == 0)
) {
(memcmp(data, "\x1C\x83\x0C", 3) == 0)
) {
PrintAndLogEx(INFO, " result: " _RED_("MIFARE DESFire"));
PrintAndLogEx(HINT, "Hint: Try " _YELLOW_("`hf mfdes info`"));
DropField();
return PM3_SUCCESS;
} else if (memcmp(data, "\x6D\x00", 2) == 0) {
isPlus = false;
} else {
PrintAndLogEx(INFO, " result: " _GREEN_("MIFARE Plus SL0/SL3"));
}
@ -436,12 +439,12 @@ static int CmdHFMFPWritePerso(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfp wrp",
"Executes Write Perso command. Can be used in SL0 mode only.",
"Usage:\n\thf mfp wrp 4000 000102030405060708090a0b0c0d0e0f -> write key (00..0f) to key number 4000 \n"
"\thf mfp wrp 4000 -> write default key(0xff..0xff) to key number 4000");
"hf mfp wrp 4000 000102030405060708090a0b0c0d0e0f -> write key (00..0f) to key number 4000 \n"
"hf mfp wrp 4000 -> write default key(0xff..0xff) to key number 4000");
void *argtable[] = {
arg_param_begin,
arg_lit0("vV", "verbose", "show internal data."),
arg_lit0("v", "verbose", "show internal data."),
arg_str1(NULL, NULL, "<HEX key number (2b)>", NULL),
arg_strx0(NULL, NULL, "<HEX key (16b)>", NULL),
arg_param_end
@ -503,12 +506,12 @@ static int CmdHFMFPInitPerso(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfp initp",
"Executes Write Perso command for all card's keys. Can be used in SL0 mode only.",
"Usage:\n\thf mfp initp 000102030405060708090a0b0c0d0e0f -> fill all the keys with key (00..0f)\n"
"\thf mfp initp -vv -> fill all the keys with default key(0xff..0xff) and show all the data exchange");
"hf mfp initp 000102030405060708090a0b0c0d0e0f -> fill all the keys with key (00..0f)\n"
"hf mfp initp -vv -> fill all the keys with default key(0xff..0xff) and show all the data exchange");
void *argtable[] = {
arg_param_begin,
arg_litn("vV", "verbose", 0, 2, "show internal data."),
arg_litn("v", "verbose", 0, 2, "show internal data."),
arg_strx0(NULL, NULL, "<HEX key (16b)>", NULL),
arg_param_end
};
@ -571,11 +574,11 @@ static int CmdHFMFPCommitPerso(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfp commitp",
"Executes Commit Perso command. Can be used in SL0 mode only.",
"Usage:\n\thf mfp commitp -> \n");
"hf mfp commitp");
void *argtable[] = {
arg_param_begin,
arg_lit0("vV", "verbose", "show internal data."),
arg_lit0("v", "verbose", "show internal data."),
arg_int0(NULL, NULL, "SL mode", NULL),
arg_param_end
};
@ -618,12 +621,12 @@ static int CmdHFMFPAuth(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfp auth",
"Executes AES authentication command for Mifare Plus card",
"Usage:\n\thf mfp auth 4000 000102030405060708090a0b0c0d0e0f -> executes authentication\n"
"\thf mfp auth 9003 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -v -> executes authentication and shows all the system data\n");
"hf mfp auth 4000 000102030405060708090a0b0c0d0e0f -> executes authentication\n"
"hf mfp auth 9003 FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -v -> executes authentication and shows all the system data");
void *argtable[] = {
arg_param_begin,
arg_lit0("vV", "verbose", "show internal data."),
arg_lit0("v", "verbose", "show internal data."),
arg_str1(NULL, NULL, "<Key Num (HEX 2 bytes)>", NULL),
arg_str1(NULL, NULL, "<Key Value (HEX 16 bytes)>", NULL),
arg_param_end
@ -656,15 +659,15 @@ static int CmdHFMFPRdbl(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfp rdbl",
"Reads several blocks from Mifare Plus card.",
"Usage:\n\thf mfp rdbl 0 000102030405060708090a0b0c0d0e0f -> executes authentication and read block 0 data\n"
"\thf mfp rdbl 1 -v -> executes authentication and shows sector 1 data with default key 0xFF..0xFF and some additional data\n");
"hf mfp rdbl 0 000102030405060708090a0b0c0d0e0f -> executes authentication and read block 0 data\n"
"hf mfp rdbl 1 -v -> executes authentication and shows sector 1 data with default key 0xFF..0xFF and some additional data");
void *argtable[] = {
arg_param_begin,
arg_lit0("vV", "verbose", "show internal data."),
arg_int0("nN", "count", "blocks count (by default 1).", NULL),
arg_lit0("bB", "keyb", "use key B (by default keyA)."),
arg_lit0("pP", "plain", "plain communication mode between reader and card."),
arg_lit0("v", "verbose", "show internal data."),
arg_int0("n", "count", "blocks count (by default 1).", NULL),
arg_lit0("b", "keyb", "use key B (by default keyA)."),
arg_lit0("p", "plain", "plain communication mode between reader and card."),
arg_int1(NULL, NULL, "<Block Num (0..255)>", NULL),
arg_str0(NULL, NULL, "<Key Value (HEX 16 bytes)>", NULL),
arg_param_end
@ -769,14 +772,14 @@ static int CmdHFMFPRdsc(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfp rdsc",
"Reads one sector from Mifare Plus card.",
"Usage:\n\thf mfp rdsc 0 000102030405060708090a0b0c0d0e0f -> executes authentication and read sector 0 data\n"
"\thf mfp rdsc 1 -v -> executes authentication and shows sector 1 data with default key 0xFF..0xFF and some additional data\n");
"hf mfp rdsc 0 000102030405060708090a0b0c0d0e0f -> executes authentication and read sector 0 data\n"
"hf mfp rdsc 1 -v -> executes authentication and shows sector 1 data with default key 0xFF..0xFF and some additional data");
void *argtable[] = {
arg_param_begin,
arg_lit0("vV", "verbose", "show internal data."),
arg_lit0("bB", "keyb", "use key B (by default keyA)."),
arg_lit0("pP", "plain", "plain communication mode between reader and card."),
arg_lit0("v", "verbose", "show internal data."),
arg_lit0("b", "keyb", "use key B (by default keyA)."),
arg_lit0("p", "plain", "plain communication mode between reader and card."),
arg_int1(NULL, NULL, "<Sector Num (0..255)>", NULL),
arg_str0(NULL, NULL, "<Key Value (HEX 16 bytes)>", NULL),
arg_param_end
@ -868,13 +871,13 @@ static int CmdHFMFPWrbl(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfp wrbl",
"Writes one block to Mifare Plus card.",
"Usage:\n\thf mfp wrbl 1 ff0000000000000000000000000000ff 000102030405060708090a0b0c0d0e0f -> writes block 1 data\n"
"\thf mfp wrbl 2 ff0000000000000000000000000000ff -v -> writes block 2 data with default key 0xFF..0xFF and some additional data\n");
"hf mfp wrbl 1 ff0000000000000000000000000000ff 000102030405060708090a0b0c0d0e0f -> writes block 1 data\n"
"hf mfp wrbl 2 ff0000000000000000000000000000ff -v -> writes block 2 data with default key 0xFF..0xFF and some additional data");
void *argtable[] = {
arg_param_begin,
arg_lit0("vV", "verbose", "show internal data."),
arg_lit0("bB", "keyb", "use key B (by default keyA)."),
arg_lit0("v", "verbose", "show internal data."),
arg_lit0("b", "keyb", "use key B (by default keyA)."),
arg_int1(NULL, NULL, "<Block Num (0..255)>", NULL),
arg_str1(NULL, NULL, "<Data (HEX 16 bytes)>", NULL),
arg_str0(NULL, NULL, "<Key (HEX 16 bytes)>", NULL),
@ -1070,26 +1073,25 @@ static int CmdHFMFPChk(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfp chk",
"Checks keys with Mifare Plus card.",
"Usage:\n"
" hf mfp chk -k 000102030405060708090a0b0c0d0e0f -> check key on sector 0 as key A and B\n"
" hf mfp chk -s 2 -a -> check default key list on sector 2, key A\n"
" hf mfp chk -d mfp_default_keys -s0 -e6 -> check keys from dictionary against sectors 0-6\n"
" hf mfp chk --pattern1b -j keys -> check all 1-byte keys pattern and save found keys to json\n"
" hf mfp chk --pattern2b --startp2b FA00 -> check all 2-byte keys pattern. Start from key FA00FA00...FA00\n");
"hf mfp chk -k 000102030405060708090a0b0c0d0e0f -> check key on sector 0 as key A and B\n"
"hf mfp chk -s 2 -a -> check default key list on sector 2, key A\n"
"hf mfp chk -d mfp_default_keys -s0 -e6 -> check keys from dictionary against sectors 0-6\n"
"hf mfp chk --pattern1b -j keys -> check all 1-byte keys pattern and save found keys to json\n"
"hf mfp chk --pattern2b --startp2b FA00 -> check all 2-byte keys pattern. Start from key FA00FA00...FA00");
void *argtable[] = {
arg_param_begin,
arg_lit0("aA", "keya", "check only key A (by default check all keys)."),
arg_lit0("bB", "keyb", "check only key B (by default check all keys)."),
arg_int0("sS", "startsec", "Start sector Num (0..255)", NULL),
arg_int0("eE", "endsec", "End sector Num (0..255)", NULL),
arg_str0("kK", "key", "<Key>", "Key for checking (HEX 16 bytes)"),
arg_str0("dD", "dict", "<file>", "file with keys dictionary"),
arg_lit0("a", "keya", "check only key A (by default check all keys)."),
arg_lit0("b", "keyb", "check only key B (by default check all keys)."),
arg_int0("s", "startsec", "Start sector Num (0..255)", NULL),
arg_int0("e", "endsec", "End sector Num (0..255)", NULL),
arg_str0("k", "key", "<Key>", "Key for checking (HEX 16 bytes)"),
arg_str0("d", "dict", "<file>", "file with keys dictionary"),
arg_lit0(NULL, "pattern1b", "check all 1-byte combinations of key (0000...0000, 0101...0101, 0202...0202, ...)"),
arg_lit0(NULL, "pattern2b", "check all 2-byte combinations of key (0000...0000, 0001...0001, 0002...0002, ...)"),
arg_str0(NULL, "startp2b", "<Pattern>", "Start key (2-byte HEX) for 2-byte search (use with `--pattern2b`)"),
arg_str0("jJ", "json", "<file>", "json file to save keys"),
arg_lit0("vV", "verbose", "verbose mode."),
arg_str0("j", "json", "<file>", "json file to save keys"),
arg_lit0("v", "verbose", "verbose mode."),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -1303,17 +1305,17 @@ static int CmdHFMFPMAD(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfp mad",
"Checks and prints Mifare Application Directory (MAD)",
"Usage:\n\thf mfp mad -> shows MAD if exists\n"
"\thf mfp mad -a e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data if exists\n");
"hf mfp mad -> shows MAD if exists\n"
"hf mfp mad -a e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data if exists");
void *argtable[] = {
arg_param_begin,
arg_lit0("vV", "verbose", "show technical data"),
arg_str0("", "aid", "<aid>", "print all sectors with aid"),
arg_str0("kK", "key", "<key>", "key for printing sectors"),
arg_lit0("bB", "keyb", "use key B for access printing sectors (by default: key A)"),
arg_lit0("", "be", "(optional, BigEndian)"),
arg_lit0("", "dch", "decode Card Holder information"),
arg_lit0("v", "verbose", "show technical data"),
arg_str0(NULL, "aid", "<aid>", "print all sectors with aid"),
arg_str0("k", "key", "<key>", "key for printing sectors"),
arg_lit0("b", "keyb", "use key B for access printing sectors (by default: key A)"),
arg_lit0(NULL, "be", "(optional, BigEndian)"),
arg_lit0(NULL, "dch", "decode Card Holder information"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
@ -1443,17 +1445,16 @@ static int CmdHFMFPNDEF(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfp ndef",
"Prints NFC Data Exchange Format (NDEF)",
"Usage:\n"
_YELLOW_("\thf mfp ndef") " -> shows NDEF data\n"
_YELLOW_("\thf mfp ndef -vv") " -> shows NDEF parsed and raw data\n"
_YELLOW_("\thf mfp ndef -a e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7") " -> shows NDEF data with custom AID and key\n");
"hf mfp ndef -> shows NDEF data\n"
"hf mfp ndef -vv -> shows NDEF parsed and raw data\n"
"hf mfp ndef -a e103 -k d3f7d3f7d3f7d3f7d3f7d3f7d3f7d3f7 -> shows NDEF data with custom AID and key");
void *argtable[] = {
arg_param_begin,
arg_litn("vV", "verbose", 0, 2, "show technical data"),
arg_str0("", "aid", "<aid>", "replace default aid for NDEF"),
arg_str0("kK", "key", "<key>", "replace default key for NDEF"),
arg_lit0("bB", "keyb", "use key B for access sectors (by default: key A)"),
arg_litn("v", "verbose", 0, 2, "show technical data"),
arg_str0(NULL, "aid", "<aid>", "replace default aid for NDEF"),
arg_str0("k", "key", "<key>", "replace default key for NDEF"),
arg_lit0("b", "keyb", "use key B for access sectors (by default: key A)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);

View file

@ -814,7 +814,7 @@ static int ulev1_print_configuration(uint32_t tagtype, uint8_t *data, uint8_t st
break;
}
// valid mirror start page and byte position within start page.
if ((tagtype & NTAG_213_F)||(tagtype & NTAG_213_TT)) {
if ((tagtype & NTAG_213_F) || (tagtype & NTAG_213_TT)) {
switch (mirror_conf) {
case 1:
{ PrintAndLogEx(INFO, " mirror start block %02X | byte pos %02X - %s", data[2], mirror_byte, (data[2] >= 0x4 && data[2] <= 0x24) ? "OK" : "Invalid value"); break;}
@ -1116,7 +1116,7 @@ uint32_t GetHF14AMfU_Type(void) {
else if (memcmp(version, "\x00\x04\x04\x01\x01\x00\x0B", 7) == 0) { tagtype = NTAG_210; break; }
else if (memcmp(version, "\x00\x04\x04\x01\x01\x00\x0E", 7) == 0) { tagtype = NTAG_212; break; }
else if (memcmp(version, "\x00\x04\x04\x02\x01\x00\x0F", 7) == 0) { tagtype = NTAG_213; break; }
else if (memcmp(version, "\x00\x04\x04\x02\x01\x01\x0F", 7) == 0) { tagtype = NTAG_213_C; break; }
else if (memcmp(version, "\x00\x04\x04\x02\x01\x01\x0F", 7) == 0) { tagtype = NTAG_213_C; break; }
else if (memcmp(version, "\x00\x04\x04\x02\x01\x00\x11", 7) == 0) { tagtype = NTAG_215; break; }
else if (memcmp(version, "\x00\x04\x04\x02\x01\x00\x13", 7) == 0) { tagtype = NTAG_216; break; }
else if (memcmp(version, "\x00\x04\x04\x04\x01\x00\x0F", 7) == 0) { tagtype = NTAG_213_F; break; }
@ -1466,7 +1466,7 @@ static int CmdHF14AMfUInfo(const char *Cmd) {
if (ul_auth_select(&card, tagtype, hasAuthKey, authkeyptr, pack, sizeof(pack)) == PM3_ESOFT) return PM3_ESOFT;
}
}
if (len < 1) {
if (len < 1) {
PrintAndLogEx(WARNING, _YELLOW_("password not known"));
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`hf mfu pwdgen r`") " to get see known pwd gen algo suggestions");
}
@ -2954,13 +2954,13 @@ static int CmdHF14MfuNDEF(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf mfu ndef",
"Prints NFC Data Exchange Format (NDEF)",
"Usage:\n\thf mfu ndef -> shows NDEF data\n"
"\thf mfu ndef -k ffffffff -> shows NDEF data with key\n");
"hf mfu ndef -> shows NDEF data\n"
"hf mfu ndef -k ffffffff -> shows NDEF data with key");
void *argtable[] = {
arg_param_begin,
arg_str0("kK", "key", "replace default key for NDEF", NULL),
arg_lit0("lL", "key", "(optional) swap entered key's endianness"),
arg_str0("k", "key", "replace default key for NDEF", NULL),
arg_lit0("l", "key", "(optional) swap entered key's endianness"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);

View file

@ -14,6 +14,7 @@
#include "cmdparser.h" // command_t
#include "comms.h" // clearCommandBuffer
#include "cmdtrace.h"
#include "cliparser.h"
#include "crc16.h"
#include "cmdhf14a.h"
#include "protocols.h" // definitions of ISO14A/7816 protocol
@ -21,65 +22,9 @@
#include "mifare/ndef.h" // NDEFRecordsDecodeAndPrint
#define TIMEOUT 2000
static int CmdHelp(const char *Cmd);
static int usage_hf_st_info(void) {
PrintAndLogEx(NORMAL, "Usage: hf st info [h]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h this help");
PrintAndLogEx(NORMAL, "Example:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf st info"));
return PM3_SUCCESS;
}
static int usage_hf_st_sim(void) {
PrintAndLogEx(NORMAL, "\n Emulating ST25TA512B tag with 7 byte UID\n");
PrintAndLogEx(NORMAL, "Usage: hf st sim [h] u <uid> ");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : This help");
PrintAndLogEx(NORMAL, " u : 7 byte UID");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf st sim u 02E2007D0FCA4C"));
return PM3_SUCCESS;
}
static int usage_hf_st_ndef(void) {
PrintAndLogEx(NORMAL, "\n Print NFC Data Exchange Format (NDEF)\n");
PrintAndLogEx(NORMAL, "Usage: hf st ndef [h] p <pwd> ");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : This help");
PrintAndLogEx(NORMAL, " p <pwd> : 16 byte password");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf st ndef p 82E80053D4CA5C0B656D852CC696C8A1"));
return PM3_SUCCESS;
}
static int usage_hf_st_protect(void) {
PrintAndLogEx(NORMAL, "\n Change R/W protection for NFC Data Exchange Format (NDEF)\n");
PrintAndLogEx(NORMAL, "Usage: hf st protect [h] p <pwd> r|w [0|1]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : This help");
PrintAndLogEx(NORMAL, " p <pwd> : 16 byte write password");
PrintAndLogEx(NORMAL, " r|w : Change (r)ead or (w)rite protection");
PrintAndLogEx(NORMAL, " [0|1] : Enable / Disable protection");
PrintAndLogEx(NORMAL, " 0 = Disable (default)");
PrintAndLogEx(NORMAL, " 1 = Enable");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf st protect p 82E80053D4CA5C0B656D852CC696C8A1 r 0"));
return PM3_SUCCESS;
}
static int usage_hf_st_pwd(void) {
PrintAndLogEx(NORMAL, "\n Change R/W password for NFC Data Exchange Format (NDEF)\n");
PrintAndLogEx(NORMAL, "Usage: hf st pwd [h] p <pwd> r|w n <newpwd>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : This help");
PrintAndLogEx(NORMAL, " p <pwd> : 16 byte write password");
PrintAndLogEx(NORMAL, " r|w : Change (r)ead or (w)rite password");
PrintAndLogEx(NORMAL, " n <newpwd> : New 16 byte password");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" hf st pwd p 82E80053D4CA5C0B656D852CC696C8A1 r n 00000000000000000000000000000000"));
return PM3_SUCCESS;
}
// get ST Microelectronics chip model (from UID)
static char *get_st_chip_model(uint8_t pc) {
static char model[40];
@ -348,26 +293,44 @@ int infoHF_ST(void) {
return PM3_SUCCESS;
}
// menu command to get and print all info known about any known 14b tag
// menu command to get and print all info known about any known ST25TA tag
static int cmd_hf_st_info(const char *Cmd) {
char c = tolower(param_getchar(Cmd, 0));
if (c == 'h') return usage_hf_st_info();
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf st info",
"Get info about ST25TA tag",
"hf st info"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
return infoHF_ST();
}
static int cmd_hf_st_sim(const char *Cmd) {
char c = tolower(param_getchar(Cmd, 0));
if (c == 'h' || c == 0x00) return usage_hf_st_sim();
int uidlen = 0;
uint8_t cmdp = 0;
uint8_t uid[7] = {0};
if (c == 'u') {
param_gethex_ex(Cmd, cmdp + 1, uid, &uidlen);
uidlen >>= 1;
if (uidlen != 7) {
return usage_hf_st_sim();
}
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf st sim",
"Emulating ST25TA512B tag with 7 byte UID",
"hf st sim -u 02E2007D0FCA4C\n");
void *argtable[] = {
arg_param_begin,
arg_str1("u", "uid", "<hex>", "7 byte UID"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
CLIGetHexWithReturn(ctx, 1, uid, &uidlen);
if (uidlen != 7) {
PrintAndLogEx(ERR, "UID must be 7 hex bytes");
return PM3_EINVARG;
}
char param[40];
@ -376,18 +339,32 @@ static int cmd_hf_st_sim(const char *Cmd) {
}
static int cmd_hf_st_ndef(const char *Cmd) {
char c = tolower(param_getchar(Cmd, 0));
if (c == 'h' || c == 0x00) return usage_hf_st_ndef();
int pwdlen = 0;
uint8_t cmdp = 0;
uint8_t pwd[16] = {0};
if (c == 'p') {
param_gethex_ex(Cmd, cmdp + 1, pwd, &pwdlen);
pwdlen >>= 1;
bool with_pwd = false;
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf st ndef",
"Read NFC Data Exchange Format (NDEF) file on ST25TA",
"hf st ndef -p 82E80053D4CA5C0B656D852CC696C8A1\n");
void *argtable[] = {
arg_param_begin,
arg_str0("p", "password", "<hex>", "16 byte read password"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIGetHexWithReturn(ctx, 1, pwd, &pwdlen);
if (pwdlen == 0) {
with_pwd = false;
} else {
if (pwdlen != 16) {
return usage_hf_st_ndef();
PrintAndLogEx(ERR, "Password must be 16 hex bytes");
return PM3_EINVARG;
}
with_pwd = true;
}
bool activate_field = true;
@ -429,27 +406,29 @@ static int cmd_hf_st_ndef(const char *Cmd) {
return PM3_ESOFT;
}
// --------------- VERIFY ----------------
uint8_t aVERIFY[30];
int aVERIFY_n = 0;
param_gethex_to_eol("0020000100", 0, aVERIFY, sizeof(aVERIFY), &aVERIFY_n);
res = ExchangeAPDU14a(aVERIFY, aVERIFY_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
if (res)
return res;
sw = get_sw(response, resplen);
if (sw == 0x6300) {
// need to provide 16byte password
param_gethex_to_eol("0020000110", 0, aVERIFY, sizeof(aVERIFY), &aVERIFY_n);
memcpy(aVERIFY + aVERIFY_n, pwd, pwdlen);
res = ExchangeAPDU14a(aVERIFY, aVERIFY_n + pwdlen, activate_field, keep_field_on, response, sizeof(response), &resplen);
if (with_pwd) {
// --------------- VERIFY ----------------
uint8_t aVERIFY[30];
int aVERIFY_n = 0;
param_gethex_to_eol("0020000100", 0, aVERIFY, sizeof(aVERIFY), &aVERIFY_n);
res = ExchangeAPDU14a(aVERIFY, aVERIFY_n, activate_field, keep_field_on, response, sizeof(response), &resplen);
if (res)
return res;
sw = get_sw(response, resplen);
if (sw != 0x9000) {
PrintAndLogEx(ERR, "Verify password failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
return PM3_ESOFT;
if (sw == 0x6300) {
// need to provide 16byte password
param_gethex_to_eol("0020000110", 0, aVERIFY, sizeof(aVERIFY), &aVERIFY_n);
memcpy(aVERIFY + aVERIFY_n, pwd, pwdlen);
res = ExchangeAPDU14a(aVERIFY, aVERIFY_n + pwdlen, activate_field, keep_field_on, response, sizeof(response), &resplen);
if (res)
return res;
sw = get_sw(response, resplen);
if (sw != 0x9000) {
PrintAndLogEx(ERR, "Verify password failed (%04x - %s).", sw, GetAPDUCodeDescription(sw >> 8, sw & 0xff));
return PM3_ESOFT;
}
}
}
@ -473,57 +452,72 @@ static int cmd_hf_st_ndef(const char *Cmd) {
static int cmd_hf_st_protect(const char *Cmd) {
uint8_t cmdp = 0;
bool errors = false;
int pwdlen = 0;
uint8_t pwd[16] = {0};
int statelen = 3;
uint8_t state[3] = {0x26, 0, 0};
uint8_t state[3] = {0x26, 0, 0x02};
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_hf_st_protect();
case '0':
state[0] = 0x26; //Disable protection
cmdp++;
break;
case '1':
state[0] = 0x28; //Enable protection
cmdp++;
break;
case 'r':
state[2] = 0x01;
cmdp++;
break;
case 'w':
state[2] = 0x02;
cmdp++;
break;
case 'p':
param_gethex_ex(Cmd, cmdp + 1, pwd, &pwdlen);
pwdlen >>= 1;
cmdp += 2;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
bool disable_protection = false;
bool enable_protection = false;
bool read_protection = false;
bool write_protection = false;
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf st protect",
"Change read or write protection for NFC Data Exchange Format (NDEF) file on ST25TA",
"hf st protect -p 82E80053D4CA5C0B656D852CC696C8A1 -r -e -> enable read protection\n"
"hf st protect -p 82E80053D4CA5C0B656D852CC696C8A1 -w -d -> disable write protection\n");
void *argtable[] = {
arg_param_begin,
arg_lit0("e", "enable", "enable protection"),
arg_lit0("d", "disable", "disable protection (default)"),
arg_lit0("r", "read", "change read protection"),
arg_lit0("w", "write", "change write protection (default)"),
arg_str1("p", "password", "<hex>", "16 byte write password"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
enable_protection = arg_get_lit(ctx, 1);
disable_protection = arg_get_lit(ctx, 2);
read_protection = arg_get_lit(ctx, 3);
write_protection = arg_get_lit(ctx, 4);
CLIGetHexWithReturn(ctx, 5, pwd, &pwdlen);
CLIParserFree(ctx);
//Validations
if (state[2] == 0x00) {
PrintAndLogEx(WARNING, "Missing action (r)ead or (w)rite");
errors = true;
}
if (pwdlen != 16) {
PrintAndLogEx(WARNING, "Missing 16 byte password");
errors = true;
if (enable_protection && disable_protection) {
PrintAndLogEx(ERR, "Must specify either enable or disable protection, not both");
return PM3_EINVARG;
} else {
if (enable_protection) {
state[0] = 0x28;
}
if (disable_protection) {
state[0] = 0x26;
}
}
if (errors || cmdp == 0) return usage_hf_st_protect();
if (read_protection && write_protection) {
PrintAndLogEx(ERR, "Must specify either read or write protection, not both");
return PM3_EINVARG;
} else {
if (read_protection) {
state[2] = 0x01;
}
if (write_protection) {
state[2] = 0x02;
}
}
if (pwdlen != 16) {
PrintAndLogEx(ERR, "Missing 16 byte password");
return PM3_EINVARG;
}
bool activate_field = true;
bool keep_field_on = true;
@ -603,63 +597,63 @@ static int cmd_hf_st_protect(const char *Cmd) {
}
static int cmd_hf_st_pwd(const char *Cmd) {
char c = tolower(param_getchar(Cmd, 0));
if (c == 'h' || c == 0x00) return usage_hf_st_pwd();
uint8_t cmdp = 0;
bool errors = false;
int pwdlen = 0;
uint8_t pwd[16] = {0};
int newpwdlen = 0;
uint8_t newpwd[16] = {0};
int changePwdlen = 4;
uint8_t changePwd[4] = {0x24, 0x00, 0x00, 0x10};
uint8_t changePwd[4] = {0x24, 0x00, 0x01, 0x10};
bool change_read_password = false;
bool change_write_password = false;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_hf_st_pwd();
case 'r':
changePwd[2] = 0x01;
cmdp++;
break;
case 'w':
changePwd[2] = 0x02;
cmdp++;
break;
case 'p':
param_gethex_ex(Cmd, cmdp + 1, pwd, &pwdlen);
pwdlen >>= 1;
cmdp += 2;
break;
case 'n':
param_gethex_ex(Cmd, cmdp + 1, newpwd, &newpwdlen);
newpwdlen >>= 1;
cmdp += 2;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
break;
CLIParserContext *ctx;
CLIParserInit(&ctx, "hf st pwd",
"Change read or write password for NFC Data Exchange Format (NDEF) file on ST25TA",
"hf st pwd -p 82E80053D4CA5C0B656D852CC696C8A1 -r -n 00000000000000000000000000000000 -> change read password\n"
"hf st pwd -p 82E80053D4CA5C0B656D852CC696C8A1 -w -n 00000000000000000000000000000000 -> change write password\n");
void *argtable[] = {
arg_param_begin,
arg_lit0("r", "read", "change the read password (default)"),
arg_lit0("w", "write", "change the write password"),
arg_str1("p", "password", "<hex>", "current 16 byte write password"),
arg_str1("n", "new", "<hex>", "new 16 byte password"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
change_read_password = arg_get_lit(ctx, 1);
change_write_password = arg_get_lit(ctx, 2);
CLIGetHexWithReturn(ctx, 3, pwd, &pwdlen);
CLIGetHexWithReturn(ctx, 4, newpwd, &newpwdlen);
if (change_read_password && change_write_password) {
PrintAndLogEx(ERR, "Must specify either read or write, not both");
CLIParserFree(ctx);
return PM3_EINVARG;
} else {
if (change_read_password) {
changePwd[2] = 0x01;
}
if (change_write_password) {
changePwd[2] = 0x02;
}
}
//Validations
CLIParserFree(ctx);
if (changePwd[2] == 0x00) {
PrintAndLogEx(WARNING, "Missing password specification: (r)ead or (w)rite");
errors = true;
}
if (pwdlen != 16) {
PrintAndLogEx(WARNING, "Missing original 16 byte password");
errors = true;
PrintAndLogEx(ERR, "Original write password must be 16 hex bytes");
return PM3_EINVARG;
}
if (newpwdlen != 16) {
PrintAndLogEx(WARNING, "Missing new 16 byte password");
errors = true;
PrintAndLogEx(ERR, "New password must be 16 hex bytes");
return PM3_EINVARG;
}
if (errors || cmdp == 0) return usage_hf_st_pwd();
bool activate_field = true;
bool keep_field_on = true;
uint8_t response[PM3_CMD_DATA_SIZE];
@ -745,13 +739,13 @@ static int cmd_hf_st_list(const char *Cmd) {
}
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"info", cmd_hf_st_info, IfPm3Iso14443a, "Tag information"},
{"list", cmd_hf_st_list, AlwaysAvailable, "List ISO 14443A/7816 history"},
{"ndef", cmd_hf_st_ndef, AlwaysAvailable, "read NDEF file on tag"},
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"info", cmd_hf_st_info, IfPm3Iso14443a, "Tag information"},
{"list", cmd_hf_st_list, AlwaysAvailable, "List ISO 14443A/7816 history"},
{"ndef", cmd_hf_st_ndef, AlwaysAvailable, "read NDEF file on tag"},
{"protect", cmd_hf_st_protect, IfPm3Iso14443a, "change protection on tag"},
{"pwd", cmd_hf_st_pwd, IfPm3Iso14443a, "change password on tag"},
{"sim", cmd_hf_st_sim, IfPm3Iso14443a, "Fake ISO 14443A/ST tag"},
{"pwd", cmd_hf_st_pwd, IfPm3Iso14443a, "change password on tag"},
{"sim", cmd_hf_st_sim, IfPm3Iso14443a, "Fake ISO 14443A/ST tag"},
{NULL, NULL, NULL, NULL}
};

View file

@ -565,7 +565,7 @@ static int transceive_blocking(uint8_t *txBuf, uint16_t txBufLen, uint8_t *rxBuf
if (WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
if (resp.oldarg[0] > rxBufLen) {
PrintAndLogEx(WARNING, "Received %u bytes, rxBuf too small (%u)", resp.oldarg[0], rxBufLen);
PrintAndLogEx(WARNING, "Received %"PRIu32 " bytes, rxBuf too small (%u)", resp.oldarg[0], rxBufLen);
memcpy(rxBuf, resp.data.asBytes, rxBufLen);
*actLen = rxBufLen;
return PM3_ESOFT;

View file

@ -716,7 +716,7 @@ void pm3_version(bool verbose, bool oneliner) {
PrintAndLogEx(NORMAL, " compiled with " PM3CLIENTCOMPILER __VERSION__ PM3HOSTOS PM3HOSTARCH);
PrintAndLogEx(NORMAL, "\n [ " _YELLOW_("PROXMARK3") " ]");
if (IfPm3Rdv4Fw() == false ){
if (IfPm3Rdv4Fw() == false) {
PrintAndLogEx(NORMAL, " firmware.........................%s", _GREEN_("PM3OTHER"));
if (IfPm3FpcUsartHost()) {
PrintAndLogEx(NORMAL, " FPC USART for BT add-on..........%s", _GREEN_("present"));

View file

@ -33,28 +33,29 @@
#include "cmdlfem4x50.h" // for em4x50
#include "cmdlfhid.h" // for hid menu
#include "cmdlfhitag.h" // for hitag menu
#include "cmdlfidteck.h" // for idteck menu
#include "cmdlfio.h" // for ioprox menu
#include "cmdlft55xx.h" // for t55xx menu
#include "cmdlfti.h" // for ti menu
#include "cmdlfpresco.h" // for presco menu
#include "cmdlfpcf7931.h" // for pcf7931 menu
#include "cmdlfpyramid.h" // for pyramid menu
#include "cmdlfviking.h" // for viking menu
#include "cmdlfnedap.h" // for NEDAP menu
#include "cmdlfjablotron.h" // for JABLOTRON menu
#include "cmdlfvisa2000.h" // for VISA2000 menu
#include "cmdlfnoralsy.h" // for NORALSY meny
#include "cmdlfcotag.h" // for COTAG meny
#include "cmdlfindala.h" // for indala menu
#include "cmdlfguard.h" // for gproxii menu
#include "cmdlffdx.h" // for fdx-b menu
#include "cmdlfparadox.h" // for paradox menu
#include "cmdlfnexwatch.h" // for nexwatch menu
#include "cmdlfsecurakey.h" // for securakey menu
#include "cmdlfpac.h" // for pac menu
#include "cmdlfgallagher.h" // for GALLAGHER menu
#include "cmdlfguard.h" // for gproxii menu
#include "cmdlfindala.h" // for indala menu
#include "cmdlfjablotron.h" // for JABLOTRON menu
#include "cmdlfkeri.h" // for keri menu
#include "cmdlfmotorola.h" // for Motorola menu
#include "cmdlfgallagher.h" // for GALLAGHER menu
#include "cmdlfnedap.h" // for NEDAP menu
#include "cmdlfnexwatch.h" // for nexwatch menu
#include "cmdlfnoralsy.h" // for NORALSY meny
#include "cmdlfpac.h" // for pac menu
#include "cmdlfparadox.h" // for paradox menu
#include "cmdlfpcf7931.h" // for pcf7931 menu
#include "cmdlfpresco.h" // for presco menu
#include "cmdlfpyramid.h" // for pyramid menu
#include "cmdlfsecurakey.h" // for securakey menu
#include "cmdlft55xx.h" // for t55xx menu
#include "cmdlfti.h" // for ti menu
#include "cmdlfviking.h" // for viking menu
#include "cmdlfvisa2000.h" // for VISA2000 menu
#define LF_CMDREAD_MAX_EXTRA_SYMBOLS 4
static bool g_lf_threshold_set = false;
@ -77,14 +78,14 @@ static int usage_lf_cmdread(void) {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, " ************* " _YELLOW_("All periods in decimal and in microseconds (us)"));
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, "- probing for Hitag 1/Hitag S:");
PrintAndLogEx(NORMAL, _CYAN_(" probing for Hitag 1/Hitag S") ":");
PrintAndLogEx(NORMAL, _YELLOW_(" lf cmdread d 50 z 116 o 166 e W 3000 c W00110"));
PrintAndLogEx(NORMAL, "- probing for Hitag 2:");
PrintAndLogEx(NORMAL, _CYAN_(" probing for Hitag 2") ":");
PrintAndLogEx(NORMAL, _YELLOW_(" lf cmdread d 50 z 116 o 166 e W 3000 c W11000"));
PrintAndLogEx(NORMAL, "- probing for Hitag 2, oscilloscope style:");
PrintAndLogEx(NORMAL, _CYAN_(" probing for Hitag 2, oscilloscope style") ":");
PrintAndLogEx(NORMAL, _YELLOW_(" data plot"));
PrintAndLogEx(NORMAL, _YELLOW_(" lf cmdread d 50 z 116 o 166 e W 3000 c W11000 q s 2000 @"));
PrintAndLogEx(NORMAL, "- probing for Hitag (us):");
PrintAndLogEx(NORMAL, _CYAN_(" probing for Hitag (us)") ":");
PrintAndLogEx(NORMAL, _YELLOW_(" lf cmdread d 48 z 112 o 176 e W 3000 e S 240 e E 336 c W0S00000010000E"));
PrintAndLogEx(NORMAL, "Extras:");
PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")" to set parameters.");
@ -116,8 +117,8 @@ static int usage_lf_sim(void) {
PrintAndLogEx(NORMAL, " h This help");
PrintAndLogEx(NORMAL, " <gap> Start gap (in microseconds)");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf sim 240 - start simulating with 240ms gap");
PrintAndLogEx(NORMAL, " lf sim");
PrintAndLogEx(NORMAL, _YELLOW_(" lf sim 240") " - start simulating with 240ms gap");
PrintAndLogEx(NORMAL, _YELLOW_(" lf sim"));
PrintAndLogEx(NORMAL, "Extras:");
PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")" to set parameters.");
return PM3_SUCCESS;
@ -132,9 +133,9 @@ static int usage_lf_sniff(void) {
PrintAndLogEx(NORMAL, " @ run continuously until a key is pressed (optional)");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf sniff");
PrintAndLogEx(NORMAL, "- oscilloscope style:");
PrintAndLogEx(NORMAL, " data plot");
PrintAndLogEx(NORMAL, " lf sniff q s 3000 @");
PrintAndLogEx(NORMAL, _CYAN_(" oscilloscope style") ":");
PrintAndLogEx(NORMAL, _YELLOW_(" data plot"));
PrintAndLogEx(NORMAL, _YELLOW_(" lf sniff q s 3000 @"));
PrintAndLogEx(NORMAL, "Extras:");
PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")" to set parameters.");
PrintAndLogEx(NORMAL, " use " _YELLOW_("'data plot'")" to look at it");
@ -154,12 +155,12 @@ static int usage_lf_config(void) {
PrintAndLogEx(NORMAL, " t <threshold> Sets trigger threshold. 0 means no threshold (range: 0-128)");
PrintAndLogEx(NORMAL, " s <samplestoskip> Sets a number of samples to skip before capture. Default: 0");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf config - shows current config");
PrintAndLogEx(NORMAL, " lf config b 8 L - samples at 125 kHz, 8bps.");
PrintAndLogEx(NORMAL, " lf config H b 4 d 3 - samples at 134 kHz, averages three samples into one, stored with ");
PrintAndLogEx(NORMAL, _YELLOW_(" lf config") " - shows current config");
PrintAndLogEx(NORMAL, _YELLOW_(" lf config b 8 L") " - samples at 125 kHz, 8bps.");
PrintAndLogEx(NORMAL, _YELLOW_(" lf config H b 4 d 3") " - samples at 134 kHz, averages three samples into one, stored with ");
PrintAndLogEx(NORMAL, " a resolution of 4 bits per sample.");
PrintAndLogEx(NORMAL, " lf read - performs a read (active field)");
PrintAndLogEx(NORMAL, " lf sniff - performs a sniff (no active field)");
PrintAndLogEx(NORMAL, _YELLOW_(" lf read") " - performs a read (active field)");
PrintAndLogEx(NORMAL, _YELLOW_(" lf sniff") " - performs a sniff (no active field)");
return PM3_SUCCESS;
}
static int usage_lf_simfsk(void) {
@ -180,10 +181,10 @@ static int usage_lf_simfsk(void) {
PrintAndLogEx(NORMAL, "\n NOTE: if you set one clock manually set them all manually");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf simfsk c 40 H 8 L 5 d 010203 - FSK1 rf/40 data 010203");
PrintAndLogEx(NORMAL, " lf simfsk c 40 H 5 L 8 d 010203 - FSK1a rf/40 data 010203");
PrintAndLogEx(NORMAL, " lf simfsk c 64 H 10 L 8 d 010203 - FSK2 rf/64 data 010203");
PrintAndLogEx(NORMAL, " lf simfsk c 64 H 8 L 10 d 010203 - FSK2a rf/64 data 010203");
PrintAndLogEx(NORMAL, _YELLOW_(" lf simfsk c 40 H 8 L 5 d 010203") " - FSK1 rf/40 data 010203");
PrintAndLogEx(NORMAL, _YELLOW_(" lf simfsk c 40 H 5 L 8 d 010203") " - FSK1a rf/40 data 010203");
PrintAndLogEx(NORMAL, _YELLOW_(" lf simfsk c 64 H 10 L 8 d 010203") " - FSK2 rf/64 data 010203");
PrintAndLogEx(NORMAL, _YELLOW_(" lf simfsk c 64 H 8 L 10 d 010203") " - FSK2a rf/64 data 010203");
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
@ -221,10 +222,10 @@ static int usage_lf_find(void) {
PrintAndLogEx(NORMAL, " <0|1> Use data from Graphbuffer, if not set, try reading data from tag.");
PrintAndLogEx(NORMAL, " u Search for Unknown tags, if not set, reads only known tags.");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf search = try reading data from tag & search for known tags");
PrintAndLogEx(NORMAL, " lf search 1 = use data from GraphBuffer & search for known tags");
PrintAndLogEx(NORMAL, " lf search u = try reading data from tag & search for known and unknown tags");
PrintAndLogEx(NORMAL, " lf search 1 u = use data from GraphBuffer & search for known and unknown tags");
PrintAndLogEx(NORMAL, _YELLOW_(" lf search") " - try reading data from tag & search for known tags");
PrintAndLogEx(NORMAL, _YELLOW_(" lf search 1") " - use data from GraphBuffer & search for known tags");
PrintAndLogEx(NORMAL, _YELLOW_(" lf search u") " - try reading data from tag & search for known and unknown tags");
PrintAndLogEx(NORMAL, _YELLOW_(" lf search 1 u") " - use data from GraphBuffer & search for known and unknown tags");
return PM3_SUCCESS;
}
static int usage_lf_tune(void) {
@ -1445,27 +1446,27 @@ int CmdLFfind(const char *Cmd) {
}
}
if (demodVisa2k() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Visa2000 ID") " found!"); goto out;}
if (demodHID() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("HID Prox ID") " found!"); goto out;}
if (demodAWID() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("AWID ID") " found!"); goto out;}
if (demodIOProx() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("IO Prox ID") " found!"); goto out;}
if (demodParadox() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Paradox ID") " found!"); goto out;}
if (demodNexWatch() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("NexWatch ID") " found!"); goto out;}
if (demodIndala() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Indala ID") " found!"); goto out;}
if (demodEM410x() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("EM410x ID") " found!"); goto out;}
if (demodVisa2k(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Visa2000 ID") " found!"); goto out;}
if (demodHID(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("HID Prox ID") " found!"); goto out;}
if (demodAWID(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("AWID ID") " found!"); goto out;}
if (demodIOProx(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("IO Prox ID") " found!"); goto out;}
if (demodParadox(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Paradox ID") " found!"); goto out;}
if (demodNexWatch(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("NexWatch ID") " found!"); goto out;}
if (demodIndala(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Indala ID") " found!"); goto out;}
if (demodEM410x(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("EM410x ID") " found!"); goto out;}
if (demodFDX(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("FDX-B ID") " found!"); goto out;}
if (demodGuard() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Guardall G-Prox II ID") " found!"); goto out; }
if (demodIdteck() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Idteck ID") " found!"); goto out;}
if (demodJablotron() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Jablotron ID") " found!"); goto out;}
if (demodNedap() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("NEDAP ID") " found!"); goto out;}
if (demodNoralsy() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Noralsy ID") " found!"); goto out;}
if (demodKeri() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("KERI ID") " found!"); goto out;}
if (demodPac() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("PAC/Stanley ID") " found!"); goto out;}
if (demodPresco() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Presco ID") " found!"); goto out;}
if (demodPyramid() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Pyramid ID") " found!"); goto out;}
if (demodSecurakey() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Securakey ID") " found!"); goto out;}
if (demodViking() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Viking ID") " found!"); goto out;}
if (demodGallagher() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("GALLAGHER ID") " found!"); goto out;}
if (demodGuard(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Guardall G-Prox II ID") " found!"); goto out; }
if (demodIdteck(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Idteck ID") " found!"); goto out;}
if (demodJablotron(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Jablotron ID") " found!"); goto out;}
if (demodNedap(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("NEDAP ID") " found!"); goto out;}
if (demodNoralsy(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Noralsy ID") " found!"); goto out;}
if (demodKeri(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("KERI ID") " found!"); goto out;}
if (demodPac(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("PAC/Stanley ID") " found!"); goto out;}
if (demodPresco(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Presco ID") " found!"); goto out;}
if (demodPyramid(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Pyramid ID") " found!"); goto out;}
if (demodSecurakey(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Securakey ID") " found!"); goto out;}
if (demodViking(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Viking ID") " found!"); goto out;}
if (demodGallagher(true) == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("GALLAGHER ID") " found!"); goto out;}
// if (demodTI() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Texas Instrument ID") " found!"); goto out;}
// if (demodFermax() == PM3_SUCCESS) { PrintAndLogEx(SUCCESS, "\nValid " _GREEN_("Fermax ID") " found!"); goto out;}
@ -1486,14 +1487,14 @@ int CmdLFfind(const char *Cmd) {
//fsk
if (GetFskClock("", false)) {
if (FSKrawDemod("", true) == PM3_SUCCESS) {
if (FSKrawDemod(0, 0, 0, 0, true) == PM3_SUCCESS) {
PrintAndLogEx(NORMAL, "\nUnknown FSK Modulated Tag found!");
goto out;
}
}
bool st = true;
if (ASKDemod_ext("0 0 0", true, false, 1, &st) == PM3_SUCCESS) {
if (ASKDemod_ext(0, 0, 0, 0, false, true, false, 1, &st) == PM3_SUCCESS) {
PrintAndLogEx(NORMAL, "\nUnknown ASK Modulated and Manchester encoded Tag found!");
PrintAndLogEx(NORMAL, "if it does not look right it could instead be ASK/Biphase - try " _YELLOW_("'data rawdemod ab'"));
goto out;
@ -1531,6 +1532,7 @@ static command_t CommandTable[] = {
{"gproxii", CmdLFGuard, AlwaysAvailable, "{ Guardall Prox II RFIDs... }"},
{"hid", CmdLFHID, AlwaysAvailable, "{ HID Prox RFIDs... }"},
{"hitag", CmdLFHitag, AlwaysAvailable, "{ Hitag CHIPs... }"},
{"idteck", CmdLFIdteck, AlwaysAvailable, "{ Idteck RFIDs... }"},
{"indala", CmdLFINDALA, AlwaysAvailable, "{ Indala RFIDs... }"},
{"io", CmdLFIO, AlwaysAvailable, "{ ioProx RFIDs... }"},
{"jablotron", CmdLFJablotron, AlwaysAvailable, "{ Jablotron RFIDs... }"},

View file

@ -196,9 +196,8 @@ static int CmdAWIDWatch(const char *Cmd) {
//by marshmellow
//AWID Prox demod - FSK2a RF/50 with preamble of 00000001 (always a 96 bit data stream)
//print full AWID Prox ID and some bit format details if found
static int CmdAWIDDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
int demodAWID(bool verbose) {
(void) verbose; // unused so far
uint8_t *bits = calloc(MAX_GRAPH_TRACE_LEN, sizeof(uint8_t));
if (bits == NULL) {
PrintAndLogEx(DEBUG, "DEBUG: Error - AWID failed to allocate memory");
@ -337,10 +336,16 @@ static int CmdAWIDDemod(const char *Cmd) {
return PM3_SUCCESS;
}
static int CmdAWIDDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodAWID(true);
}
// this read is the "normal" read, which download lf signal and tries to demod here.
static int CmdAWIDRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
lf_read(false, 12000);
return CmdAWIDDemod(Cmd);
return demodAWID(true);
}
static int CmdAWIDSim(const char *Cmd) {
@ -605,7 +610,3 @@ int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits) {
return PM3_SUCCESS;
}
int demodAWID(void) {
return CmdAWIDDemod("");
}

View file

@ -15,7 +15,7 @@
int CmdLFAWID(const char *Cmd);
int demodAWID(void);
int demodAWID(bool verbose);
int getAWIDBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *bits);
#endif

View file

@ -37,7 +37,8 @@ static int usage_lf_cotag_read(void) {
// COTAG demod should be able to use GraphBuffer,
// when data load samples
int demodCOTAG(void) {
int demodCOTAG(bool verbose) {
(void) verbose; // unused so far
uint8_t bits[COTAG_BITS] = {0};
size_t bitlen = COTAG_BITS;
@ -73,8 +74,8 @@ int demodCOTAG(void) {
}
static int CmdCOTAGDemod(const char *Cmd) {
(void)Cmd;
return demodCOTAG();
(void)Cmd; // Cmd is not used so far
return demodCOTAG(true);
}
// When reading a COTAG.
// 0 = HIGH/LOW signal - maxlength bigbuff
@ -118,7 +119,7 @@ static int CmdCOTAGRead(const char *Cmd) {
case 1: {
memcpy(DemodBuffer, resp.data.asBytes, resp.length);
DemodBufferLen = resp.length;
return demodCOTAG();
return demodCOTAG(true);
}
}
return PM3_SUCCESS;

View file

@ -18,6 +18,6 @@
#endif
int CmdLFCOTAG(const char *Cmd);
int demodCOTAG(void);
int demodCOTAG(bool verbose);
int readCOTAGUid(void);
#endif

View file

@ -63,17 +63,17 @@ static int usage_lf_em410x_watch(void) {
return PM3_SUCCESS;
}
static int usage_lf_em410x_write(void) {
static int usage_lf_em410x_clone(void) {
PrintAndLogEx(NORMAL, "Writes EM410x ID to a T55x7 or Q5/T5555 tag");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf em 410x_write [h] <id> <card> [clock]");
PrintAndLogEx(NORMAL, "Usage: lf em 410x_clone [h] <id> <card> [clock]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h - this help");
PrintAndLogEx(NORMAL, " <id> - ID number");
PrintAndLogEx(NORMAL, " <card> - 0|1 0 = Q5/T5555, 1 = T55x7");
PrintAndLogEx(NORMAL, " <clock> - 16|32|40|64, optional, set R/F clock rate, defaults to 64");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" lf em 410x_write 0F0368568B 1") " = write ID to t55x7 card");
PrintAndLogEx(NORMAL, _YELLOW_(" lf em 410x_clone 0F0368568B 1") " = write ID to t55x7 card");
return PM3_SUCCESS;
}
static int usage_lf_em410x_ws(void) {
@ -390,15 +390,14 @@ int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo) {
return PM3_SUCCESS;
}
int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose) {
int AskEm410xDemod(int clk, int invert, int maxErr, size_t maxLen, bool amplify, uint32_t *hi, uint64_t *lo, bool verbose) {
bool st = true;
// em410x simulation etc uses 0/1 as signal data. This must be converted in order to demod it back again
if (isGraphBitstream()) {
convertGraphFromBitstream();
}
if (ASKDemod_ext(Cmd, false, false, 1, &st) != PM3_SUCCESS)
if (ASKDemod_ext(clk, invert, maxErr, maxLen, amplify, false, false, 1, &st) != PM3_SUCCESS)
return PM3_ESOFT;
return AskEm410xDecode(verbose, hi, lo);
}
@ -423,14 +422,27 @@ static int CmdEM410xWatch(const char *Cmd) {
//takes 3 arguments - clock, invert and maxErr as integers
//attempts to demodulate ask while decoding manchester
//prints binary found and saves in graphbuffer for further commands
int demodEM410x(bool verbose) {
(void) verbose; // unused so far
uint32_t hi = 0;
uint64_t lo = 0;
return AskEm410xDemod(0, 0, 100, 0, false, &hi, &lo, true);
}
static int CmdEM410xDemod(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) > 10 || cmdp == 'h') return usage_lf_em410x_demod();
uint32_t hi = 0;
uint64_t lo = 0;
if (AskEm410xDemod(Cmd, &hi, &lo, true) != PM3_SUCCESS)
int clk = 0;
int invert = 0;
int maxErr = 100;
size_t maxLen = 0;
char amp = tolower(param_getchar(Cmd, 0));
sscanf(Cmd, "%i %i %i %zu %c", &clk, &invert, &maxErr, &maxLen, &amp);
bool amplify = amp == 'a';
if (AskEm410xDemod(clk, invert, maxErr, maxLen, amplify, &hi, &lo, true) != PM3_SUCCESS)
return PM3_ESOFT;
g_em410xid = lo;
@ -439,8 +451,20 @@ static int CmdEM410xDemod(const char *Cmd) {
// this read is the "normal" read, which download lf signal and tries to demod here.
static int CmdEM410xRead(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) > 10 || cmdp == 'h') return usage_lf_em410x_demod();
uint32_t hi = 0;
uint64_t lo = 0;
int clk = 0;
int invert = 0;
int maxErr = 100;
size_t maxLen = 0;
char amp = tolower(param_getchar(Cmd, 0));
sscanf(Cmd, "%i %i %i %zu %c", &clk, &invert, &maxErr, &maxLen, &amp);
bool amplify = amp == 'a';
lf_read(false, 12288);
return CmdEM410xDemod(Cmd);
return AskEm410xDemod(clk, invert, maxErr, maxLen, amplify, &hi, &lo, true);
}
// emulate an EM410X tag
@ -591,9 +615,9 @@ static int CmdEM410xWatchnSpoof(const char *Cmd) {
return PM3_SUCCESS;
}
static int CmdEM410xWrite(const char *Cmd) {
static int CmdEM410xClone(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 0x00 || cmdp == 'h') return usage_lf_em410x_write();
if (cmdp == 0x00 || cmdp == 'h') return usage_lf_em410x_clone();
uint64_t id = param_get64ex(Cmd, 0, -1, 16);
uint8_t card = param_get8ex(Cmd, 1, 0xFF, 10);
@ -602,19 +626,19 @@ static int CmdEM410xWrite(const char *Cmd) {
// Check ID
if (id == 0xFFFFFFFFFFFFFFFF) {
PrintAndLogEx(ERR, "error, ID is required\n");
usage_lf_em410x_write();
usage_lf_em410x_clone();
return PM3_EINVARG;
}
if (id >= 0x10000000000) {
PrintAndLogEx(ERR, "error, given EM410x ID is longer than 40 bits\n");
usage_lf_em410x_write();
usage_lf_em410x_clone();
return PM3_EINVARG;
}
// Check Card
if (card > 1) {
PrintAndLogEx(FAILED, "error, bad card type selected\n");
usage_lf_em410x_write();
usage_lf_em410x_clone();
return PM3_EINVARG;
}
@ -626,7 +650,7 @@ static int CmdEM410xWrite(const char *Cmd) {
if ((clock1 != 16) && (clock1 != 32) && (clock1 != 64) && (clock1 != 40)) {
PrintAndLogEx(FAILED, "error, clock rate" _RED_("%d")" not valid", clock1);
PrintAndLogEx(INFO, "supported clock rates: " _YELLOW_("16, 32, 40, 60") "\n");
usage_lf_em410x_write();
usage_lf_em410x_clone();
return PM3_EINVARG;
}
@ -735,7 +759,7 @@ static bool detectFSK(void) {
return false;
}
// demod
int ans = FSKrawDemod("0 0", false);
int ans = FSKrawDemod(0, 0, 0, 0, false);
if (ans != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - EM: FSK Demod failed");
return false;
@ -751,12 +775,12 @@ static bool detectPSK(void) {
}
//demod
//try psk1 -- 0 0 6 (six errors?!?)
ans = PSKDemod("0 0 6", false);
ans = PSKDemod(0, 0, 6, false);
if (ans != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - EM: PSK1 Demod failed");
//try psk1 inverted
ans = PSKDemod("0 1 6", false);
ans = PSKDemod(0, 1, 6, false);
if (ans != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - EM: PSK1 inverted Demod failed");
return false;
@ -769,7 +793,7 @@ static bool detectPSK(void) {
// try manchester - NOTE: ST only applies to T55x7 tags.
static bool detectASK_MAN(void) {
bool stcheck = false;
if (ASKDemod_ext("0 0 0", false, false, 1, &stcheck) != PM3_SUCCESS) {
if (ASKDemod_ext(0, 0, 0, 0, false, false, false, 1, &stcheck) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - EM: ASK/Manchester Demod failed");
return false;
}
@ -777,11 +801,11 @@ static bool detectASK_MAN(void) {
}
static bool detectASK_BI(void) {
int ans = ASKbiphaseDemod("0 0 1", false);
int ans = ASKbiphaseDemod(0, 0, 1, 50, false);
if (ans != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - EM: ASK/biphase normal demod failed");
ans = ASKbiphaseDemod("0 1 1", false);
ans = ASKbiphaseDemod(0, 1, 1, 50, false);
if (ans != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - EM: ASK/biphase inverted demod failed");
return false;
@ -790,11 +814,11 @@ static bool detectASK_BI(void) {
return true;
}
static bool detectNRZ(void) {
int ans = NRZrawDemod("0 0 1", false);
int ans = NRZrawDemod(0, 0, 1, false);
if (ans != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - EM: NRZ normal demod failed");
ans = NRZrawDemod("0 1 1", false);
ans = NRZrawDemod(0, 1, 1, false);
if (ans != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - EM: NRZ inverted demod failed");
return false;
@ -1383,7 +1407,7 @@ static command_t CommandTable[] = {
{"410x_brute", CmdEM410xBrute, IfPm3Lf, "reader bruteforce attack by simulating EM410x tags"},
{"410x_watch", CmdEM410xWatch, IfPm3Lf, "watches for EM410x 125/134 kHz tags (option 'h' for 134)"},
{"410x_spoof", CmdEM410xWatchnSpoof, IfPm3Lf, "watches for EM410x 125/134 kHz tags, and replays them. (option 'h' for 134)" },
{"410x_write", CmdEM410xWrite, IfPm3Lf, "write EM410x UID to T55x7 or Q5/T5555 tag"},
{"410x_clone", CmdEM410xClone, IfPm3Lf, "write EM410x UID to T55x7 or Q5/T5555 tag"},
{"----------", CmdHelp, AlwaysAvailable, "-------------------- " _CYAN_("EM 4x05 / 4x69") " -------------------"},
{"4x05_demod", CmdEM4x05Demod, AlwaysAvailable, "demodulate a EM4x05/EM4x69 tag from the GraphBuffer"},
{"4x05_dump", CmdEM4x05Dump, IfPm3Lf, "dump EM4x05/EM4x69 tag"},
@ -1414,7 +1438,3 @@ int CmdLFEM4X(const char *Cmd) {
clearCommandBuffer();
return CmdsParse(CommandTable, Cmd);
}
int demodEM410x(void) {
return CmdEM410xDemod("");
}

View file

@ -15,11 +15,11 @@
int CmdLFEM4X(const char *Cmd);
int demodEM410x(void);
int demodEM410x(bool verbose);
bool EM4x05IsBlock0(uint32_t *word);
void printEM410x(uint32_t hi, uint64_t id);
int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo);
int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose);
int AskEm410xDemod(int clk, int invert, int maxErr, size_t maxLen, bool amplify, uint32_t *hi, uint64_t *lo, bool verbose);
#endif

View file

@ -597,6 +597,8 @@ int em4x50_read(em4x50_data_t *etd, em4x50_word_t *out, bool verbose) {
int CmdEM4x50Read(const char *Cmd) {
em4x50_data_t etd;
memset(&etd, 0x00, sizeof(em4x50_data_t));
etd.pwd_given = false;
etd.addr_given = false;
etd.newpwd_given = false;

View file

@ -220,7 +220,7 @@ static int CmdFDXBdemodBI(const char *Cmd) {
int demodFDX(bool verbose) {
//Differential Biphase / di-phase (inverted biphase)
//get binary from ask wave
if (ASKbiphaseDemod("0 32 1 100", false) != PM3_SUCCESS) {
if (ASKbiphaseDemod(0, 32, 1, 100, false) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - FDX-B ASKbiphaseDemod failed");
return PM3_ESOFT;
}

View file

@ -67,11 +67,10 @@ static void descramble(uint8_t *arr, uint8_t len) {
}
//see ASK/MAN Demod for what args are accepted
static int CmdGallagherDemod(const char *Cmd) {
(void)Cmd;
int demodGallagher(bool verbose) {
(void) verbose; // unused so far
bool st = true;
if (ASKDemod_ext("32 0 0 0", false, false, 1, &st) != PM3_SUCCESS) {
if (ASKDemod_ext(32, 0, 100, 0, false, false, false, 1, &st) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - GALLAGHER: ASKDemod failed");
return PM3_ESOFT;
}
@ -134,9 +133,15 @@ static int CmdGallagherDemod(const char *Cmd) {
return PM3_SUCCESS;
}
static int CmdGallagherDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodGallagher(true);
}
static int CmdGallagherRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
lf_read(false, 4096 * 2 + 20);
return CmdGallagherDemod(Cmd);
return demodGallagher(true);
}
static int CmdGallagherClone(const char *Cmd) {
@ -222,8 +227,3 @@ int detectGallagher(uint8_t *dest, size_t *size) {
//return start position
return (int)startIdx;
}
int demodGallagher(void) {
return CmdGallagherDemod("");
}

View file

@ -14,7 +14,7 @@
int CmdLFGallagher(const char *Cmd);
int demodGallagher(void);
int demodGallagher(bool verbose);
int detectGallagher(uint8_t *dest, size_t *size);
#endif

View file

@ -65,12 +65,11 @@ static int usage_lf_guard_sim(void) {
//WARNING: if it fails during some points it will destroy the DemodBuffer data
// but will leave the GraphBuffer intact.
//if successful it will push askraw data back to demod buffer ready for emulation
static int CmdGuardDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
int demodGuard(bool verbose) {
(void) verbose; // unused so far
//Differential Biphase
//get binary from ask wave
if (ASKbiphaseDemod("0 64 0 0", false) != PM3_SUCCESS) {
if (ASKbiphaseDemod(0, 64, 0, 0, false) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - gProxII ASKbiphaseDemod failed");
return PM3_ESOFT;
}
@ -150,9 +149,15 @@ static int CmdGuardDemod(const char *Cmd) {
return PM3_SUCCESS;
}
static int CmdGuardDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodGuard(true);
}
static int CmdGuardRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
lf_read(false, 10000);
return CmdGuardDemod(Cmd);
return demodGuard(true);
}
static int CmdGuardClone(const char *Cmd) {
@ -290,10 +295,6 @@ int detectGProxII(uint8_t *bits, size_t *size) {
return -5; //spacer bits not found - not a valid gproxII
}
int demodGuard(void) {
return CmdGuardDemod("");
}
// Works for 26bits.
int getGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits) {

View file

@ -13,6 +13,6 @@
int CmdLFGuard(const char *Cmd);
int detectGProxII(uint8_t *bits, size_t *size);
int demodGuard(void);
int demodGuard(bool verbose);
int getGuardBits(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint8_t *guardBits);
#endif

View file

@ -29,6 +29,7 @@
#include "cmdparser.h" // command_t
#include "comms.h"
#include "commonutil.h" // ARRAYLEN
#include "cliparser.h"
#include "ui.h"
#include "graph.h"
#include "cmddata.h" //for g_debugMode, demodbuff cmds
@ -43,70 +44,6 @@
static int CmdHelp(const char *Cmd);
static int usage_lf_hid_watch(void) {
PrintAndLogEx(NORMAL, "Enables HID compatible reader mode printing details.");
PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf hid watch");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" lf hid watch"));
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
static int usage_lf_hid_sim(void) {
PrintAndLogEx(NORMAL, "Enables simulation of HID card with card number.");
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf hid sim [h] [ID]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h - This help");
PrintAndLogEx(NORMAL, " ID - HID id");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" lf hid sim 2006ec0c86"));
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
static int usage_lf_hid_clone(void) {
PrintAndLogEx(NORMAL, "Clone HID to T55x7. " _BLUE_("Tag must be on antenna!"));
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf hid clone [h] [l] ID");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h - This help");
PrintAndLogEx(NORMAL, " l - 84bit ID");
PrintAndLogEx(NORMAL, " ID - HID id");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" lf hid clone 2006ec0c86"));
PrintAndLogEx(NORMAL, _YELLOW_(" lf hid clone l 2006ec0c86"));
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
static int usage_lf_hid_brute(void) {
PrintAndLogEx(NORMAL, "Enables bruteforce of HID readers with specified facility code.");
PrintAndLogEx(NORMAL, "This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step");
PrintAndLogEx(NORMAL, "if cardnumber is not given, it starts with 1 and goes up to 65535");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Usage: lf hid brute [h] [v] w <format> [<field> (decimal)>] [up|down] {...}");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h : This help");
PrintAndLogEx(NORMAL, " w <format> : see " _YELLOW_("`wiegand list`") " for available formats");
PrintAndLogEx(NORMAL, " f <facility-code> : facility code");
PrintAndLogEx(NORMAL, " c <cardnumber> : card number to start with");
PrintAndLogEx(NORMAL, " i <issuelevel> : issue level");
PrintAndLogEx(NORMAL, " o <oem> : OEM code");
PrintAndLogEx(NORMAL, " d <delay> : delay betweens attempts in ms. Default 1000ms");
PrintAndLogEx(NORMAL, " v : verbose logging, show all tries");
PrintAndLogEx(NORMAL, " up : direction to increment card number. (default is both directions)");
PrintAndLogEx(NORMAL, " down : direction to decrement card number. (default is both directions)");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" lf hid brute w H10301 f 224"));
PrintAndLogEx(NORMAL, _YELLOW_(" lf hid brute w H10301 f 21 d 2000"));
PrintAndLogEx(NORMAL, _YELLOW_(" lf hid brute v w H10301 f 21 c 200 d 2000"));
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
// sending three times. Didn't seem to break the previous sim?
static int sendPing(void) {
SendCommandNG(CMD_PING, NULL, 0);
@ -152,8 +89,8 @@ static int sendTry(uint8_t format_idx, wiegand_card_t *card, uint32_t delay, boo
//by marshmellow (based on existing demod + holiman's refactor)
//HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded)
//print full HID Prox ID and some bit format details if found
static int CmdHIDDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
int demodHID(bool verbose) {
(void) verbose; // unused so far
// HID simulation etc uses 0/1 as signal data. This must be converted in order to demod it back again
if (isGraphBitstream()) {
@ -261,17 +198,35 @@ static int CmdHIDDemod(const char *Cmd) {
return PM3_SUCCESS;
}
static int CmdHIDDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodHID(true);
}
// this read is the "normal" read, which download lf signal and tries to demod here.
static int CmdHIDRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
lf_read(false, 12000);
return CmdHIDDemod(Cmd);
return demodHID(true);
}
// this read loops on device side.
// uses the demod in lfops.c
static int CmdHIDWatch(const char *Cmd) {
uint8_t c = tolower(param_getchar(Cmd, 0));
if (c == 'h') return usage_lf_hid_watch();
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf hid watch",
"Enables HID compatible reader mode printing details.\n"
"By default, values are printed and logged until the button is pressed or another USB command is issued.\n",
"lf hid watch"
);
void *argtable[] = {
arg_param_begin,
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, true);
CLIParserFree(ctx);
PrintAndLogEx(SUCCESS, "Watching for HID Prox cards - place tag on antenna");
PrintAndLogEx(INFO, "Press pm3-button to stop reading cards");
@ -284,28 +239,52 @@ static int CmdHIDWatch(const char *Cmd) {
}
static int CmdHIDSim(const char *Cmd) {
int idlen = 0;
uint8_t id[10] = {0};
lf_hidsim_t payload;
payload.longFMT = 0;
uint32_t hi2 = 0, hi = 0, lo = 0;
uint32_t n = 0, i = 0;
uint32_t i = 0;
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_hid_sim();
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf hid sim",
"Enables simulation of HID card with card number.",
"lf hid sim 2006ec0c86"
);
void *argtable[] = {
arg_param_begin,
arg_lit0("l", "long", "Simulate HID tag with long ID"),
arg_str1(NULL, NULL, "<hex>", "HID tag ID"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
if (strchr(Cmd, 'l') != 0) {
i++;
while (sscanf(&Cmd[i++], "%1x", &n) == 1) {
bool long_id = arg_get_lit(ctx, 1);
CLIGetHexWithReturn(ctx, 2, id, &idlen);
CLIParserFree(ctx);
if (long_id) {
for (i=0; i < idlen; ++i) {
hi2 = (hi2 << 4) | (hi >> 28);
hi = (hi << 4) | (lo >> 28);
lo = (lo << 4) | (n & 0xf);
}
lo = (lo << 4) | (id[i] >> 4); //get first 4 bits
hi2 = (hi2 << 4) | (hi >> 28);
hi = (hi << 4) | (lo >> 28);
lo = (lo << 4) | (id[i] & 0xf); //get last 4 bits
}
PrintAndLogEx(INFO, "Simulating HID tag with long ID: " _GREEN_("%x%08x%08x"), hi2, hi, lo);
payload.longFMT = 1;
} else {
while (sscanf(&Cmd[i++], "%1x", &n) == 1) {
for (i=0; i < idlen; ++i) {
hi = (hi << 4) | (lo >> 28);
lo = (lo << 4) | (n & 0xf);
lo = (lo << 4) | (id[i] >> 4); //get first 4 bits
hi = (hi << 4) | (lo >> 28);
lo = (lo << 4) | (id[i] & 0xf); //get last 4 bits
}
PrintAndLogEx(SUCCESS, "Simulating HID tag with ID: " _GREEN_("%x%08x"), hi, lo);
hi2 = 0;
@ -328,28 +307,55 @@ static int CmdHIDSim(const char *Cmd) {
}
static int CmdHIDClone(const char *Cmd) {
int idlen = 0;
uint8_t id[10] = {0};
uint32_t hi2 = 0, hi = 0, lo = 0;
uint32_t n = 0, i = 0;
uint32_t i = 0;
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf hid clone",
"Clone HID to T55x7. Tag must be on antenna!",
"lf hid clone 2006ec0c86\n"
"lf hid clone -l 2006ec0c86"
);
void *argtable[] = {
arg_param_begin,
arg_lit0("l", "long", "84bit HID long ID"),
arg_str1(NULL, NULL, "<hex>", "HID tag ID"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
bool long_id = arg_get_lit(ctx, 1);
CLIGetHexWithReturn(ctx, 2, id, &idlen);
CLIParserFree(ctx);
uint8_t ctmp = tolower(param_getchar(Cmd, 0));
if (strlen(Cmd) == 0 || ctmp == 'h') return usage_lf_hid_clone();
uint8_t longid[1] = {0};
if (strchr(Cmd, 'l') != 0) {
i++;
while (sscanf(&Cmd[i++], "%1x", &n) == 1) {
if (long_id) {
for (i=0; i < idlen; ++i) {
hi2 = (hi2 << 4) | (hi >> 28);
hi = (hi << 4) | (lo >> 28);
lo = (lo << 4) | (n & 0xf);
}
lo = (lo << 4) | (id[i] >> 4); //get first 4 bits
hi2 = (hi2 << 4) | (hi >> 28);
hi = (hi << 4) | (lo >> 28);
lo = (lo << 4) | (id[i] & 0xf); //get last 4 bits
}
PrintAndLogEx(INFO, "Preparing to clone HID tag with long ID: " _GREEN_("%x%08x%08x"), hi2, hi, lo);
longid[0] = 1;
} else {
while (sscanf(&Cmd[i++], "%1x", &n) == 1) {
for (i=0; i < idlen; ++i) {
hi = (hi << 4) | (lo >> 28);
lo = (lo << 4) | (n & 0xf);
lo = (lo << 4) | (id[i] >> 4); //get first 4 bits
hi = (hi << 4) | (lo >> 28);
lo = (lo << 4) | (id[i] & 0xf); //get last 4 bits
}
PrintAndLogEx(INFO, "Preparing to clone HID tag with ID: " _GREEN_("%x%08x"), hi, lo);
hi2 = 0;
@ -379,82 +385,63 @@ static int CmdHIDClone(const char *Cmd) {
static int CmdHIDBrute(const char *Cmd) {
bool errors = false, verbose = false;
uint32_t delay = 1000;
uint8_t cmdp = 0;
int format_idx = -1;
int direction = 0;
char format[16] = {0};
uint8_t format[16] = {0};
int formatLen;
wiegand_card_t cn_hi, cn_low;
memset(&cn_hi, 0, sizeof(wiegand_card_t));
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf hid brute",
"Enables bruteforce of HID readers with specified facility code.\n"
"This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step\n"
"if cardnumber is not given, it starts with 1 and goes up to 65535",
"lf hid brute -w H10301 -f 224\n"
"lf hid brute -w H10301 -f 21 -d 2000\n"
"lf hid brute -v -w H10301 -f 21 -c 200 -d 2000\n"
);
void *argtable[] = {
arg_param_begin,
arg_lit0("v", "verbose", "verbose logging, show all tries"),
arg_str1("w", "wiegand", "format", "see " _YELLOW_("`wiegand list`") " for available formats"),
arg_int0("f", "fn", "dec", "facility code"),
arg_int0("c", "cn", "dec", "card number to start with"),
arg_int0("i", NULL, "dec", "issue level"),
arg_int0("o", "oem", "dec", "OEM code"),
arg_int0("d", "delay", "dec", "delay betweens attempts in ms. Default 1000ms"),
arg_lit0(NULL, "up", "direction to increment card number. (default is both directions)"),
arg_lit0(NULL, "down", "direction to decrement card number. (default is both directions)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
char s[10] = {0};
if (param_getstr(Cmd, cmdp, s, sizeof(s)) > 0) {
if (strlen(s) > 1) {
str_lower((char *)s);
if (str_startswith(s, "up")) {
direction = 1;
} else if (str_startswith(s, "do")) {
direction = 2;
}
cmdp++;
continue;
}
}
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_lf_hid_brute();
case 'w':
param_getstr(Cmd, cmdp + 1, format, sizeof(format));
format_idx = HIDFindCardFormat(format);
if (format_idx == -1) {
PrintAndLogEx(WARNING, "Unknown format: " _YELLOW_("%s"), format);
errors = true;
}
cmdp += 2;
break;
case 'c':
cn_hi.CardNumber = param_get32ex(Cmd, cmdp + 1, 0, 10);
cmdp += 2;
break;
case 'd':
// delay between attemps, defaults to 1000ms.
delay = param_get32ex(Cmd, cmdp + 1, 1000, 10);
cmdp += 2;
break;
case 'f':
cn_hi.FacilityCode = param_get32ex(Cmd, cmdp + 1, 0, 10);
cmdp += 2;
break;
case 'i':
cn_hi.IssueLevel = param_get32ex(Cmd, cmdp + 1, 0, 10);
cmdp += 2;
break;
case 'o':
cn_hi.OEM = param_get32ex(Cmd, cmdp + 1, 0, 10);
cmdp += 2;
break;
case 'v':
verbose = true;
cmdp++;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter: " _YELLOW_("'%c'"), param_getchar(Cmd, cmdp));
errors = true;
break;
}
}
bool verbose = arg_get_lit(ctx, 1);
CLIGetStrWithReturn(ctx, 2, format, &formatLen);
format_idx = HIDFindCardFormat((char*) format);
if (format_idx == -1) {
PrintAndLogEx(ERR, "You must select a wiegand format. See " _YELLOW_("`wiegand list`") " for available formats\n");
errors = true;
PrintAndLogEx(WARNING, "Unknown format: " _YELLOW_("%s"), format);
return PM3_EINVARG;
}
if (errors) return usage_lf_hid_brute();
cn_hi.FacilityCode = arg_get_int_def(ctx, 3, 0);
cn_hi.CardNumber = arg_get_int_def(ctx, 4, 0);
cn_hi.IssueLevel = arg_get_int_def(ctx, 5, 0);
cn_hi.OEM = arg_get_int_def(ctx, 6, 0);
delay = arg_get_int_def(ctx, 7, 1000);
if (arg_get_lit(ctx, 8) && arg_get_lit(ctx, 9)) {
direction = 0;
} else if (arg_get_lit(ctx, 8)) {
direction = 1;
} else if (arg_get_lit(ctx, 9)) {
direction = 2;
}
if (verbose) {
PrintAndLogEx(INFO, "Wiegand format#.. %i", format_idx);
@ -562,7 +549,3 @@ int CmdLFHID(const char *Cmd) {
clearCommandBuffer();
return CmdsParse(CommandTable, Cmd);
}
int demodHID(void) {
return CmdHIDDemod("");
}

View file

@ -15,6 +15,6 @@
int CmdLFHID(const char *Cmd);
int demodHID(void);
int demodHID(bool verbose);
#endif

136
client/src/cmdlfidteck.c Normal file
View file

@ -0,0 +1,136 @@
//-----------------------------------------------------------------------------
// Iceman,
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Low frequency Idteck tag commands
// PSK
//-----------------------------------------------------------------------------
#include "cmdlfidteck.h"
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "common.h"
#include "cmdparser.h" // command_t
#include "comms.h"
#include "ui.h"
#include "cmddata.h"
#include "cmdlf.h"
#include "lfdemod.h"
#include "commonutil.h" // num_to_bytes
static int CmdHelp(const char *Cmd);
int demodIdteck(bool verbose) {
(void) verbose; // unused so far
if (PSKDemod(0, 0, 100, false) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck PSKDemod failed");
return PM3_ESOFT;
}
size_t size = DemodBufferLen;
//get binary from PSK1 wave
int idx = detectIdteck(DemodBuffer, &size);
if (idx < 0) {
if (idx == -1)
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: not enough samples");
else if (idx == -2)
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: just noise");
else if (idx == -3)
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: preamble not found");
else if (idx == -4)
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: size not correct: %zu", size);
else
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: idx: %d", idx);
// if didn't find preamble try again inverting
if (PSKDemod(0, 1, 100, false) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck PSKDemod failed");
return PM3_ESOFT;
}
idx = detectIdteck(DemodBuffer, &size);
if (idx < 0) {
if (idx == -1)
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: not enough samples");
else if (idx == -2)
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: just noise");
else if (idx == -3)
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: preamble not found");
else if (idx == -4)
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: size not correct: %zu", size);
else
PrintAndLogEx(DEBUG, "DEBUG: Error - Idteck: idx: %d", idx);
return PM3_ESOFT;
}
}
setDemodBuff(DemodBuffer, 64, idx);
//got a good demod
uint32_t id = 0;
uint32_t raw1 = bytebits_to_byte(DemodBuffer, 32);
uint32_t raw2 = bytebits_to_byte(DemodBuffer + 32, 32);
//parity check (TBD)
//checksum check (TBD)
//output
PrintAndLogEx(SUCCESS, "IDTECK Tag Found: Card ID %u , Raw: %08X%08X", id, raw1, raw2);
return PM3_SUCCESS;
}
static int CmdIdteckDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodIdteck(true);
}
static int CmdIdteckRead(const char *Cmd) {
(void)Cmd;
lf_read(false, 5000);
return demodIdteck(true);
}
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdIdteckDemod, AlwaysAvailable, "Demodulate an Idteck tag from the GraphBuffer"},
{"read", CmdIdteckRead, IfPm3Lf, "Attempt to read and Extract tag data from the antenna"},
{NULL, NULL, NULL, NULL}
};
static int CmdHelp(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
CmdsHelp(CommandTable);
return PM3_SUCCESS;
}
int CmdLFIdteck(const char *Cmd) {
clearCommandBuffer();
return CmdsParse(CommandTable, Cmd);
}
// Find IDTEC PSK1, RF Preamble == 0x4944544B, Demodsize 64bits
// by iceman
int detectIdteck(uint8_t *dest, size_t *size) {
//make sure buffer has data
if (*size < 64 * 2) return -1;
if (getSignalProperties()->isnoise) return -2;
size_t start_idx = 0;
uint8_t preamble[] = {0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1};
//preamble not found
if (!preambleSearch(dest, preamble, sizeof(preamble), size, &start_idx))
return -3;
// wrong demoded size
if (*size != 64) return -4;
return (int)start_idx;
}

19
client/src/cmdlfidteck.h Normal file
View file

@ -0,0 +1,19 @@
//-----------------------------------------------------------------------------
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Low frequency Idteck tag commands
//-----------------------------------------------------------------------------
#ifndef CMDLFIDTECK_H__
#define CMDLFIDTECK_H__
#include "common.h"
int CmdLFIdteck(const char *Cmd);
int demodIdteck(bool verbose);
int detectIdteck(uint8_t *dest, size_t *size);
#endif

View file

@ -151,25 +151,17 @@ static void decodeHeden2L(uint8_t *bits) {
// Indala 26 bit decode
// by marshmellow, martinbeier
// optional arguments - same as PSKDemod (clock & invert & maxerr)
static int CmdIndalaDemod(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_lf_indala_demod();
int ans;
if (strlen(Cmd) > 0)
ans = PSKDemod(Cmd, true);
else
ans = PSKDemod("32", true);
int demodIndalaEx(int clk, int invert, int maxErr, bool verbose) {
(void) verbose; // unused so far
int ans = PSKDemod(clk, invert, maxErr, true);
if (ans != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - Indala can't demod signal: %d", ans);
return PM3_ESOFT;
}
uint8_t invert = 0;
uint8_t inv = 0;
size_t size = DemodBufferLen;
int idx = detectIndala(DemodBuffer, &size, &invert);
int idx = detectIndala(DemodBuffer, &size, &inv);
if (idx < 0) {
if (idx == -1)
PrintAndLogEx(DEBUG, "DEBUG: Error - Indala: not enough samples");
@ -281,6 +273,29 @@ static int CmdIndalaDemod(const char *Cmd) {
return PM3_SUCCESS;
}
int demodIndala(bool verbose) {
return demodIndalaEx(32, 0, 100, verbose);
}
static int CmdIndalaDemod(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_lf_indala_demod();
int clk = 32, invert = 0, maxErr = 100;
if (strlen(Cmd) > 0) {
sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
}
if (clk == 1) {
invert = 1;
clk = 0;
}
if (invert != 0 && invert != 1) {
PrintAndLogEx(WARNING, "Invalid value for invert: %i", invert);
return PM3_EINVARG;
}
return demodIndalaEx(clk, invert, maxErr, true);
}
// older alternative indala demodulate (has some positives and negatives)
// returns false positives more often - but runs against more sets of samples
// poor psk signal can be difficult to demod this approach might succeed when the other fails
@ -485,8 +500,15 @@ static int CmdIndalaDemodAlt(const char *Cmd) {
// this read is the "normal" read, which download lf signal and tries to demod here.
static int CmdIndalaRead(const char *Cmd) {
char cmdp = tolower(param_getchar(Cmd, 0));
if (cmdp == 'h') return usage_lf_indala_demod();
int clk = 32, invert = 0, maxErr = 100;
if (strlen(Cmd) > 0) {
sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
}
lf_read(false, 30000);
return CmdIndalaDemod(Cmd);
return demodIndalaEx(clk, invert, maxErr, true);
}
static int CmdIndalaSim(const char *Cmd) {
@ -558,20 +580,19 @@ static int CmdIndalaClone(const char *Cmd) {
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf indala clone",
"clone INDALA UID to T55x7 or Q5/T5555 tag",
"Examples:\n"
_YELLOW_("\tlf indala clone --heden 888\n")
_YELLOW_("\tlf indala clone --fc 123 --cn 1337\n")
_YELLOW_("\tlf indala clone -r a0000000a0002021\n")
_YELLOW_("\tlf indala clone -l -r 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5"));
"lf indala clone --heden 888\n"
"lf indala clone --fc 123 --cn 1337\n"
"lf indala clone -r a0000000a0002021\n"
"lf indala clone -l -r 80000001b23523a6c2e31eba3cbee4afb3c6ad1fcf649393928c14e5");
void *argtable[] = {
arg_param_begin,
arg_lit0("lL", "long", "optional - long UID 224 bits"),
arg_int0("cC", "heden", "<decimal>", "Cardnumber for Heden 2L format"),
arg_strx0("rR", "raw", "<hex>", "raw bytes"),
arg_lit0("qQ", "Q5", "optional - specify writing to Q5/T5555 tag"),
arg_int0("", "fc", "<decimal>", "Facility Code (26 bit format)"),
arg_int0("", "cn", "<decimal>", "Cardnumber (26 bit format)"),
arg_lit0("l", "long", "optional - long UID 224 bits"),
arg_int0("c", "heden", "<decimal>", "Cardnumber for Heden 2L format"),
arg_strx0("r", "raw", "<hex>", "raw bytes"),
arg_lit0("q", "Q5", "optional - specify writing to Q5/T5555 tag"),
arg_int0(NULL, "fc", "<decimal>", "Facility Code (26 bit format)"),
arg_int0(NULL, "cn", "<decimal>", "Cardnumber (26 bit format)"),
arg_param_end
};
CLIExecWithReturn(ctx, Cmd, argtable, false);
@ -865,7 +886,3 @@ out:
return (int) idx;
}
int demodIndala(void) {
return CmdIndalaDemod("");
}

View file

@ -15,10 +15,11 @@
int CmdLFINDALA(const char *Cmd);
int detectIndala(uint8_t *dest, size_t *size, uint8_t *invert);
int detectIndala26(uint8_t *bitStream, size_t *size, uint8_t *invert);
int detectIndala64(uint8_t *bitStream, size_t *size, uint8_t *invert);
int detectIndala224(uint8_t *bitStream, size_t *size, uint8_t *invert);
int demodIndala(void);
//int detectIndala26(uint8_t *bitStream, size_t *size, uint8_t *invert);
//int detectIndala64(uint8_t *bitStream, size_t *size, uint8_t *invert);
//int detectIndala224(uint8_t *bitStream, size_t *size, uint8_t *invert);
int demodIndalaEx(int clk, int invert, int maxErr, bool verbose);
int demodIndala(bool verbose);
int getIndalaBits(uint8_t fc, uint16_t cn, uint8_t *bits);
#endif

View file

@ -95,8 +95,8 @@ static int CmdIOProxWatch(const char *Cmd) {
//by marshmellow
//IO-Prox demod - FSK RF/64 with preamble of 000000001
//print ioprox ID and some format details
static int CmdIOProxDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
int demodIOProx(bool verbose) {
(void) verbose; // unused so far
int idx = 0, retval = PM3_SUCCESS;
uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0};
size_t size = getFromGraphBuf(bits);
@ -190,10 +190,15 @@ static int CmdIOProxDemod(const char *Cmd) {
return retval;
}
static int CmdIOProxDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodIOProx(true);
}
// this read is the "normal" read, which download lf signal and tries to demod here.
static int CmdIOProxRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
lf_read(false, 12000);
return CmdIOProxDemod(Cmd);
return demodIOProx(true);
}
static int CmdIOProxSim(const char *Cmd) {
uint16_t cn = 0;
@ -311,10 +316,6 @@ int CmdLFIO(const char *Cmd) {
return CmdsParse(CommandTable, Cmd);
}
int demodIOProx(void) {
return CmdIOProxDemod("");
}
//Index map
//0 10 20 30 40 50 60
//| | | | | | |

View file

@ -8,7 +8,7 @@
int CmdLFIO(const char *Cmd);
int demodIOProx(void);
int demodIOProx(bool verbose);
int getIOProxBits(uint8_t version, uint8_t fc, uint16_t cn, uint8_t *bits);
#endif

View file

@ -78,16 +78,11 @@ static uint64_t getJablontronCardId(uint64_t rawcode) {
return id;
}
//see ASKDemod for what args are accepted
static int CmdJablotronDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodJablotron();
}
int demodJablotron(void) {
int demodJablotron(bool verbose) {
(void) verbose; // unused so far
//Differential Biphase / di-phase (inverted biphase)
//get binary from ask wave
if (ASKbiphaseDemod("0 64 1 0", false) != PM3_SUCCESS) {
if (ASKbiphaseDemod(0, 64, 1, 0, false) != PM3_SUCCESS) {
if (g_debugMode) PrintAndLogEx(DEBUG, "DEBUG: Error - Jablotron ASKbiphaseDemod failed");
return PM3_ESOFT;
}
@ -137,9 +132,16 @@ int demodJablotron(void) {
return PM3_SUCCESS;
}
//see ASKDemod for what args are accepted
static int CmdJablotronDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodJablotron(true);
}
static int CmdJablotronRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
lf_read(false, 16000);
return demodJablotron();
return demodJablotron(true);
}
static int CmdJablotronClone(const char *Cmd) {

View file

@ -13,7 +13,7 @@
int CmdLFJablotron(const char *Cmd);
int demodJablotron(void);
int demodJablotron(bool verbose);
int detectJablotron(uint8_t *bits, size_t *size);
int getJablotronBits(uint64_t fullcode, uint8_t *bits);

View file

@ -135,14 +135,10 @@ static int CmdKeriMSScramble(KeriMSScramble_t Action, uint32_t *FC, uint32_t *ID
return PM3_SUCCESS;
}
static int CmdKeriDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodKeri();
}
int demodKeri(bool verbose) {
(void) verbose; // unused so far
int demodKeri(void) {
if (PSKDemod("", false) != PM3_SUCCESS) {
if (PSKDemod(0, 0, 100, false) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - KERI: PSK1 Demod failed");
return PM3_ESOFT;
}
@ -212,9 +208,15 @@ int demodKeri(void) {
return PM3_SUCCESS;
}
static int CmdKeriDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodKeri(true);
}
static int CmdKeriRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
lf_read(false, 10000);
return CmdKeriDemod(Cmd);
return demodKeri(true);
}
static int CmdKeriClone(const char *Cmd) {

View file

@ -13,7 +13,7 @@
int CmdLFKeri(const char *Cmd);
int demodKeri(void);
int demodKeri(bool verbose);
int detectKeri(uint8_t *dest, size_t *size, bool *invert);
#endif

View file

@ -28,16 +28,10 @@
static int CmdHelp(const char *Cmd);
//see PSKDemod for what args are accepted
static int CmdMotorolaDemod(const char *Cmd) {
(void)Cmd;
return demodMotorola();
}
int demodMotorola(void) {
int demodMotorola(bool verbose) {
(void) verbose; // unused so far
//PSK1
if (PSKDemod("32 1", true) != PM3_SUCCESS) {
if (PSKDemod(32, 1, 100, true) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - Motorola: PSK Demod failed");
return PM3_ESOFT;
}
@ -124,6 +118,12 @@ int demodMotorola(void) {
return PM3_SUCCESS;
}
//see PSKDemod for what args are accepted
static int CmdMotorolaDemod(const char *Cmd) {
(void)Cmd;
return demodMotorola(true);
}
static int CmdMotorolaRead(const char *Cmd) {
// Motorola Flexpass seem to work at 74 kHz
// and take about 4400 samples to befor modulating
@ -145,7 +145,7 @@ static int CmdMotorolaRead(const char *Cmd) {
sc.divisor = LF_DIVISOR_125;
sc.samples_to_skip = 0;
lf_config(&sc);
return demodMotorola();
return demodMotorola(true);
}
static int CmdMotorolaClone(const char *Cmd) {
@ -155,12 +155,10 @@ static int CmdMotorolaClone(const char *Cmd) {
int datalen = 0;
CLIParserContext *ctx;
CLIParserInit(&ctx, "lf indala clone",
CLIParserInit(&ctx, "lf motorola clone",
"Enables cloning of Motorola card with specified uid onto T55x7\n"
"defaults to 64.\n",
"\n"
"Samples:\n"
_YELLOW_("\tlf motorola clone a0000000a0002021") "\n"
"defaults to 64.",
"lf motorola clone a0000000a0002021"
);
void *argtable[] = {

View file

@ -14,7 +14,7 @@
int CmdLFMotorola(const char *Cmd);
int demodMotorola(void);
int demodMotorola(bool verbose);
int detectMotorola(uint8_t *dest, size_t *size);
int readMotorolaUid(void);
#endif

View file

@ -107,15 +107,14 @@ static uint8_t isEven_64_63(const uint8_t *data) { // 8
}
//NEDAP demod - ASK/Biphase (or Diphase), RF/64 with preamble of 1111111110 (always a 128 bit data stream)
static int CmdLFNedapDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
int demodNedap(bool verbose) {
(void) verbose; // unused so far
uint8_t data[16], buffer[7], r0, r1, r2, r3, r4, r5, idxC1, idxC2, idxC3, idxC4, idxC5, fixed0, fixed1, unk1, unk2, subtype; // 4 bits
size_t size, offset = 0;
uint16_t checksum, customerCode; // 12 bits
uint32_t badgeId; // max 99999
if (ASKbiphaseDemod("0 64 1 0", false) != PM3_SUCCESS) {
if (ASKbiphaseDemod(0, 64, 1, 0, false) != PM3_SUCCESS) {
if (g_debugMode) PrintAndLogEx(DEBUG, "DEBUG: Error - NEDAP: ASK/Biphase Demod failed");
return PM3_ESOFT;
}
@ -262,6 +261,10 @@ static int CmdLFNedapDemod(const char *Cmd) {
return PM3_SUCCESS;
}
static int CmdLFNedapDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodNedap(true);
}
/* Index map E E
preamble enc tag type encrypted uid P d 33 d 90 d 04 d 71 d 40 d 45 d E7 P
1111111110 00101101000001011010001100100100001011010100110101100 1 0 00110011 0 10010000 0 00000100 0 01110001 0 01000000 0 01000101 0 11100111 1
@ -307,8 +310,9 @@ lf t55xx wr b 4 d 4c0003ff
*/
static int CmdLFNedapRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
lf_read(false, 16000);
return CmdLFNedapDemod(Cmd);
return demodNedap(true);
}
static void NedapGen(uint8_t subType, uint16_t customerCode, uint32_t id, bool isLong, uint8_t *data) { // 8 or 16
@ -554,8 +558,3 @@ int CmdLFNedap(const char *Cmd) {
clearCommandBuffer();
return CmdsParse(CommandTable, Cmd);
}
int demodNedap(void) {
return CmdLFNedapDemod("");
}

View file

@ -13,7 +13,7 @@
int CmdLFNedap(const char *Cmd);
int demodNedap(void);
int demodNedap(bool verbose);
int detectNedap(uint8_t *dest, size_t *size);
int getNedapBits(uint32_t cn, uint8_t *nedapBits);

View file

@ -150,8 +150,9 @@ static int nexwatch_scamble(NexWatchScramble_t action, uint32_t *id, uint32_t *s
return PM3_SUCCESS;
}
int demodNexWatch(void) {
if (PSKDemod("", false) != PM3_SUCCESS) {
int demodNexWatch(bool verbose) {
(void) verbose; // unused so far
if (PSKDemod(0, 0, 100, false) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - NexWatch can't demod signal");
return PM3_ESOFT;
}
@ -259,14 +260,15 @@ int demodNexWatch(void) {
static int CmdNexWatchDemod(const char *Cmd) {
(void)Cmd;
return demodNexWatch();
return demodNexWatch(true);
}
//by marshmellow
//see ASKDemod for what args are accepted
static int CmdNexWatchRead(const char *Cmd) {
(void)Cmd;
lf_read(false, 20000);
return CmdNexWatchDemod(Cmd);
return demodNexWatch(true);
}
static int CmdNexWatchClone(const char *Cmd) {

View file

@ -13,6 +13,6 @@
int CmdLFNEXWATCH(const char *Cmd);
int demodNexWatch(void);
int demodNexWatch(bool verbose);
int detectNexWatch(uint8_t *dest, size_t *size, bool *invert);
#endif

View file

@ -62,12 +62,11 @@ static uint8_t noralsy_chksum(uint8_t *bits, uint8_t len) {
}
//see ASKDemod for what args are accepted
static int CmdNoralsyDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
int demodNoralsy(bool verbose) {
(void) verbose; // unused so far
//ASK / Manchester
bool st = true;
if (ASKDemod_ext("32 0 0", false, false, 1, &st) != PM3_SUCCESS) {
if (ASKDemod_ext(32, 0, 0, 0, false, false, false, 1, &st) != PM3_SUCCESS) {
if (g_debugMode) PrintAndLogEx(DEBUG, "DEBUG: Error - Noralsy: ASK/Manchester Demod failed");
return PM3_ESOFT;
}
@ -132,9 +131,15 @@ static int CmdNoralsyDemod(const char *Cmd) {
return PM3_SUCCESS;
}
static int CmdNoralsyDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodNoralsy(true);
}
static int CmdNoralsyRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
lf_read(false, 8000);
return CmdNoralsyDemod(Cmd);
return demodNoralsy(true);
}
static int CmdNoralsyClone(const char *Cmd) {
@ -291,7 +296,3 @@ int detectNoralsy(uint8_t *dest, size_t *size) {
* * = unknown
*
**/
int demodNoralsy(void) {
return CmdNoralsyDemod("");
}

View file

@ -13,7 +13,7 @@
int CmdLFNoralsy(const char *Cmd);
int demodNoralsy(void);
int demodNoralsy(bool verbose);
int detectNoralsy(uint8_t *dest, size_t *size);
int getnoralsyBits(uint32_t id, uint16_t year, uint8_t *bits);

View file

@ -144,14 +144,10 @@ static void pacCardIdToRaw(uint8_t *outRawBytes, const char *cardId) {
}
//see NRZDemod for what args are accepted
static int CmdPacDemod(const char *Cmd) {
(void)Cmd;
return demodPac();
}
int demodPac(void) {
int demodPac(bool verbose) {
(void) verbose; // unused so far
//NRZ
if (NRZrawDemod("", false) != PM3_SUCCESS) {
if (NRZrawDemod(0, 0, 100, false) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - PAC: NRZ Demod failed");
return PM3_ESOFT;
}
@ -188,9 +184,15 @@ int demodPac(void) {
return retval;
}
static int CmdPacDemod(const char *Cmd) {
(void)Cmd;
return demodPac(true);
}
static int CmdPacRead(const char *Cmd) {
(void)Cmd;
lf_read(false, 4096 * 2 + 20);
return CmdPacDemod(Cmd);
return demodPac(true);
}
static int CmdPacClone(const char *Cmd) {

View file

@ -13,7 +13,7 @@
int CmdLFPac(const char *Cmd);
int demodPac(void);
int demodPac(bool verbose);
int detectPac(uint8_t *dest, size_t *size);
#endif

View file

@ -71,16 +71,12 @@ const uint8_t paradox_lut[] = {
#define PARADOX_PREAMBLE_LEN 8
static int CmdParadoxDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodParadox();
}
//by marshmellow
//Paradox Prox demod - FSK2a RF/50 with preamble of 00001111 (then manchester encoded)
//print full Paradox Prox ID and some bit format details if found
int demodParadox(void) {
int demodParadox(bool verbose) {
(void) verbose; // unused so far
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0};
size_t size = getFromGraphBuf(bits);
@ -201,11 +197,18 @@ int demodParadox(void) {
return PM3_SUCCESS;
}
static int CmdParadoxDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodParadox(true);
}
//by marshmellow
//see ASKDemod for what args are accepted
static int CmdParadoxRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
lf_read(false, 10000);
return CmdParadoxDemod(Cmd);
return demodParadox(true);
}
static int CmdParadoxClone(const char *Cmd) {

View file

@ -13,6 +13,6 @@
int CmdLFParadox(const char *Cmd);
int demodParadox(void);
int demodParadox(bool verbose);
int detectParadox(uint8_t *dest, size_t *size, int *wave_start_idx);
#endif

View file

@ -57,10 +57,10 @@ static int usage_lf_presco_sim(void) {
}
//see ASKDemod for what args are accepted
static int CmdPrescoDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
int demodPresco(bool verbose) {
(void) verbose; // unused so far
bool st = true;
if (ASKDemod_ext("32 0 0 0 0 a", false, false, 1, &st) != PM3_SUCCESS) {
if (ASKDemod_ext(32, 0, 0, 0, false, false, false, 1, &st) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error Presco ASKDemod failed");
return PM3_ESOFT;
}
@ -97,11 +97,17 @@ static int CmdPrescoDemod(const char *Cmd) {
return PM3_SUCCESS;
}
static int CmdPrescoDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodPresco(true);
}
//see ASKDemod for what args are accepted
static int CmdPrescoRead(const char *Cmd) {
// Presco Number: 123456789 --> Sitecode 30 | usercode 8665
(void)Cmd; // Cmd is not used so far
lf_read(false, 12000);
return CmdPrescoDemod(Cmd);
return demodPresco(true);
}
// takes base 12 ID converts to hex
@ -178,6 +184,7 @@ static int CmdPrescoSim(const char *Cmd) {
static command_t CommandTable[] = {
{"help", CmdHelp, AlwaysAvailable, "This help"},
{"demod", CmdPrescoDemod, AlwaysAvailable, "demodulate Presco tag from the GraphBuffer"},
{"read", CmdPrescoRead, IfPm3Lf, "Attempt to read and Extract tag data"},
{"clone", CmdPrescoClone, IfPm3Lf, "clone presco tag to T55x7 or Q5/T5555"},
{"sim", CmdPrescoSim, IfPm3Lf, "simulate presco tag"},
@ -277,8 +284,3 @@ int getPrescoBits(uint32_t fullcode, uint8_t *prescoBits) {
num_to_bytebits(fullcode, 32, prescoBits + 96);
return PM3_SUCCESS;
}
int demodPresco(void) {
return CmdPrescoDemod("");
}

View file

@ -13,7 +13,7 @@
int CmdLFPresco(const char *Cmd);
int demodPresco(void);
int demodPresco(bool verbose);
int detectPresco(uint8_t *dest, size_t *size);
int getPrescoBits(uint32_t fullcode, uint8_t *prescoBits);
int getWiegandFromPresco(const char *Cmd, uint32_t *sitecode, uint32_t *usercode, uint32_t *fullcode, bool *Q5);

View file

@ -64,14 +64,10 @@ static int usage_lf_pyramid_sim(void) {
return PM3_SUCCESS;
}
static int CmdPyramidDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodPyramid();
}
//Pyramid Prox demod - FSK RF/50 with preamble of 0000000000000001 (always a 128 bit data stream)
//print full Farpointe Data/Pyramid Prox ID and some bit format details if found
int demodPyramid(void) {
int demodPyramid(bool verbose) {
(void) verbose; // unused so far
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
uint8_t bits[MAX_GRAPH_TRACE_LEN] = {0};
size_t size = getFromGraphBuf(bits);
@ -213,9 +209,15 @@ int demodPyramid(void) {
return PM3_SUCCESS;
}
static int CmdPyramidDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodPyramid(true);
}
static int CmdPyramidRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
lf_read(false, 15000);
return CmdPyramidDemod(Cmd);
return demodPyramid(true);
}
static int CmdPyramidClone(const char *Cmd) {

View file

@ -13,7 +13,7 @@
int CmdLFPyramid(const char *Cmd);
int demodPyramid(void);
int demodPyramid(bool verbose);
int detectPyramid(uint8_t *dest, size_t *size, int *waveStartIdx);
int getPyramidBits(uint32_t fc, uint32_t cn, uint8_t *pyramidBits);
#endif

View file

@ -38,17 +38,13 @@ static int usage_lf_securakey_clone(void) {
return PM3_SUCCESS;
}
static int CmdSecurakeyDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodSecurakey();
}
//see ASKDemod for what args are accepted
int demodSecurakey(void) {
int demodSecurakey(bool verbose) {
(void) verbose; // unused so far
//ASK / Manchester
bool st = false;
if (ASKDemod_ext("40 0 0", false, false, 1, &st) != PM3_SUCCESS) {
if (ASKDemod_ext(40, 0, 0, 0, false, false, false, 1, &st) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - Securakey: ASK/Manchester Demod failed");
return PM3_ESOFT;
}
@ -128,9 +124,15 @@ int demodSecurakey(void) {
return PM3_SUCCESS;
}
static int CmdSecurakeyDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodSecurakey(true);
}
static int CmdSecurakeyRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
lf_read(false, 8000);
return CmdSecurakeyDemod(Cmd);
return demodSecurakey(true);
}
static int CmdSecurakeyClone(const char *Cmd) {

View file

@ -13,7 +13,7 @@
int CmdLFSecurakey(const char *Cmd);
int demodSecurakey(void);
int demodSecurakey(bool verbose);
int detectSecurakey(uint8_t *dest, size_t *size);
#endif

View file

@ -354,8 +354,8 @@ static int usage_t55xx_protect(void) {
print_usage_t55xx_downloadlink(T55XX_DLMODE_SINGLE, config.downlink_mode);
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx protect n 01020304") " - sets new password to 01020304");
PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx protect p 11223344") " - use pwd 11223344 to set newpwd to 00000000");
PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx protect n 01020304") " - sets new password to 01020304");
PrintAndLogEx(NORMAL, _YELLOW_(" lf t55xx protect p 11223344 n 00000000") " - use pwd 11223344 to set newpwd to 00000000");
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}
@ -379,7 +379,7 @@ static int usage_t55xx_clonehelp(void) {
PrintAndLogEx(NORMAL, "For cloning specific techs on T55xx tags, see commands available in corresponding LF sub-menus, e.g.:");
PrintAndLogEx(NORMAL, _GREEN_("lf awid clone"));
// todo: rename to clone
PrintAndLogEx(NORMAL, _GREEN_("lf em 410x_write"));
PrintAndLogEx(NORMAL, _GREEN_("lf em 410x_clone"));
// todo: implement restore
// PrintAndLogEx(NORMAL, _GREEN_("lf em 4x05_write"));
// PrintAndLogEx(NORMAL, _GREEN_("lf em 4x50_write"));
@ -407,7 +407,7 @@ static int usage_t55xx_sniff(void) {
PrintAndLogEx(NORMAL, "Usage: lf t55xx sniff [w <width 0> <width 1>] [l <min level>] [s <level>] [t <level>] [1] [h]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " w <0> <1> - Set samples width for 0 and 1 matching (default auto detect)");
// PrintAndLogEx(NORMAL, " s <level> - Set minimum signal level (default 20)");
// PrintAndLogEx(NORMAL, " s <level> - Set minimum signal level (default 20)");
PrintAndLogEx(NORMAL, " t <level> - Set tolerance level (default 5). lower means tighter");
PrintAndLogEx(NORMAL, " 1 - Extract from current sample buffer (default will get new samples)");
PrintAndLogEx(NORMAL, " h - This help");
@ -944,8 +944,6 @@ static int CmdT55xxReadBlock(const char *Cmd) {
bool DecodeT55xxBlock(void) {
char buf[30] = {0x00};
char *cmdStr = buf;
int ans = 0;
bool ST = config.ST;
uint8_t bitRate[8] = {8, 16, 32, 40, 50, 64, 100, 128};
@ -953,41 +951,33 @@ bool DecodeT55xxBlock(void) {
switch (config.modulation) {
case DEMOD_FSK:
snprintf(cmdStr, sizeof(buf), "%d %d", bitRate[config.bitrate], config.inverted);
ans = FSKrawDemod(cmdStr, false);
ans = FSKrawDemod(bitRate[config.bitrate], config.inverted, 0, 0, false);
break;
case DEMOD_FSK1:
case DEMOD_FSK1a:
snprintf(cmdStr, sizeof(buf), "%d %d 8 5", bitRate[config.bitrate], config.inverted);
ans = FSKrawDemod(cmdStr, false);
ans = FSKrawDemod(bitRate[config.bitrate], config.inverted, 8, 5, false);
break;
case DEMOD_FSK2:
case DEMOD_FSK2a:
snprintf(cmdStr, sizeof(buf), "%d %d 10 8", bitRate[config.bitrate], config.inverted);
ans = FSKrawDemod(cmdStr, false);
ans = FSKrawDemod(bitRate[config.bitrate], config.inverted, 10, 8, false);
break;
case DEMOD_ASK:
snprintf(cmdStr, sizeof(buf), "%d %d 1", bitRate[config.bitrate], config.inverted);
ans = ASKDemod_ext(cmdStr, false, false, 1, &ST);
ans = ASKDemod_ext(bitRate[config.bitrate], config.inverted, 1, 0, false, false, false, 1, &ST);
break;
case DEMOD_PSK1:
snprintf(cmdStr, sizeof(buf), "%d %d 6", bitRate[config.bitrate], config.inverted);
ans = PSKDemod(cmdStr, false);
ans = PSKDemod(bitRate[config.bitrate], config.inverted, 6, false);
break;
case DEMOD_PSK2: //inverted won't affect this
case DEMOD_PSK3: //not fully implemented
snprintf(cmdStr, sizeof(buf), "%d 0 6", bitRate[config.bitrate]);
ans = PSKDemod(cmdStr, false);
ans = PSKDemod(bitRate[config.bitrate], 0, 6, false);
psk1TOpsk2(DemodBuffer, DemodBufferLen);
break;
case DEMOD_NRZ:
snprintf(cmdStr, sizeof(buf), "%d %d 1", bitRate[config.bitrate], config.inverted);
ans = NRZrawDemod(cmdStr, false);
ans = NRZrawDemod(bitRate[config.bitrate], config.inverted, 1, false);
break;
case DEMOD_BI:
case DEMOD_BIa:
snprintf(cmdStr, sizeof(buf), "0 %d %d 1", bitRate[config.bitrate], config.inverted);
ans = ASKbiphaseDemod(cmdStr, false);
ans = ASKbiphaseDemod(0, bitRate[config.bitrate], config.inverted, 1, false);
break;
default:
return false;
@ -999,7 +989,8 @@ static bool DecodeT5555TraceBlock(void) {
DemodBufferLen = 0x00;
// According to datasheet. Always: RF/64, not inverted, Manchester
return (ASKDemod("64 0 1", false, false, 1) == PM3_SUCCESS);
bool st = false;
return (ASKDemod_ext(64, 0, 1, 0, false, false, false, 1, &st) == PM3_SUCCESS);
}
// sanity check. Don't use proxmark if it is offline and you didn't specify useGraphbuf
@ -1139,7 +1130,7 @@ bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wa
ans = fskClocks(&fc1, &fc2, (uint8_t *)&clk, &firstClockEdge);
if (ans && ((fc1 == 10 && fc2 == 8) || (fc1 == 8 && fc2 == 5))) {
if ((FSKrawDemod("0 0", false) == PM3_SUCCESS) && test(DEMOD_FSK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
if ((FSKrawDemod(0, 0, 0, 0, false) == PM3_SUCCESS) && test(DEMOD_FSK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
tests[hits].modulation = DEMOD_FSK;
if (fc1 == 8 && fc2 == 5)
tests[hits].modulation = DEMOD_FSK1a;
@ -1152,7 +1143,7 @@ bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wa
tests[hits].downlink_mode = downlink_mode;
++hits;
}
if ((FSKrawDemod("0 1", false) == PM3_SUCCESS) && test(DEMOD_FSK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
if ((FSKrawDemod(0, 1, 0, 0, false) == PM3_SUCCESS) && test(DEMOD_FSK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
tests[hits].modulation = DEMOD_FSK;
if (fc1 == 8 && fc2 == 5)
tests[hits].modulation = DEMOD_FSK1;
@ -1174,7 +1165,7 @@ bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wa
// false = no emSearch
// 1 = Ask/Man
// st = true
if ((ASKDemod_ext("0 0 1", false, false, 1, &tests[hits].ST) == PM3_SUCCESS) && test(DEMOD_ASK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
if ((ASKDemod_ext(0, 0, 1, 0, false, false, false, 1, &tests[hits].ST) == PM3_SUCCESS) && test(DEMOD_ASK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
tests[hits].modulation = DEMOD_ASK;
tests[hits].bitrate = bitRate;
tests[hits].inverted = false;
@ -1188,7 +1179,7 @@ bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wa
// false = no emSearch
// 1 = Ask/Man
// st = true
if ((ASKDemod_ext("0 1 1", false, false, 1, &tests[hits].ST) == PM3_SUCCESS) && test(DEMOD_ASK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
if ((ASKDemod_ext(0, 1, 1, 0, false, false, false, 1, &tests[hits].ST) == PM3_SUCCESS) && test(DEMOD_ASK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
tests[hits].modulation = DEMOD_ASK;
tests[hits].bitrate = bitRate;
tests[hits].inverted = true;
@ -1196,7 +1187,7 @@ bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wa
tests[hits].downlink_mode = downlink_mode;
++hits;
}
if ((ASKbiphaseDemod("0 0 0 2", false) == PM3_SUCCESS) && test(DEMOD_BI, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
if ((ASKbiphaseDemod(0, 0, 0, 2, false) == PM3_SUCCESS) && test(DEMOD_BI, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
tests[hits].modulation = DEMOD_BI;
tests[hits].bitrate = bitRate;
tests[hits].inverted = false;
@ -1205,7 +1196,7 @@ bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wa
tests[hits].downlink_mode = downlink_mode;
++hits;
}
if ((ASKbiphaseDemod("0 0 1 2", false) == PM3_SUCCESS) && test(DEMOD_BIa, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
if ((ASKbiphaseDemod(0, 0, 1, 2, false) == PM3_SUCCESS) && test(DEMOD_BIa, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
tests[hits].modulation = DEMOD_BIa;
tests[hits].bitrate = bitRate;
tests[hits].inverted = true;
@ -1217,7 +1208,7 @@ bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wa
}
clk = GetNrzClock("", false);
if (clk > 8) { //clock of rf/8 is likely a false positive, so don't use it.
if ((NRZrawDemod("0 0 1", false) == PM3_SUCCESS) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
if ((NRZrawDemod(0, 0, 1, false) == PM3_SUCCESS) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
tests[hits].modulation = DEMOD_NRZ;
tests[hits].bitrate = bitRate;
tests[hits].inverted = false;
@ -1227,7 +1218,7 @@ bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wa
++hits;
}
if ((NRZrawDemod("0 1 1", false) == PM3_SUCCESS) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
if ((NRZrawDemod(0, 1, 1, false) == PM3_SUCCESS) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
tests[hits].modulation = DEMOD_NRZ;
tests[hits].bitrate = bitRate;
tests[hits].inverted = true;
@ -1244,7 +1235,7 @@ bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wa
save_restoreGB(GRAPH_SAVE);
// skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)
CmdLtrim("160");
if ((PSKDemod("0 0 6", false) == PM3_SUCCESS) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
if ((PSKDemod(0, 0, 6, false) == PM3_SUCCESS) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
tests[hits].modulation = DEMOD_PSK1;
tests[hits].bitrate = bitRate;
tests[hits].inverted = false;
@ -1253,7 +1244,7 @@ bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wa
tests[hits].downlink_mode = downlink_mode;
++hits;
}
if ((PSKDemod("0 1 6", false) == PM3_SUCCESS) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
if ((PSKDemod(0, 1, 6, false) == PM3_SUCCESS) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
tests[hits].modulation = DEMOD_PSK1;
tests[hits].bitrate = bitRate;
tests[hits].inverted = true;
@ -1264,7 +1255,7 @@ bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wa
}
//ICEMAN: are these PSKDemod calls needed?
// PSK2 - needs a call to psk1TOpsk2.
if (PSKDemod("0 0 6", false) == PM3_SUCCESS) {
if (PSKDemod(0, 0, 6, false) == PM3_SUCCESS) {
psk1TOpsk2(DemodBuffer, DemodBufferLen);
if (test(DEMOD_PSK2, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
tests[hits].modulation = DEMOD_PSK2;
@ -1277,7 +1268,7 @@ bool tryDetectModulationEx(uint8_t downlink_mode, bool print_config, uint32_t wa
}
} // inverse waves does not affect this demod
// PSK3 - needs a call to psk1TOpsk2.
if (PSKDemod("0 0 6", false) == PM3_SUCCESS) {
if (PSKDemod(0, 0, 6, false) == PM3_SUCCESS) {
psk1TOpsk2(DemodBuffer, DemodBufferLen);
if (test(DEMOD_PSK3, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
tests[hits].modulation = DEMOD_PSK3;
@ -3037,9 +3028,9 @@ static int CmdT55xxChkPwds(const char *Cmd) {
case 'e':
// White cloner password based on EM4100 ID
useCardPassword = true;
cardID = param_get64ex(Cmd,cmdp + 1,0,16);
cardID = param_get64ex(Cmd, cmdp + 1, 0, 16);
uint32_t card32Bit = cardID & 0xFFFFFFFF;
cardPassword = lf_t55xx_white_pwdgen (card32Bit);
cardPassword = lf_t55xx_white_pwdgen(card32Bit);
cmdp += 2;
break;
default:
@ -3414,12 +3405,12 @@ bool tryDetectP1(bool getData) {
// try fsk clock detect. if successful it cannot be any other type of modulation... (in theory...)
ans = fskClocks(&fc1, &fc2, (uint8_t *)&clk, &firstClockEdge);
if (ans && ((fc1 == 10 && fc2 == 8) || (fc1 == 8 && fc2 == 5))) {
if ((FSKrawDemod("0 0", false) == PM3_SUCCESS) &&
if ((FSKrawDemod(0, 0, 0, 0, false) == PM3_SUCCESS) &&
preambleSearchEx(DemodBuffer, preamble, sizeof(preamble), &DemodBufferLen, &startIdx, false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64)) {
return true;
}
if ((FSKrawDemod("0 1", false) == PM3_SUCCESS) &&
if ((FSKrawDemod(0, 1, 0, 0, false) == PM3_SUCCESS) &&
preambleSearchEx(DemodBuffer, preamble, sizeof(preamble), &DemodBufferLen, &startIdx, false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64)) {
return true;
@ -3430,26 +3421,26 @@ bool tryDetectP1(bool getData) {
// try ask clock detect. it could be another type even if successful.
clk = GetAskClock("", false);
if (clk > 0) {
if ((ASKDemod_ext("0 0 1", false, false, 1, &st) == PM3_SUCCESS) &&
if ((ASKDemod_ext(0, 0, 1, 0, false, false, false, 1, &st) == PM3_SUCCESS) &&
preambleSearchEx(DemodBuffer, preamble, sizeof(preamble), &DemodBufferLen, &startIdx, false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64)) {
return true;
}
st = true;
if ((ASKDemod_ext("0 1 1", false, false, 1, &st) == PM3_SUCCESS) &&
if ((ASKDemod_ext(0, 1, 1, 0, false, false, false, 1, &st) == PM3_SUCCESS) &&
preambleSearchEx(DemodBuffer, preamble, sizeof(preamble), &DemodBufferLen, &startIdx, false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64)) {
return true;
}
if ((ASKbiphaseDemod("0 0 0 2", false) == PM3_SUCCESS) &&
if ((ASKbiphaseDemod(0, 0, 0, 2, false) == PM3_SUCCESS) &&
preambleSearchEx(DemodBuffer, preamble, sizeof(preamble), &DemodBufferLen, &startIdx, false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64)) {
return true;
}
if ((ASKbiphaseDemod("0 0 1 2", false) == PM3_SUCCESS) &&
if ((ASKbiphaseDemod(0, 0, 1, 2, false) == PM3_SUCCESS) &&
preambleSearchEx(DemodBuffer, preamble, sizeof(preamble), &DemodBufferLen, &startIdx, false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64)) {
return true;
@ -3459,12 +3450,12 @@ bool tryDetectP1(bool getData) {
// try NRZ clock detect. it could be another type even if successful.
clk = GetNrzClock("", false); //has the most false positives :(
if (clk > 0) {
if ((NRZrawDemod("0 0 1", false) == PM3_SUCCESS) &&
if ((NRZrawDemod(0, 0, 1, false) == PM3_SUCCESS) &&
preambleSearchEx(DemodBuffer, preamble, sizeof(preamble), &DemodBufferLen, &startIdx, false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64)) {
return true;
}
if ((NRZrawDemod("0 1 1", false) == PM3_SUCCESS) &&
if ((NRZrawDemod(0, 1, 1, false) == PM3_SUCCESS) &&
preambleSearchEx(DemodBuffer, preamble, sizeof(preamble), &DemodBufferLen, &startIdx, false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64)) {
return true;
@ -3479,20 +3470,20 @@ bool tryDetectP1(bool getData) {
// save_restoreGB(GRAPH_SAVE);
// skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)
//CmdLtrim("160");
if ((PSKDemod("0 0 6", false) == PM3_SUCCESS) &&
if ((PSKDemod(0, 0, 6, false) == PM3_SUCCESS) &&
preambleSearchEx(DemodBuffer, preamble, sizeof(preamble), &DemodBufferLen, &startIdx, false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64)) {
//save_restoreGB(GRAPH_RESTORE);
return true;
}
if ((PSKDemod("0 1 6", false) == PM3_SUCCESS) &&
if ((PSKDemod(0, 1, 6, false) == PM3_SUCCESS) &&
preambleSearchEx(DemodBuffer, preamble, sizeof(preamble), &DemodBufferLen, &startIdx, false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64)) {
//save_restoreGB(GRAPH_RESTORE);
return true;
}
// PSK2 - needs a call to psk1TOpsk2.
if (PSKDemod("0 0 6", false) == PM3_SUCCESS) {
if (PSKDemod(0, 0, 6, false) == PM3_SUCCESS) {
psk1TOpsk2(DemodBuffer, DemodBufferLen);
if (preambleSearchEx(DemodBuffer, preamble, sizeof(preamble), &DemodBufferLen, &startIdx, false) &&
(DemodBufferLen == 32 || DemodBufferLen == 64)) {
@ -3775,7 +3766,7 @@ static uint8_t t55sniffGetPacket(int *pulseBuffer, char *data, uint8_t width0, u
i++;
continue;
}
if (approxEq(width1, pulseBuffer[i], tolerance)) {
if (approxEq(width1, pulseBuffer[i], tolerance)) {
data[dataLen++] = '1';
i++;
continue;
@ -3792,7 +3783,7 @@ static uint8_t t55sniffTrimSamples(int *pulseBuffer, int *pulseIdx, uint8_t len)
for (uint8_t ii = 0; ii < (80 - len); ii++) {
pulseBuffer[ii] = pulseBuffer[ii + len];
}
*pulseIdx -= len;
return PM3_SUCCESS;
}
@ -3815,7 +3806,7 @@ static int CmdT55xxSniff(const char *Cmd) {
char pwdText [100];
char dataText [100];
int pulseBuffer[80] = { 0 }; // max should be 73 +/- - Holds Pulse widths
char data[80]; // linked to pulseBuffer. - Holds 0/1 from pulse widths
char data[80]; // linked to pulseBuffer. - Holds 0/1 from pulse widths
/*
@ -3832,7 +3823,7 @@ static int CmdT55xxSniff(const char *Cmd) {
| Regular Read | 2 | 3 | 3 | 4 |
| Reset | 2 | 3 | 3 | 4 |
----------------------------------------------------------------
T55xx bit widths (decimation 1) - Expected, but may vary a little
Reference 0 for LL0 and Leading 0 can be longer
-----------------------------------------------
@ -3856,20 +3847,20 @@ static int CmdT55xxSniff(const char *Cmd) {
width1 = param_get8ex(Cmd, cmdp + 2, 0, 10);
cmdp += 3;
if (width0 == 0) PrintAndLogEx (ERR,"need both sample widths! "_RED_("Missing sample width for 0"));
if (width1 == 0) PrintAndLogEx (ERR,"need both sample widths! "_RED_("Missing sample width for 1"));
if (width0 == 0) PrintAndLogEx(ERR, "need both sample widths! "_RED_("Missing sample width for 0"));
if (width1 == 0) PrintAndLogEx(ERR, "need both sample widths! "_RED_("Missing sample width for 1"));
if ((width0 == 0) || (width1 == 0)) {
PrintAndLogEx (NORMAL,"");
PrintAndLogEx(NORMAL, "");
return usage_t55xx_sniff();
}
break;
case 't':
case 't':
tolerance = param_get8ex(Cmd, cmdp + 1, 0, 10);
cmdp += 2;
break;
default:
cmdp++;
PrintAndLogEx (ERR,"Invalid options supplied!");
PrintAndLogEx(ERR, "Invalid options supplied!");
return usage_t55xx_sniff();
}
}
@ -3877,12 +3868,12 @@ static int CmdT55xxSniff(const char *Cmd) {
// setup and sample data from Proxmark
// if not directed to existing sample/graphbuffer
if (sampleData) {
CmdLFSniff ("");
CmdLFSniff("");
}
// Headings
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(INFO,_CYAN_("T55xx command detection"));
PrintAndLogEx(INFO, _CYAN_("T55xx command detection"));
PrintAndLogEx(SUCCESS, "Downlink mode | password | Data | blk | page | 0 | 1 | raw");
PrintAndLogEx(SUCCESS, "----------------------+----------+----------+-----+------+-----+-----+-------------------------------------------------------------------------------");
@ -3918,13 +3909,13 @@ static int CmdT55xxSniff(const char *Cmd) {
if (pulseSamples > 0) {
pulseBuffer[pulseIdx++] = pulseSamples;
if (pulseIdx > 79) { // make room for next sample - if not used by now, it wont be.
t55sniffTrimSamples (pulseBuffer, &pulseIdx, 1);
t55sniffTrimSamples(pulseBuffer, &pulseIdx, 1);
}
// Check Samples for valid packets;
// We should find (outside of leading bits) we have a packet of "1" and "0" at same widths.
if (pulseIdx >= 6) {// min size for a read - ignoring 1of4 10 0 <adr>
// We auto find widths
if ((width0 == 0) && (width1 == 0)) {
// We ignore bit 0 for the moment as it may be a ref. pulse, so check last
@ -3932,13 +3923,13 @@ static int CmdT55xxSniff(const char *Cmd) {
minWidth = pulseBuffer[1];
maxWidth = pulseBuffer[1];
bool done = false;
while ((!done) && (ii < pulseIdx) && ((maxWidth <= minWidth) || (approxEq(minWidth,maxWidth,tolerance)))) { // min should be 8, 16-32 more normal
if (pulseBuffer[ii]+3 < minWidth) {
while ((!done) && (ii < pulseIdx) && ((maxWidth <= minWidth) || (approxEq(minWidth, maxWidth, tolerance)))) { // min should be 8, 16-32 more normal
if (pulseBuffer[ii] + 3 < minWidth) {
minWidth = pulseBuffer[ii];
done = true;
}
if (pulseBuffer[ii]-1 > maxWidth) {
if (pulseBuffer[ii] - 1 > maxWidth) {
maxWidth = pulseBuffer[ii];
done = true;
}
@ -3951,44 +3942,44 @@ static int CmdT55xxSniff(const char *Cmd) {
}
// out of bounds... min max far enough appart and minWidth is large enough
if (((maxWidth - minWidth) < 6) || (minWidth < 6)) // min 8 +/-
if (((maxWidth - minWidth) < 6) || (minWidth < 6)) // min 8 +/-
continue;
// At this point we should have
// At this point we should have
// - a min of 6 samples
// - the 0 and 1 sample widths
// - min 0 and min seperations (worst case)
// No max checks done (yet) as have seen samples > then specs in use.
// Check first bit.
// Long leading 0
if (haveData == false && (approxEq(pulseBuffer[0],136+minWidth,tolerance) && approxEq(pulseBuffer[1],maxWidth,tolerance))) {
printf ("Long Leading 0 - not yet hanled | have 1 Fisrt bit | Min : %-3d - Max : %-3d : diff : %d\n",minWidth,maxWidth, maxWidth-minWidth);
if (haveData == false && (approxEq(pulseBuffer[0], 136 + minWidth, tolerance) && approxEq(pulseBuffer[1], maxWidth, tolerance))) {
// printf ("Long Leading 0 - not yet hanled | have 1 Fisrt bit | Min : %-3d - Max : %-3d : diff : %d\n",minWidth,maxWidth, maxWidth-minWidth);
continue;
}
// Fixed bit - Default
if (haveData == false && (approxEq(pulseBuffer[0], maxWidth, tolerance))) {
dataLen = t55sniffGetPacket (pulseBuffer, data, minWidth, maxWidth, tolerance);
dataLen = t55sniffGetPacket(pulseBuffer, data, minWidth, maxWidth, tolerance);
// if ((dataLen == 39) )
// printf ("Fixed | Data end of 80 samples | offset : %llu - datalen %-2d - data : %s --- - Bit 0 width : %d\n",idx,dataLen,data,pulseBuffer[0]);
// if ((dataLen == 39) )
// printf ("Fixed | Data end of 80 samples | offset : %llu - datalen %-2d - data : %s --- - Bit 0 width : %d\n",idx,dataLen,data,pulseBuffer[0]);
if (data[0] == '0') { // should never get here..
dataLen = 0;
dataLen = 0;
data[0] = 0;
} else {
// Default Read
if (dataLen == 6) {
t55sniffTrimSamples (pulseBuffer, &pulseIdx,4); // left 1 or 2 samples seemed to help
t55sniffTrimSamples(pulseBuffer, &pulseIdx, 4); // left 1 or 2 samples seemed to help
page = data[1] - '0';
blockAddr = 0;
for (uint8_t i = 3; i < 6; i++) {
blockAddr <<= 1;
if (data[i] == '1')
if (data[i] == '1')
blockAddr |= 1;
}
blockData = 0;
@ -3998,92 +3989,92 @@ static int CmdT55xxSniff(const char *Cmd) {
// Password Write
if (dataLen == 70) {
t55sniffTrimSamples (pulseBuffer, &pulseIdx,70);
t55sniffTrimSamples(pulseBuffer, &pulseIdx, 70);
page = data[1] - '0';
usedPassword = 0;
for (uint8_t i = 2; i <= 33; i++) {
usedPassword <<= 1;
if (data[i] == '1')
if (data[i] == '1')
usedPassword |= 1;
}
// Lock bit 34
blockData = 0;
for (uint8_t i = 35; i <= 66; i++) {
blockData <<= 1;
if (data[i] == '1')
if (data[i] == '1')
blockData |= 1;
}
blockAddr = 0;
for (uint8_t i = 67; i <= 69; i++) {
blockAddr <<= 1;
if (data[i] == '1')
if (data[i] == '1')
blockAddr |= 1;
}
haveData = true;
sprintf(modeText, "Default pwd write");
sprintf(pwdText, "%08X", usedPassword);
sprintf(dataText, "%08X",blockData );
sprintf(dataText, "%08X", blockData);
}
// Default Write (or password read ??)
if (dataLen == 38) {
t55sniffTrimSamples (pulseBuffer, &pulseIdx,38);
t55sniffTrimSamples(pulseBuffer, &pulseIdx, 38);
page = data[1] - '0';
usedPassword = 0;
blockData = 0;
for (uint8_t i = 3; i <= 34; i++) {
blockData <<= 1;
if (data[i] == '1')
if (data[i] == '1')
blockData |= 1;
}
blockAddr = 0;
for (uint8_t i = 35; i <= 37; i++) {
blockAddr <<= 1;
if (data[i] == '1')
if (data[i] == '1')
blockAddr |= 1;
}
haveData = true;
sprintf(modeText, "Default write");
sprintf(dataText, "%08X",blockData );
sprintf(dataText, "%08X", blockData);
}
}
}
// Leading 0
if (haveData == false && (approxEq(pulseBuffer[0], minWidth, tolerance))) {
// leading 0 (should = 0 width)
// leading 0 (should = 0 width)
// 1 of 4 (leads with 00)
dataLen = t55sniffGetPacket (pulseBuffer,data,minWidth,maxWidth,tolerance);
dataLen = t55sniffGetPacket(pulseBuffer, data, minWidth, maxWidth, tolerance);
// **** Should check to 0 to be actual 0 as well i.e. 01 .... data ....
if ((data[0] == '0') && (data[1] == '1')) {
if (dataLen == 73) {
t55sniffTrimSamples (pulseBuffer, &pulseIdx, 73);
t55sniffTrimSamples(pulseBuffer, &pulseIdx, 73);
page = data[2] - '0';
usedPassword = 0;
for (uint8_t i = 5; i <= 36; i++) {
usedPassword <<= 1;
if (data[i] == '1')
if (data[i] == '1')
usedPassword |= 1;
}
blockData = 0;
for (uint8_t i = 38; i <= 69; i++) {
blockData <<= 1;
if (data[i] == '1')
if (data[i] == '1')
blockData |= 1;
}
blockAddr = 0;
for (uint8_t i = 70; i <= 72; i++) {
blockAddr <<= 1;
if (data[i] == '1')
if (data[i] == '1')
blockAddr |= 1;
}
haveData = true;
sprintf(modeText, "Leading 0 pwd write");
sprintf(pwdText, "%08X", usedPassword);
sprintf(dataText, "%08X",blockData );
sprintf(dataText, "%08X", blockData);
}
}
}
@ -4092,16 +4083,16 @@ static int CmdT55xxSniff(const char *Cmd) {
// Print results
if (haveData) { //&& (minWidth > 1) && (maxWidth > minWidth)){
if (blockAddr == 7)
PrintAndLogEx (SUCCESS, "%-20s | "_GREEN_("%8s")" | "_YELLOW_("%8s")" | "_YELLOW_("%d")" | "_GREEN_("%d")" | %3d | %3d | %s", modeText, pwdText, dataText, blockAddr, page, minWidth, maxWidth, data);
PrintAndLogEx(SUCCESS, "%-20s | "_GREEN_("%8s")" | "_YELLOW_("%8s")" | "_YELLOW_("%d")" | "_GREEN_("%d")" | %3d | %3d | %s", modeText, pwdText, dataText, blockAddr, page, minWidth, maxWidth, data);
else
PrintAndLogEx (SUCCESS, "%-20s | "_GREEN_("%8s")" | "_GREEN_("%8s")" | "_GREEN_("%d")" | "_GREEN_("%d")" | %3d | %3d | %s", modeText, pwdText, dataText, blockAddr, page, minWidth, maxWidth, data);
PrintAndLogEx(SUCCESS, "%-20s | "_GREEN_("%8s")" | "_GREEN_("%8s")" | "_GREEN_("%d")" | "_GREEN_("%d")" | %3d | %3d | %s", modeText, pwdText, dataText, blockAddr, page, minWidth, maxWidth, data);
}
}
// footer
PrintAndLogEx (SUCCESS, "-----------------------------------------------------------------------------------------------------------------------------------------------------");
PrintAndLogEx (NORMAL, "");
PrintAndLogEx(SUCCESS, "-----------------------------------------------------------------------------------------------------------------------------------------------------");
PrintAndLogEx(NORMAL, "");
return PM3_SUCCESS;
}

View file

@ -23,8 +23,8 @@
static int CmdHelp(const char *Cmd);
static int CmdTIDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
int demodTI(bool verbose) {
(void) verbose; // unused so far
/* MATLAB as follows:
f_s = 2000000; % sampling frequency
f_l = 123200; % low FSK tone
@ -271,6 +271,11 @@ out:
return retval;
}
static int CmdTIDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodTI(true);
}
// read a TI tag and return its ID
static int CmdTIRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
@ -317,8 +322,3 @@ int CmdLFTI(const char *Cmd) {
clearCommandBuffer();
return CmdsParse(CommandTable, Cmd);
}
int demodTI(void) {
return CmdTIDemod("");
}

View file

@ -15,5 +15,5 @@
int CmdLFTI(const char *Cmd);
int demodTI(void);
int demodTI(bool verbose);
#endif

View file

@ -38,14 +38,10 @@ static int usage_lf_verichip_clone(void) {
}
//see NRZDemod for what args are accepted
static int CmdVerichipDemod(const char *Cmd) {
(void)Cmd;
return demodVerichip();
}
int demodVerichip(void) {
int demodVerichip(bool verbose) {
(void) verbose; // unused so far
//NRZ
if (NRZrawDemod("", false) != PM3_SUCCESS) {
if (NRZrawDemod(0, 0, 100, false) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - VERICHIP: NRZ Demod failed");
return PM3_ESOFT;
}
@ -81,9 +77,15 @@ int demodVerichip(void) {
return PM3_SUCCESS;
}
static int CmdVerichipDemod(const char *Cmd) {
(void)Cmd;
return demodVerichip(true);
}
static int CmdVerichipRead(const char *Cmd) {
(void)Cmd;
lf_read(false, 4096 * 2 + 20);
return CmdVerichipDemod(Cmd);
return demodVerichip(true);
}
static int CmdVerichipClone(const char *Cmd) {

View file

@ -13,7 +13,7 @@
int CmdLFVerichip(const char *Cmd);
int demodVerichip(void);
int demodVerichip(bool verbose);
int detectVerichip(uint8_t *dest, size_t *size);
#endif

View file

@ -53,14 +53,12 @@ static int usage_lf_viking_sim(void) {
return PM3_SUCCESS;
}
static int CmdVikingDemod(const char *Cmd) {
return demodViking();
}
//see ASKDemod for what args are accepted
int demodViking(void) {
int demodViking(bool verbose) {
(void) verbose; // unused so far
if (ASKDemod("", false, false, 1) != PM3_SUCCESS) {
bool st = false;
if (ASKDemod_ext(0, 0, 100, 0, false, false, false, 1, &st) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - Viking ASKDemod failed");
return PM3_ESOFT;
}
@ -84,10 +82,16 @@ int demodViking(void) {
return PM3_SUCCESS;
}
static int CmdVikingDemod(const char *Cmd) {
(void)Cmd;
return demodViking(true);
}
//see ASKDemod for what args are accepted
static int CmdVikingRead(const char *Cmd) {
(void)Cmd;
lf_read(false, 10000);
return CmdVikingDemod(Cmd);
return demodViking(true);
}
static int CmdVikingClone(const char *Cmd) {

View file

@ -13,7 +13,7 @@
int CmdLFViking(const char *Cmd);
int demodViking(void);
int demodViking(bool verbose);
int detectViking(uint8_t *src, size_t *size);
uint64_t getVikingBits(uint32_t id);

View file

@ -87,10 +87,6 @@ static uint8_t visa_parity(uint32_t id) {
return par;
}
static int CmdVisa2kDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodVisa2k();
}
/**
*
* 56495332 00096ebd 00000077 > tag id 618173
@ -103,14 +99,15 @@ static int CmdVisa2kDemod(const char *Cmd) {
*
**/
//see ASKDemod for what args are accepted
int demodVisa2k(void) {
int demodVisa2k(bool verbose) {
(void) verbose; // unused so far
save_restoreGB(GRAPH_SAVE);
//CmdAskEdgeDetect("");
//ASK / Manchester
bool st = true;
if (ASKDemod_ext("64 0 0", false, false, 1, &st) != PM3_SUCCESS) {
if (ASKDemod_ext(64, 0, 0, 0, false, false, false, 1, &st) != PM3_SUCCESS) {
PrintAndLogEx(DEBUG, "DEBUG: Error - Visa2k: ASK/Manchester Demod failed");
save_restoreGB(GRAPH_RESTORE);
return PM3_ESOFT;
@ -160,10 +157,16 @@ int demodVisa2k(void) {
return PM3_SUCCESS;
}
static int CmdVisa2kDemod(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
return demodVisa2k(true);
}
// 64*96*2=12288 samples just in case we just missed the first preamble we can still catch 2 of them
static int CmdVisa2kRead(const char *Cmd) {
(void)Cmd; // Cmd is not used so far
lf_read(false, 20000);
return CmdVisa2kDemod(Cmd);
return demodVisa2k(true);
}
static int CmdVisa2kClone(const char *Cmd) {

View file

@ -14,7 +14,7 @@
int CmdLFVisa2k(const char *Cmd);
int getvisa2kBits(uint64_t fullcode, uint8_t *bits);
int demodVisa2k(void);
int demodVisa2k(bool verbose);
int detectVisa2k(uint8_t *dest, size_t *size);
#endif

View file

@ -196,7 +196,7 @@ int CmdsParse(const command_t Commands[], const char *Cmd) {
dumpCommandsRecursive(Commands, 1);
return PM3_SUCCESS;
}
if (strcmp(Cmd, "coffee") == 0) {
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, " ((\n ))\n" _YELLOW_(" .______.\n | |]\n \\ /\n `----´\n\n"));

View file

@ -203,7 +203,7 @@ static uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *tr
data_len = hdr->data_len;
if (tracepos + TRACELOG_HDR_LEN + data_len + TRACELOG_PARITY_LEN(hdr) > traceLen) {
PrintAndLogEx(DEBUG, "trace pos offset %u larger than reported tracelen %u", tracepos + TRACELOG_HDR_LEN + data_len + TRACELOG_PARITY_LEN(hdr), traceLen);
PrintAndLogEx(DEBUG, "trace pos offset %"PRIu32 " larger than reported tracelen %u", tracepos + TRACELOG_HDR_LEN + data_len + TRACELOG_PARITY_LEN(hdr), traceLen);
return traceLen;
}

View file

@ -638,7 +638,7 @@ void Plot::closeEvent(QCloseEvent *event) {
}
void Plot::Zoom(float factor, int refX) {
if (factor >=1) { // Zoom in
if (factor >= 1) { // Zoom in
if (GraphPixelsPerPoint <= 25 * factor) {
GraphPixelsPerPoint *= factor;
GraphStart += (refX - GraphStart) - ((refX - GraphStart) / factor);
@ -664,7 +664,7 @@ void Plot::Move(int offset) {
}
} else { // Move left
if (GraphPixelsPerPoint < 20) {
if (GraphStart >= (uint)-offset) {
if (GraphStart >= (uint) - offset) {
GraphStart += offset;
} else {
GraphStart = 0;
@ -697,15 +697,15 @@ void Plot::wheelEvent(QWheelEvent *event) {
x += GraphStart;
// event->angleDelta doesn't exist in QT4, both exist in 5.12.8 and 5.14.2 and event->delta doesn't exist in 5.15.0
#if QT_VERSION >= 0x050d00
Zoom(1.0-(float)event->angleDelta().y()/(120/zoom_offset), x);
Zoom(1.0 - (float)event->angleDelta().y() / (120 / zoom_offset), x);
#else
Zoom(1.0-(float)event->delta()/(120/zoom_offset), x);
Zoom(1.0 - (float)event->delta() / (120 / zoom_offset), x);
#endif
} else {
#if QT_VERSION >= 0x050d00
Move(PageWidth*(-(float)event->angleDelta().y()/(120/move_offset)));
Move(PageWidth * (-(float)event->angleDelta().y() / (120 / move_offset)));
#else
Move(PageWidth*(-(float)event->delta()/(120/move_offset)));
Move(PageWidth * (-(float)event->delta() / (120 / move_offset)));
#endif
}
this->update();

View file

@ -129,6 +129,7 @@ static int l_SendCommandOLD(lua_State *L) {
}
}
clearCommandBuffer();
SendCommandOLD(cmd, arg0, arg1, arg2, data, len);
lua_pushboolean(L, true);
return 1;
@ -176,6 +177,7 @@ static int l_SendCommandMIX(lua_State *L) {
}
}
clearCommandBuffer();
SendCommandMIX(cmd, arg0, arg1, arg2, data, len);
lua_pushboolean(L, true);
return 1;
@ -215,6 +217,7 @@ static int l_SendCommandNG(lua_State *L) {
}
}
clearCommandBuffer();
SendCommandNG(cmd, data, len);
lua_pushboolean(L, true);
return 1;
@ -387,8 +390,9 @@ static int l_WaitForResponseTimeout(lua_State *L) {
ms_timeout = luaL_checkunsigned(L, 2);
PacketResponseNG resp;
if (WaitForResponseTimeout(cmd, &resp, ms_timeout) == false)
if (WaitForResponseTimeout(cmd, &resp, ms_timeout) == false) {
return returnToLuaWithError(L, "No response from the device");
}
char foo[sizeof(PacketResponseNG)];
n = 0;
@ -426,7 +430,6 @@ static int l_WaitForResponseTimeout(lua_State *L) {
//Push it as a string
lua_pushlstring(L, (const char *)&foo, sizeof(foo));
return 1;
}

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