nfc_magic_scene_mf_classic_dict_attack.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. #include "../nfc_magic_app_i.h"
  2. #include <dolphin/dolphin.h>
  3. #include <lib/nfc/protocols/mf_classic/mf_classic_poller.h>
  4. #include "views/dict_attack.h"
  5. #define TAG "NfcMagicMfClassicDictAttack"
  6. typedef enum {
  7. DictAttackStateUserDictInProgress,
  8. DictAttackStateSystemDictInProgress,
  9. } DictAttackState;
  10. NfcCommand nfc_dict_attack_worker_callback(NfcGenericEvent event, void* context) {
  11. furi_assert(context);
  12. furi_assert(event.event_data);
  13. furi_assert(event.instance);
  14. furi_assert(event.protocol == NfcProtocolMfClassic);
  15. NfcCommand command = NfcCommandContinue;
  16. MfClassicPollerEvent* mfc_event = event.event_data;
  17. NfcMagicApp* instance = context;
  18. if(mfc_event->type == MfClassicPollerEventTypeCardDetected) {
  19. instance->nfc_dict_context.is_card_present = true;
  20. view_dispatcher_send_custom_event(
  21. instance->view_dispatcher, NfcMagicAppCustomEventCardDetected);
  22. } else if(mfc_event->type == MfClassicPollerEventTypeCardLost) {
  23. instance->nfc_dict_context.is_card_present = false;
  24. view_dispatcher_send_custom_event(
  25. instance->view_dispatcher, NfcMagicAppCustomEventCardLost);
  26. } else if(mfc_event->type == MfClassicPollerEventTypeRequestMode) {
  27. const MfClassicData* mfc_data = nfc_poller_get_data(instance->poller);
  28. if(nfc_device_get_protocol(instance->target_dev) == NfcProtocolInvalid) {
  29. FURI_LOG_D(TAG, "Setting MFC data to target device");
  30. nfc_device_set_data(instance->target_dev, NfcProtocolMfClassic, mfc_data);
  31. } else {
  32. FURI_LOG_D(TAG, "MFC data already set to target device");
  33. mfc_data = nfc_device_get_data(instance->target_dev, NfcProtocolMfClassic);
  34. }
  35. FURI_LOG_D(TAG, "MFC type: %d", mfc_data->type);
  36. mfc_event->data->poller_mode.mode = MfClassicPollerModeDictAttack;
  37. mfc_event->data->poller_mode.data = mfc_data;
  38. instance->nfc_dict_context.sectors_total =
  39. mf_classic_get_total_sectors_num(mfc_data->type);
  40. FURI_LOG_D(TAG, "Total sectors: %d", mf_classic_get_total_sectors_num(mfc_data->type));
  41. mf_classic_get_read_sectors_and_keys(
  42. mfc_data,
  43. &instance->nfc_dict_context.sectors_read,
  44. &instance->nfc_dict_context.keys_found);
  45. view_dispatcher_send_custom_event(
  46. instance->view_dispatcher, NfcMagicAppCustomEventDictAttackDataUpdate);
  47. } else if(mfc_event->type == MfClassicPollerEventTypeRequestKey) {
  48. MfClassicKey key = {};
  49. if(keys_dict_get_next_key(
  50. instance->nfc_dict_context.dict, key.data, sizeof(MfClassicKey))) {
  51. mfc_event->data->key_request_data.key = key;
  52. mfc_event->data->key_request_data.key_provided = true;
  53. instance->nfc_dict_context.dict_keys_current++;
  54. if(instance->nfc_dict_context.dict_keys_current % 10 == 0) {
  55. view_dispatcher_send_custom_event(
  56. instance->view_dispatcher, NfcMagicAppCustomEventDictAttackDataUpdate);
  57. }
  58. } else {
  59. mfc_event->data->key_request_data.key_provided = false;
  60. }
  61. } else if(mfc_event->type == MfClassicPollerEventTypeDataUpdate) {
  62. MfClassicPollerEventDataUpdate* data_update = &mfc_event->data->data_update;
  63. instance->nfc_dict_context.sectors_read = data_update->sectors_read;
  64. instance->nfc_dict_context.keys_found = data_update->keys_found;
  65. instance->nfc_dict_context.current_sector = data_update->current_sector;
  66. view_dispatcher_send_custom_event(
  67. instance->view_dispatcher, NfcMagicAppCustomEventDictAttackDataUpdate);
  68. } else if(mfc_event->type == MfClassicPollerEventTypeNextSector) {
  69. keys_dict_rewind(instance->nfc_dict_context.dict);
  70. instance->nfc_dict_context.dict_keys_current = 0;
  71. instance->nfc_dict_context.current_sector =
  72. mfc_event->data->next_sector_data.current_sector;
  73. view_dispatcher_send_custom_event(
  74. instance->view_dispatcher, NfcMagicAppCustomEventDictAttackDataUpdate);
  75. } else if(mfc_event->type == MfClassicPollerEventTypeFoundKeyA) {
  76. view_dispatcher_send_custom_event(
  77. instance->view_dispatcher, NfcMagicAppCustomEventDictAttackDataUpdate);
  78. } else if(mfc_event->type == MfClassicPollerEventTypeFoundKeyB) {
  79. view_dispatcher_send_custom_event(
  80. instance->view_dispatcher, NfcMagicAppCustomEventDictAttackDataUpdate);
  81. } else if(mfc_event->type == MfClassicPollerEventTypeKeyAttackStart) {
  82. instance->nfc_dict_context.key_attack_current_sector =
  83. mfc_event->data->key_attack_data.current_sector;
  84. instance->nfc_dict_context.is_key_attack = true;
  85. view_dispatcher_send_custom_event(
  86. instance->view_dispatcher, NfcMagicAppCustomEventDictAttackDataUpdate);
  87. } else if(mfc_event->type == MfClassicPollerEventTypeKeyAttackStop) {
  88. keys_dict_rewind(instance->nfc_dict_context.dict);
  89. instance->nfc_dict_context.is_key_attack = false;
  90. instance->nfc_dict_context.dict_keys_current = 0;
  91. view_dispatcher_send_custom_event(
  92. instance->view_dispatcher, NfcMagicAppCustomEventDictAttackDataUpdate);
  93. } else if(mfc_event->type == MfClassicPollerEventTypeSuccess) {
  94. const MfClassicData* mfc_data = nfc_poller_get_data(instance->poller);
  95. nfc_device_set_data(instance->target_dev, NfcProtocolMfClassic, mfc_data);
  96. view_dispatcher_send_custom_event(
  97. instance->view_dispatcher, NfcMagicAppCustomEventDictAttackComplete);
  98. command = NfcCommandStop;
  99. }
  100. return command;
  101. }
  102. void nfc_dict_attack_dict_attack_result_callback(DictAttackEvent event, void* context) {
  103. furi_assert(context);
  104. NfcMagicApp* instance = context;
  105. if(event == DictAttackEventSkipPressed) {
  106. view_dispatcher_send_custom_event(
  107. instance->view_dispatcher, NfcMagicAppCustomEventDictAttackSkip);
  108. }
  109. }
  110. static void nfc_magic_scene_mf_classic_dict_attack_update_view(NfcMagicApp* instance) {
  111. NfcMagicAppMfClassicDictAttackContext* mfc_dict = &instance->nfc_dict_context;
  112. if(mfc_dict->is_key_attack) {
  113. dict_attack_set_key_attack(instance->dict_attack, mfc_dict->key_attack_current_sector);
  114. } else {
  115. dict_attack_reset_key_attack(instance->dict_attack);
  116. dict_attack_set_sectors_total(instance->dict_attack, mfc_dict->sectors_total);
  117. dict_attack_set_sectors_read(instance->dict_attack, mfc_dict->sectors_read);
  118. dict_attack_set_keys_found(instance->dict_attack, mfc_dict->keys_found);
  119. dict_attack_set_current_dict_key(instance->dict_attack, mfc_dict->dict_keys_current);
  120. dict_attack_set_current_sector(instance->dict_attack, mfc_dict->current_sector);
  121. }
  122. }
  123. static void nfc_magic_scene_mf_classic_dict_attack_prepare_view(NfcMagicApp* instance) {
  124. uint32_t state =
  125. scene_manager_get_scene_state(instance->scene_manager, NfcMagicSceneMfClassicDictAttack);
  126. if(state == DictAttackStateUserDictInProgress) {
  127. do {
  128. if(!keys_dict_check_presence(NFC_APP_MF_CLASSIC_DICT_USER_PATH)) {
  129. state = DictAttackStateSystemDictInProgress;
  130. break;
  131. }
  132. instance->nfc_dict_context.dict = keys_dict_alloc(
  133. NFC_APP_MF_CLASSIC_DICT_USER_PATH, KeysDictModeOpenAlways, sizeof(MfClassicKey));
  134. if(keys_dict_get_total_keys(instance->nfc_dict_context.dict) == 0) {
  135. keys_dict_free(instance->nfc_dict_context.dict);
  136. state = DictAttackStateSystemDictInProgress;
  137. break;
  138. }
  139. dict_attack_set_header(instance->dict_attack, "MF Classic User Dictionary");
  140. } while(false);
  141. }
  142. if(state == DictAttackStateSystemDictInProgress) {
  143. instance->nfc_dict_context.dict = keys_dict_alloc(
  144. NFC_APP_MF_CLASSIC_DICT_SYSTEM_PATH, KeysDictModeOpenExisting, sizeof(MfClassicKey));
  145. dict_attack_set_header(instance->dict_attack, "MF Classic System Dictionary");
  146. }
  147. instance->nfc_dict_context.dict_keys_total =
  148. keys_dict_get_total_keys(instance->nfc_dict_context.dict);
  149. dict_attack_set_total_dict_keys(
  150. instance->dict_attack, instance->nfc_dict_context.dict_keys_total);
  151. instance->nfc_dict_context.dict_keys_current = 0;
  152. dict_attack_set_callback(
  153. instance->dict_attack, nfc_dict_attack_dict_attack_result_callback, instance);
  154. nfc_magic_scene_mf_classic_dict_attack_update_view(instance);
  155. scene_manager_set_scene_state(
  156. instance->scene_manager, NfcMagicSceneMfClassicDictAttack, state);
  157. }
  158. void nfc_magic_scene_mf_classic_dict_attack_on_enter(void* context) {
  159. NfcMagicApp* instance = context;
  160. scene_manager_set_scene_state(
  161. instance->scene_manager,
  162. NfcMagicSceneMfClassicDictAttack,
  163. DictAttackStateUserDictInProgress);
  164. nfc_magic_scene_mf_classic_dict_attack_prepare_view(instance);
  165. dict_attack_set_card_state(instance->dict_attack, true);
  166. view_dispatcher_switch_to_view(instance->view_dispatcher, NfcMagicAppViewDictAttack);
  167. nfc_magic_app_blink_start(instance);
  168. notification_message(instance->notifications, &sequence_display_backlight_enforce_on);
  169. instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolMfClassic);
  170. nfc_poller_start(instance->poller, nfc_dict_attack_worker_callback, instance);
  171. }
  172. static void nfc_magic_scene_mf_classic_dict_attack_notify_read(NfcMagicApp* instance) {
  173. const MfClassicData* mfc_data = nfc_poller_get_data(instance->poller);
  174. bool is_card_fully_read = mf_classic_is_card_read(mfc_data);
  175. if(is_card_fully_read) {
  176. notification_message(instance->notifications, &sequence_success);
  177. } else {
  178. notification_message(instance->notifications, &sequence_semi_success);
  179. }
  180. }
  181. bool nfc_magic_scene_mf_classic_dict_attack_on_event(void* context, SceneManagerEvent event) {
  182. NfcMagicApp* instance = context;
  183. bool consumed = false;
  184. uint32_t state =
  185. scene_manager_get_scene_state(instance->scene_manager, NfcMagicSceneMfClassicDictAttack);
  186. if(event.type == SceneManagerEventTypeCustom) {
  187. if(event.event == NfcMagicAppCustomEventDictAttackComplete) {
  188. if(state == DictAttackStateUserDictInProgress) {
  189. nfc_poller_stop(instance->poller);
  190. nfc_poller_free(instance->poller);
  191. keys_dict_free(instance->nfc_dict_context.dict);
  192. scene_manager_set_scene_state(
  193. instance->scene_manager,
  194. NfcMagicSceneMfClassicDictAttack,
  195. DictAttackStateSystemDictInProgress);
  196. nfc_magic_scene_mf_classic_dict_attack_prepare_view(instance);
  197. instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolMfClassic);
  198. nfc_poller_start(instance->poller, nfc_dict_attack_worker_callback, instance);
  199. consumed = true;
  200. } else {
  201. nfc_magic_scene_mf_classic_dict_attack_notify_read(instance);
  202. if(instance->protocol == NfcMagicProtocolGen2) {
  203. scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen2WriteCheck);
  204. } else {
  205. scene_manager_next_scene(
  206. instance->scene_manager, NfcMagicSceneMfClassicWriteCheck);
  207. }
  208. dolphin_deed(DolphinDeedNfcReadSuccess);
  209. consumed = true;
  210. }
  211. } else if(event.event == NfcMagicAppCustomEventCardDetected) {
  212. dict_attack_set_card_state(instance->dict_attack, true);
  213. consumed = true;
  214. } else if(event.event == NfcMagicAppCustomEventCardLost) {
  215. dict_attack_set_card_state(instance->dict_attack, false);
  216. consumed = true;
  217. } else if(event.event == NfcMagicAppCustomEventDictAttackDataUpdate) {
  218. nfc_magic_scene_mf_classic_dict_attack_update_view(instance);
  219. } else if(event.event == NfcMagicAppCustomEventDictAttackSkip) {
  220. const MfClassicData* mfc_data = nfc_poller_get_data(instance->poller);
  221. nfc_device_set_data(instance->target_dev, NfcProtocolMfClassic, mfc_data);
  222. if(state == DictAttackStateUserDictInProgress) {
  223. if(instance->nfc_dict_context.is_card_present) {
  224. nfc_poller_stop(instance->poller);
  225. nfc_poller_free(instance->poller);
  226. keys_dict_free(instance->nfc_dict_context.dict);
  227. scene_manager_set_scene_state(
  228. instance->scene_manager,
  229. NfcMagicSceneMfClassicDictAttack,
  230. DictAttackStateSystemDictInProgress);
  231. nfc_magic_scene_mf_classic_dict_attack_prepare_view(instance);
  232. instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolMfClassic);
  233. nfc_poller_start(instance->poller, nfc_dict_attack_worker_callback, instance);
  234. } else {
  235. nfc_magic_scene_mf_classic_dict_attack_notify_read(instance);
  236. if(instance->protocol == NfcMagicProtocolGen2) {
  237. scene_manager_next_scene(
  238. instance->scene_manager, NfcMagicSceneGen2WriteCheck);
  239. } else {
  240. scene_manager_next_scene(
  241. instance->scene_manager, NfcMagicSceneMfClassicWriteCheck);
  242. }
  243. dolphin_deed(DolphinDeedNfcReadSuccess);
  244. }
  245. consumed = true;
  246. } else if(state == DictAttackStateSystemDictInProgress) {
  247. nfc_magic_scene_mf_classic_dict_attack_notify_read(instance);
  248. if(instance->protocol == NfcMagicProtocolGen2) {
  249. scene_manager_next_scene(instance->scene_manager, NfcMagicSceneGen2WriteCheck);
  250. } else {
  251. scene_manager_next_scene(
  252. instance->scene_manager, NfcMagicSceneMfClassicWriteCheck);
  253. }
  254. dolphin_deed(DolphinDeedNfcReadSuccess);
  255. consumed = true;
  256. }
  257. }
  258. } else if(event.type == SceneManagerEventTypeBack) {
  259. scene_manager_previous_scene(instance->scene_manager);
  260. consumed = true;
  261. }
  262. return consumed;
  263. }
  264. void nfc_magic_scene_mf_classic_dict_attack_on_exit(void* context) {
  265. NfcMagicApp* instance = context;
  266. const MfClassicData* mfc_data = nfc_poller_get_data(instance->poller);
  267. nfc_device_set_data(instance->target_dev, NfcProtocolMfClassic, mfc_data);
  268. nfc_poller_stop(instance->poller);
  269. nfc_poller_free(instance->poller);
  270. dict_attack_reset(instance->dict_attack);
  271. scene_manager_set_scene_state(
  272. instance->scene_manager,
  273. NfcMagicSceneMfClassicDictAttack,
  274. DictAttackStateUserDictInProgress);
  275. keys_dict_free(instance->nfc_dict_context.dict);
  276. instance->nfc_dict_context.current_sector = 0;
  277. instance->nfc_dict_context.sectors_total = 0;
  278. instance->nfc_dict_context.sectors_read = 0;
  279. instance->nfc_dict_context.keys_found = 0;
  280. instance->nfc_dict_context.dict_keys_total = 0;
  281. instance->nfc_dict_context.dict_keys_current = 0;
  282. instance->nfc_dict_context.is_key_attack = false;
  283. instance->nfc_dict_context.key_attack_current_sector = 0;
  284. instance->nfc_dict_context.is_card_present = false;
  285. nfc_magic_app_blink_stop(instance);
  286. notification_message(instance->notifications, &sequence_display_backlight_enforce_auto);
  287. }