added "Listen NfcV Reader" to sniff traffic from reader to card

This commit is contained in:
g3gg0.de
2023-01-21 01:04:02 +01:00
committed by Tiernan Messmer
parent f03d31b647
commit 4f4eca1dd7
8 changed files with 365 additions and 1 deletions
+4
View File
@@ -885,6 +885,8 @@ static bool nfc_device_save_nfcv_data(FlipperFormat* file, NfcDevice* dev) {
case NfcVTypeSlix2:
saved = nfc_device_save_slix2_data(file, dev);
break;
default:
break;
}
} while(false);
@@ -936,6 +938,8 @@ bool nfc_device_load_nfcv_data(FlipperFormat* file, NfcDevice* dev) {
case NfcVTypeSlix2:
parsed = nfc_device_load_slix2_data(file, dev);
break;
default:
break;
}
} while(false);
+30
View File
@@ -113,6 +113,8 @@ int32_t nfc_worker_task(void* context) {
nfc_worker_analyze_reader(nfc_worker);
} else if(nfc_worker->state == NfcWorkerStateNfcVEmulate) {
nfc_worker_nfcv_emulate(nfc_worker);
} else if(nfc_worker->state == NfcWorkerStateNfcVSniff) {
nfc_worker_nfcv_sniff(nfc_worker);
} else if(nfc_worker->state == NfcWorkerStateNfcVUnlock) {
nfc_worker_nfcv_unlock(nfc_worker);
} else if(nfc_worker->state == NfcWorkerStateNfcVUnlockAndSave) {
@@ -182,6 +184,34 @@ void nfc_worker_nfcv_emulate(NfcWorker* nfc_worker) {
}
}
void nfc_worker_nfcv_sniff(NfcWorker* nfc_worker) {
FuriHalNfcTxRxContext tx_rx = {};
FuriHalNfcDevData* nfc_data = &nfc_worker->dev_data->nfc_data;
NfcVData* nfcv_data = &nfc_worker->dev_data->nfcv_data;
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
reader_analyzer_prepare_tx_rx(nfc_worker->reader_analyzer, &tx_rx, true);
reader_analyzer_start(nfc_worker->reader_analyzer, ReaderAnalyzerModeDebugLog);
}
nfcv_data->sub_type = NfcVTypeSniff;
nfcv_emu_init(nfc_data, nfcv_data);
while(nfc_worker->state == NfcWorkerStateNfcVSniff) {
if(nfcv_emu_loop(&tx_rx, nfc_data, nfcv_data, 100)) {
if(nfc_worker->callback) {
nfc_worker->callback(NfcWorkerEventNfcVCommandExecuted, nfc_worker->context);
}
}
furi_delay_ms(10);
}
nfcv_emu_deinit(nfcv_data);
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) {
reader_analyzer_stop(nfc_worker->reader_analyzer);
}
}
void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker) {
furi_assert(nfc_worker);
furi_assert(nfc_worker->callback);
+2
View File
@@ -21,6 +21,7 @@ typedef enum {
NfcWorkerStateNfcVEmulate,
NfcWorkerStateNfcVUnlock,
NfcWorkerStateNfcVUnlockAndSave,
NfcWorkerStateNfcVSniff,
// Debug
NfcWorkerStateEmulateApdu,
NfcWorkerStateField,
@@ -96,3 +97,4 @@ void nfc_worker_start(
void nfc_worker_stop(NfcWorker* nfc_worker);
void nfc_worker_nfcv_unlock(NfcWorker* nfc_worker);
void nfc_worker_nfcv_emulate(NfcWorker* nfc_worker);
void nfc_worker_nfcv_sniff(NfcWorker* nfc_worker);
+162 -1
View File
@@ -732,6 +732,160 @@ void nfcv_emu_handle_packet(
}
}
void nfcv_emu_sniff_packet(
FuriHalNfcTxRxContext* tx_rx,
FuriHalNfcDevData* nfc_data,
void* nfcv_data_in) {
furi_assert(tx_rx);
furi_assert(nfc_data);
furi_assert(nfcv_data_in);
NfcVData* nfcv_data = (NfcVData*)nfcv_data_in;
NfcVEmuProtocolCtx* ctx = nfcv_data->emu_protocol_ctx;
if(nfcv_data->frame_length < 2) {
return;
}
/* parse the frame data for the upcoming part 3 handling */
ctx->flags = nfcv_data->frame[0];
ctx->command = nfcv_data->frame[1];
ctx->selected = (ctx->flags & RFAL_NFCV_REQ_FLAG_SELECT);
ctx->addressed = !(ctx->flags & RFAL_NFCV_REQ_FLAG_INVENTORY) &&
(ctx->flags & RFAL_NFCV_REQ_FLAG_ADDRESS);
ctx->advanced = (ctx->command >= 0xA0);
ctx->address_offset = 2 + (ctx->advanced ? 1 : 0);
ctx->payload_offset = ctx->address_offset + (ctx->addressed ? 8 : 0);
char flags_string[5];
snprintf(
flags_string,
5,
"%c%c%c%d",
(ctx->flags & RFAL_NFCV_REQ_FLAG_INVENTORY) ?
'I' :
(ctx->addressed ? 'A' : (ctx->selected ? 'S' : '*')),
ctx->advanced ? 'X' : ' ',
(ctx->flags & RFAL_NFCV_REQ_FLAG_DATA_RATE) ? 'h' : 'l',
(ctx->flags & RFAL_NFCV_REQ_FLAG_SUB_CARRIER) ? 2 : 1);
switch(ctx->command) {
case ISO15693_INVENTORY: {
snprintf(nfcv_data->last_command, sizeof(nfcv_data->last_command), "INVENTORY");
break;
}
case ISO15693_STAYQUIET: {
snprintf(
nfcv_data->last_command, sizeof(nfcv_data->last_command), "%s STAYQUIET", flags_string);
nfcv_data->quiet = true;
break;
}
case ISO15693_LOCKBLOCK: {
uint8_t block = nfcv_data->frame[ctx->payload_offset];
snprintf(
nfcv_data->last_command,
sizeof(nfcv_data->last_command),
"%s LOCK %d",
flags_string,
block);
break;
}
case ISO15693_SELECT: {
snprintf(
nfcv_data->last_command, sizeof(nfcv_data->last_command), "%s SELECT", flags_string);
break;
}
case ISO15693_RESET_TO_READY: {
snprintf(
nfcv_data->last_command, sizeof(nfcv_data->last_command), "%s RESET", flags_string);
break;
}
case ISO15693_READ_MULTI_BLOCK:
case ISO15693_READBLOCK: {
uint8_t block = nfcv_data->frame[ctx->payload_offset];
uint8_t blocks = 1;
if(ctx->command == ISO15693_READ_MULTI_BLOCK) {
blocks = nfcv_data->frame[ctx->payload_offset + 1] + 1;
}
snprintf(
nfcv_data->last_command,
sizeof(nfcv_data->last_command),
"%s READ %d cnt: %d",
flags_string,
block,
blocks);
break;
}
case ISO15693_WRITE_MULTI_BLOCK:
case ISO15693_WRITEBLOCK: {
uint8_t block = nfcv_data->frame[ctx->payload_offset];
uint8_t blocks = 1;
uint8_t data_pos = 1;
if(ctx->command == ISO15693_WRITE_MULTI_BLOCK) {
blocks = nfcv_data->frame[ctx->payload_offset + 1] + 1;
data_pos++;
}
uint8_t* data = &nfcv_data->frame[ctx->payload_offset + data_pos];
if(ctx->command == ISO15693_WRITE_MULTI_BLOCK) {
snprintf(
nfcv_data->last_command,
sizeof(nfcv_data->last_command),
"%s WRITE %d, cnd %d",
flags_string,
block,
blocks);
} else {
snprintf(
nfcv_data->last_command,
sizeof(nfcv_data->last_command),
"%s WRITE %d %02X %02X %02X %02X",
flags_string,
block,
data[0],
data[1],
data[2],
data[3]);
}
break;
}
case ISO15693_GET_SYSTEM_INFO: {
snprintf(
nfcv_data->last_command,
sizeof(nfcv_data->last_command),
"%s SYSTEMINFO",
flags_string);
break;
}
default:
snprintf(
nfcv_data->last_command,
sizeof(nfcv_data->last_command),
"%s unsupported: %02X",
flags_string,
ctx->command);
break;
}
if(strlen(nfcv_data->last_command) > 0) {
FURI_LOG_D(TAG, "Received command %s", nfcv_data->last_command);
}
}
void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) {
furi_assert(nfc_data);
furi_assert(nfcv_data);
@@ -765,7 +919,11 @@ void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) {
/* if not set already, initialize the default protocol handler */
if(!nfcv_data->emu_protocol_ctx) {
nfcv_data->emu_protocol_ctx = malloc(sizeof(NfcVEmuProtocolCtx));
nfcv_data->emu_protocol_handler = &nfcv_emu_handle_packet;
if(nfcv_data->sub_type == NfcVTypeSniff) {
nfcv_data->emu_protocol_handler = &nfcv_emu_sniff_packet;
} else {
nfcv_data->emu_protocol_handler = &nfcv_emu_handle_packet;
}
}
FURI_LOG_D(TAG, "Starting NfcV emulation");
@@ -801,6 +959,9 @@ void nfcv_emu_init(FuriHalNfcDevData* nfc_data, NfcVData* nfcv_data) {
case NfcVTypePlain:
FURI_LOG_D(TAG, " Card type: Plain");
break;
case NfcVTypeSniff:
FURI_LOG_D(TAG, " Card type: Sniffing");
break;
}
/* allocate a 512 edge buffer, more than enough */
+1
View File
@@ -96,6 +96,7 @@ typedef enum {
NfcVTypeSlixS = 2,
NfcVTypeSlixL = 3,
NfcVTypeSlix2 = 4,
NfcVTypeSniff = 255,
} NfcVSubtype;
typedef enum {