nfc_scene_mf_classic_dict_attack.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #include "../nfc_i.h"
  2. #define TAG "NfcMfClassicDictAttack"
  3. typedef enum {
  4. DictAttackStateIdle,
  5. DictAttackStateUserDictInProgress,
  6. DictAttackStateFlipperDictInProgress,
  7. } DictAttackState;
  8. bool nfc_dict_attack_worker_callback(NfcWorkerEvent event, void* context) {
  9. furi_assert(context);
  10. Nfc* nfc = context;
  11. view_dispatcher_send_custom_event(nfc->view_dispatcher, event);
  12. return true;
  13. }
  14. void nfc_dict_attack_dict_attack_result_callback(void* context) {
  15. furi_assert(context);
  16. Nfc* nfc = context;
  17. view_dispatcher_send_custom_event(nfc->view_dispatcher, NfcCustomEventDictAttackSkip);
  18. }
  19. static void nfc_scene_mf_classic_dict_attack_update_view(Nfc* nfc) {
  20. MfClassicData* data = &nfc->dev->dev_data.mf_classic_data;
  21. uint8_t sectors_read = 0;
  22. uint8_t keys_found = 0;
  23. // Calculate found keys and read sectors
  24. mf_classic_get_read_sectors_and_keys(data, &sectors_read, &keys_found);
  25. dict_attack_set_keys_found(nfc->dict_attack, keys_found);
  26. dict_attack_set_sector_read(nfc->dict_attack, sectors_read);
  27. }
  28. static void nfc_scene_mf_classic_dict_attack_prepare_view(Nfc* nfc, DictAttackState state) {
  29. MfClassicData* data = &nfc->dev->dev_data.mf_classic_data;
  30. NfcMfClassicDictAttackData* dict_attack_data = &nfc->dev->dev_data.mf_classic_dict_attack_data;
  31. NfcWorkerState worker_state = NfcWorkerStateReady;
  32. MfClassicDict* dict = NULL;
  33. // Identify scene state
  34. if(state == DictAttackStateIdle) {
  35. if(mf_classic_dict_check_presence(MfClassicDictTypeUser)) {
  36. state = DictAttackStateUserDictInProgress;
  37. } else {
  38. state = DictAttackStateFlipperDictInProgress;
  39. }
  40. } else if(state == DictAttackStateUserDictInProgress) {
  41. state = DictAttackStateFlipperDictInProgress;
  42. }
  43. // Setup view
  44. if(state == DictAttackStateUserDictInProgress) {
  45. worker_state = NfcWorkerStateMfClassicDictAttack;
  46. dict_attack_set_header(nfc->dict_attack, "Mf Classic User Dict.");
  47. dict = mf_classic_dict_alloc(MfClassicDictTypeUser);
  48. // If failed to load user dictionary - try flipper dictionary
  49. if(!dict) {
  50. FURI_LOG_E(TAG, "User dictionary not found");
  51. state = DictAttackStateFlipperDictInProgress;
  52. }
  53. }
  54. if(state == DictAttackStateFlipperDictInProgress) {
  55. worker_state = NfcWorkerStateMfClassicDictAttack;
  56. dict_attack_set_header(nfc->dict_attack, "Mf Classic Flipper Dict.");
  57. dict = mf_classic_dict_alloc(MfClassicDictTypeFlipper);
  58. if(!dict) {
  59. FURI_LOG_E(TAG, "Flipper dictionary not found");
  60. // Pass through to let worker handle the failure
  61. }
  62. }
  63. // Free previous dictionary
  64. if(dict_attack_data->dict) {
  65. mf_classic_dict_free(dict_attack_data->dict);
  66. }
  67. dict_attack_data->dict = dict;
  68. scene_manager_set_scene_state(nfc->scene_manager, NfcSceneMfClassicDictAttack, state);
  69. dict_attack_set_callback(nfc->dict_attack, nfc_dict_attack_dict_attack_result_callback, nfc);
  70. dict_attack_set_current_sector(nfc->dict_attack, 0);
  71. dict_attack_set_card_detected(nfc->dict_attack, data->type);
  72. dict_attack_set_total_dict_keys(
  73. nfc->dict_attack, dict ? mf_classic_dict_get_total_keys(dict) : 0);
  74. nfc_scene_mf_classic_dict_attack_update_view(nfc);
  75. nfc_worker_start(
  76. nfc->worker, worker_state, &nfc->dev->dev_data, nfc_dict_attack_worker_callback, nfc);
  77. }
  78. void nfc_scene_mf_classic_dict_attack_on_enter(void* context) {
  79. Nfc* nfc = context;
  80. nfc_scene_mf_classic_dict_attack_prepare_view(nfc, DictAttackStateIdle);
  81. view_dispatcher_switch_to_view(nfc->view_dispatcher, NfcViewDictAttack);
  82. nfc_blink_start(nfc);
  83. }
  84. bool nfc_scene_mf_classic_dict_attack_on_event(void* context, SceneManagerEvent event) {
  85. Nfc* nfc = context;
  86. MfClassicData* data = &nfc->dev->dev_data.mf_classic_data;
  87. bool consumed = false;
  88. uint32_t state =
  89. scene_manager_get_scene_state(nfc->scene_manager, NfcSceneMfClassicDictAttack);
  90. if(event.type == SceneManagerEventTypeCustom) {
  91. if(event.event == NfcWorkerEventSuccess) {
  92. if(state == DictAttackStateUserDictInProgress) {
  93. nfc_worker_stop(nfc->worker);
  94. nfc_scene_mf_classic_dict_attack_prepare_view(nfc, state);
  95. consumed = true;
  96. } else {
  97. notification_message(nfc->notifications, &sequence_success);
  98. scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicReadSuccess);
  99. consumed = true;
  100. }
  101. } else if(event.event == NfcWorkerEventAborted) {
  102. if(state == DictAttackStateUserDictInProgress) {
  103. nfc_scene_mf_classic_dict_attack_prepare_view(nfc, state);
  104. consumed = true;
  105. } else {
  106. notification_message(nfc->notifications, &sequence_success);
  107. scene_manager_next_scene(nfc->scene_manager, NfcSceneMfClassicReadSuccess);
  108. consumed = true;
  109. }
  110. } else if(event.event == NfcWorkerEventCardDetected) {
  111. dict_attack_set_card_detected(nfc->dict_attack, data->type);
  112. consumed = true;
  113. } else if(event.event == NfcWorkerEventNoCardDetected) {
  114. dict_attack_set_card_removed(nfc->dict_attack);
  115. consumed = true;
  116. } else if(event.event == NfcWorkerEventFoundKeyA) {
  117. dict_attack_inc_keys_found(nfc->dict_attack);
  118. consumed = true;
  119. } else if(event.event == NfcWorkerEventFoundKeyB) {
  120. dict_attack_inc_keys_found(nfc->dict_attack);
  121. consumed = true;
  122. } else if(event.event == NfcWorkerEventNewSector) {
  123. nfc_scene_mf_classic_dict_attack_update_view(nfc);
  124. dict_attack_inc_current_sector(nfc->dict_attack);
  125. consumed = true;
  126. } else if(event.event == NfcWorkerEventNewDictKeyBatch) {
  127. nfc_scene_mf_classic_dict_attack_update_view(nfc);
  128. dict_attack_inc_current_dict_key(nfc->dict_attack, NFC_DICT_KEY_BATCH_SIZE);
  129. consumed = true;
  130. } else if(event.event == NfcCustomEventDictAttackSkip) {
  131. if(state == DictAttackStateUserDictInProgress) {
  132. nfc_worker_stop(nfc->worker);
  133. consumed = true;
  134. } else if(state == DictAttackStateFlipperDictInProgress) {
  135. nfc_worker_stop(nfc->worker);
  136. consumed = true;
  137. }
  138. }
  139. } else if(event.type == SceneManagerEventTypeBack) {
  140. scene_manager_next_scene(nfc->scene_manager, NfcSceneExitConfirm);
  141. consumed = true;
  142. }
  143. return consumed;
  144. }
  145. void nfc_scene_mf_classic_dict_attack_on_exit(void* context) {
  146. Nfc* nfc = context;
  147. NfcMfClassicDictAttackData* dict_attack_data = &nfc->dev->dev_data.mf_classic_dict_attack_data;
  148. // Stop worker
  149. nfc_worker_stop(nfc->worker);
  150. if(dict_attack_data->dict) {
  151. mf_classic_dict_free(dict_attack_data->dict);
  152. dict_attack_data->dict = NULL;
  153. }
  154. dict_attack_reset(nfc->dict_attack);
  155. nfc_blink_stop(nfc);
  156. }