diff options
Diffstat (limited to 'applications/nfc/scenes/nfc_scene_mf_classic_dict_attack.c')
-rw-r--r-- | applications/nfc/scenes/nfc_scene_mf_classic_dict_attack.c | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/applications/nfc/scenes/nfc_scene_mf_classic_dict_attack.c b/applications/nfc/scenes/nfc_scene_mf_classic_dict_attack.c new file mode 100644 index 00000000..0736f0f1 --- /dev/null +++ b/applications/nfc/scenes/nfc_scene_mf_classic_dict_attack.c @@ -0,0 +1,137 @@ +#include "../nfc_i.h" + +typedef enum { + DictAttackStateIdle, + DictAttackStateUserDictInProgress, + DictAttackStateFlipperDictInProgress, +} DictAttackState; + +bool nfc_dict_attack_worker_callback(NfcWorkerEvent event, void* context) { + furi_assert(context); + Nfc* nfc = context; + view_dispatcher_send_custom_event(nfc->view_dispatcher, event); + return true; +} + +void nfc_dict_attack_dict_attack_result_callback(void* context) { + furi_assert(context); + Nfc* nfc = context; + view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventDictAttackSkip); +} + +static void nfc_scene_mf_classic_dict_attack_update_view(Nfc* nfc) { + MfClassicData* data = &nfc->dev->dev_data.mf_classic_data; + uint8_t sectors_read = 0; + uint8_t keys_found = 0; + + // Calculate found keys and read sectors + mf_classic_get_read_sectors_and_keys(data, §ors_read, &keys_found); + dict_attack_set_keys_found(nfc->dict_attack, keys_found); + dict_attack_set_sector_read(nfc->dict_attack, sectors_read); +} + +static void nfc_scene_mf_classic_dict_attack_prepare_view(Nfc* nfc, DictAttackState state) { + MfClassicData* data = &nfc->dev->dev_data.mf_classic_data; + NfcWorkerState worker_state = NfcWorkerStateReady; + + // Identify scene state + if(state == DictAttackStateIdle) { + if(mf_classic_dict_check_presence(MfClassicDictTypeUser)) { + state = DictAttackStateUserDictInProgress; + } else { + state = DictAttackStateFlipperDictInProgress; + } + } else if(state == DictAttackStateUserDictInProgress) { + state = DictAttackStateFlipperDictInProgress; + } + + // Setup view + if(state == DictAttackStateUserDictInProgress) { + worker_state = NfcWorkerStateMfClassicUserDictAttack; + dict_attack_set_header(nfc->dict_attack, "Mf Classic User Dict."); + } else if(state == DictAttackStateFlipperDictInProgress) { + worker_state = NfcWorkerStateMfClassicFlipperDictAttack; + dict_attack_set_header(nfc->dict_attack, "Mf Classic Flipper Dict."); + } + scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfClassicDictAttack, state); + dict_attack_set_callback(nfc->dict_attack, nfc_dict_attack_dict_attack_result_callback, nfc); + dict_attack_set_current_sector(nfc->dict_attack, 0); + dict_attack_set_card_detected(nfc->dict_attack, data->type); + nfc_scene_mf_classic_dict_attack_update_view(nfc); + nfc_worker_start( + nfc->worker, worker_state, &nfc->dev->dev_data, nfc_dict_attack_worker_callback, nfc); +} + +void nfc_scene_mf_classic_dict_attack_on_enter(void* context) { + Nfc* nfc = context; + nfc_scene_mf_classic_dict_attack_prepare_view(nfc, DictAttackStateIdle); + view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDictAttack); + nfc_blink_start(nfc); +} + +bool nfc_scene_mf_classic_dict_attack_on_event(void* context, SceneManagerEvent event) { + Nfc* nfc = context; + MfClassicData* data = &nfc->dev->dev_data.mf_classic_data; + bool consumed = false; + + uint32_t state = + scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfClassicDictAttack); + if(event.type == SceneManagerEventTypeCustom) { + if(event.event == NfcWorkerEventSuccess) { + if(state == DictAttackStateUserDictInProgress) { + nfc_worker_stop(nfc->worker); + nfc_scene_mf_classic_dict_attack_prepare_view(nfc, state); + consumed = true; + } else { + notification_message(nfc->notifications, &sequence_success); + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicReadSuccess); + consumed = true; + } + } else if(event.event == NfcWorkerEventAborted) { + if(state == DictAttackStateUserDictInProgress) { + nfc_scene_mf_classic_dict_attack_prepare_view(nfc, state); + consumed = true; + } else { + notification_message(nfc->notifications, &sequence_success); + scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicReadSuccess); + consumed = true; + } + } else if(event.event == NfcWorkerEventCardDetected) { + dict_attack_set_card_detected(nfc->dict_attack, data->type); + consumed = true; + } else if(event.event == NfcWorkerEventNoCardDetected) { + dict_attack_set_card_removed(nfc->dict_attack); + consumed = true; + } else if(event.event == NfcWorkerEventFoundKeyA) { + dict_attack_inc_keys_found(nfc->dict_attack); + consumed = true; + } else if(event.event == NfcWorkerEventFoundKeyB) { + dict_attack_inc_keys_found(nfc->dict_attack); + consumed = true; + } else if(event.event == NfcWorkerEventNewSector) { + nfc_scene_mf_classic_dict_attack_update_view(nfc); + dict_attack_inc_current_sector(nfc->dict_attack); + consumed = true; + } else if(event.event == NfcCustomEventDictAttackSkip) { + if(state == DictAttackStateUserDictInProgress) { + nfc_worker_stop(nfc->worker); + consumed = true; + } else if(state == DictAttackStateFlipperDictInProgress) { + nfc_worker_stop(nfc->worker); + consumed = true; + } + } + } else if(event.type == SceneManagerEventTypeBack) { + scene_manager_next_scene(nfc->scene_manager, NfcSceneExitConfirm); + consumed = true; + } + return consumed; +} + +void nfc_scene_mf_classic_dict_attack_on_exit(void* context) { + Nfc* nfc = context; + // Stop worker + nfc_worker_stop(nfc->worker); + dict_attack_reset(nfc->dict_attack); + nfc_blink_stop(nfc); +} |