mifare_fuzzer_emulator.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. #include "mifare_fuzzer_emulator.h"
  2. #define TAG "MifareFuzzerApp_emulator_view"
  3. // Screen is 128 × 64 pixels
  4. /// @brief mifare_fuzzer_emulator_set_callback
  5. /// @param mifare_fuzzer_emulator
  6. /// @param callback
  7. /// @param context
  8. void mifare_fuzzer_emulator_set_callback(
  9. MifareFuzzerEmulator* mifare_fuzzer_emulator,
  10. MifareFuzzerEmulatorCallback callback,
  11. void* context) {
  12. furi_assert(mifare_fuzzer_emulator);
  13. furi_assert(callback);
  14. mifare_fuzzer_emulator->callback = callback;
  15. mifare_fuzzer_emulator->context = context;
  16. }
  17. /// @brief mifare_fuzzer_emulator_draw_callback
  18. /// @param canvas
  19. /// @param _model
  20. static void mifare_fuzzer_emulator_draw_callback(Canvas* canvas, void* _model) {
  21. MifareFuzzerEmulatorModel* model = _model;
  22. FuriString* furi_string = furi_string_alloc();
  23. canvas_clear(canvas);
  24. canvas_set_color(canvas, ColorBlack);
  25. // Primary font
  26. canvas_set_font(canvas, FontPrimary);
  27. // Title
  28. canvas_draw_str(canvas, 4, 11, model->title);
  29. // Emulated UID
  30. uint8_t cpos;
  31. char uid[25];
  32. char uid_char[3];
  33. cpos = 0;
  34. for(uint8_t i = 0; i < model->nfc_data.uid_len; i++) {
  35. if(i > 0) {
  36. uid[cpos] = ':';
  37. cpos++;
  38. }
  39. snprintf(uid_char, sizeof(uid_char), "%02X", model->nfc_data.uid[i]);
  40. uid[cpos] = uid_char[0];
  41. cpos++;
  42. uid[cpos] = uid_char[1];
  43. cpos++;
  44. }
  45. uid[cpos] = 0x00;
  46. canvas_draw_str_aligned(canvas, 128 / 2, 43, AlignCenter, AlignCenter, uid);
  47. // Secondary font
  48. canvas_set_font(canvas, FontSecondary);
  49. // Card
  50. canvas_draw_str(canvas, 4, 22, "c:");
  51. canvas_draw_str(canvas, 15, 22, model->mifare_card_dsc);
  52. // Timing
  53. furi_string_printf(furi_string, "%d", model->ticks_between_cards);
  54. canvas_draw_str(canvas, 100, 33, "t:");
  55. canvas_draw_str(canvas, 110, 33, furi_string_get_cstr(furi_string));
  56. // Attack
  57. canvas_draw_str(canvas, 4, 33, "a:");
  58. canvas_draw_str(canvas, 15, 33, model->attack_dsc);
  59. if(!model->is_attacking) {
  60. elements_button_left(canvas, "t-1");
  61. elements_button_center(canvas, "Start");
  62. elements_button_right(canvas, "t+1");
  63. } else {
  64. canvas_draw_line(canvas, 1, 49, (128 * model->tick_num / model->ticks_between_cards), 49);
  65. elements_button_center(canvas, "Stop");
  66. }
  67. // Free temp string
  68. furi_string_free(furi_string);
  69. }
  70. /// @brief mifare_fuzzer_emulator_input_callback
  71. /// @param event
  72. /// @param context
  73. /// @return
  74. static bool mifare_fuzzer_emulator_input_callback(InputEvent* event, void* context) {
  75. //FURI_LOG_D(TAG, "mifare_fuzzer_emulator_input_callback()");
  76. furi_assert(context);
  77. MifareFuzzerEmulator* mifare_fuzzer_emulator = context;
  78. bool consumed = false;
  79. if(event->type == InputTypeShort) {
  80. if(event->key == InputKeyRight) {
  81. if(!mifare_fuzzer_emulator->is_attacking) {
  82. mifare_fuzzer_emulator->callback(
  83. MifareFuzzerEventIncrementTicks, mifare_fuzzer_emulator->context);
  84. };
  85. consumed = true;
  86. } else if(event->key == InputKeyLeft) {
  87. if(!mifare_fuzzer_emulator->is_attacking) {
  88. mifare_fuzzer_emulator->callback(
  89. MifareFuzzerEventDecrementTicks, mifare_fuzzer_emulator->context);
  90. };
  91. consumed = true;
  92. } else if(event->key == InputKeyUp) {
  93. consumed = true;
  94. } else if(event->key == InputKeyDown) {
  95. consumed = true;
  96. } else if(event->key == InputKeyOk) {
  97. // Toggle attack
  98. if(mifare_fuzzer_emulator->is_attacking) {
  99. mifare_fuzzer_emulator->is_attacking = false;
  100. mifare_fuzzer_emulator->callback(
  101. MifareFuzzerEventStopAttack, mifare_fuzzer_emulator->context);
  102. } else {
  103. mifare_fuzzer_emulator->is_attacking = true;
  104. mifare_fuzzer_emulator->callback(
  105. MifareFuzzerEventStartAttack, mifare_fuzzer_emulator->context);
  106. }
  107. with_view_model(
  108. mifare_fuzzer_emulator->view,
  109. MifareFuzzerEmulatorModel * model,
  110. { model->is_attacking = mifare_fuzzer_emulator->is_attacking; },
  111. true);
  112. consumed = true;
  113. }
  114. }
  115. return consumed;
  116. }
  117. /// @brief mifare_fuzzer_emulator_enter_callback
  118. /// @param context
  119. static void mifare_fuzzer_emulator_enter_callback(void* context) {
  120. //FURI_LOG_D(TAG, "mifare_fuzzer_emulator_enter_callback()");
  121. furi_assert(context);
  122. MifareFuzzerEmulator* mifare_fuzzer_emulator = context;
  123. //UNUSED(mifare_fuzzer_emulator);
  124. mifare_fuzzer_emulator->is_attacking = false;
  125. with_view_model(
  126. mifare_fuzzer_emulator->view,
  127. MifareFuzzerEmulatorModel * model,
  128. { model->is_attacking = false; },
  129. true);
  130. }
  131. /// @brief mifare_fuzzer_emulator_alloc
  132. /// @return
  133. MifareFuzzerEmulator* mifare_fuzzer_emulator_alloc() {
  134. MifareFuzzerEmulator* mifare_fuzzer_emulator = malloc(sizeof(MifareFuzzerEmulator));
  135. mifare_fuzzer_emulator->view = view_alloc();
  136. view_set_context(mifare_fuzzer_emulator->view, mifare_fuzzer_emulator);
  137. view_allocate_model(
  138. mifare_fuzzer_emulator->view, ViewModelTypeLocking, sizeof(MifareFuzzerEmulatorModel));
  139. view_set_draw_callback(mifare_fuzzer_emulator->view, mifare_fuzzer_emulator_draw_callback);
  140. view_set_input_callback(mifare_fuzzer_emulator->view, mifare_fuzzer_emulator_input_callback);
  141. view_set_enter_callback(mifare_fuzzer_emulator->view, mifare_fuzzer_emulator_enter_callback);
  142. with_view_model(
  143. mifare_fuzzer_emulator->view,
  144. MifareFuzzerEmulatorModel * model,
  145. { model->title = "Mifare Fuzzer (emulator)"; },
  146. true);
  147. return mifare_fuzzer_emulator;
  148. }
  149. /// @brief mifare_fuzzer_emulator_free
  150. /// @param context
  151. void mifare_fuzzer_emulator_free(MifareFuzzerEmulator* context) {
  152. //FURI_LOG_D(TAG, "mifare_fuzzer_emulator_free()");
  153. furi_assert(context);
  154. MifareFuzzerEmulator* mifare_fuzzer_emulator = context;
  155. /*
  156. with_view_model(
  157. mifare_fuzzer_emulator->view,
  158. MifareFuzzerEmulatorModel* model,
  159. {
  160. UNUSED(model);
  161. },
  162. true
  163. );
  164. */
  165. view_free(mifare_fuzzer_emulator->view);
  166. free(mifare_fuzzer_emulator);
  167. }
  168. /// @brief mifare_fuzzer_emulator_get_view
  169. /// @param mifare_fuzzer_emulator
  170. /// @return
  171. View* mifare_fuzzer_emulator_get_view(MifareFuzzerEmulator* mifare_fuzzer_emulator) {
  172. furi_assert(mifare_fuzzer_emulator);
  173. return mifare_fuzzer_emulator->view;
  174. }
  175. /// @brief Set card type
  176. /// @param mifare_fuzzer_emulator
  177. /// @param mifare_card
  178. void mifare_fuzzer_emulator_set_card(
  179. MifareFuzzerEmulator* mifare_fuzzer_emulator,
  180. MifareCard mifare_card,
  181. FuriString* name) {
  182. furi_assert(mifare_fuzzer_emulator);
  183. furi_assert(mifare_card);
  184. with_view_model(
  185. mifare_fuzzer_emulator->view,
  186. MifareFuzzerEmulatorModel * model,
  187. {
  188. model->mifare_card = mifare_card;
  189. if(name == NULL) {
  190. switch(mifare_card) {
  191. case MifareCardClassic1k:
  192. model->mifare_card_dsc = "Classic 1k";
  193. break;
  194. case MifareCardClassic4k:
  195. model->mifare_card_dsc = "Classic 4k";
  196. break;
  197. case MifareCardUltralight:
  198. model->mifare_card_dsc = "Ultralight";
  199. break;
  200. case MifareCardUnsupported:
  201. model->mifare_card_dsc = "Unsupported Card!";
  202. break;
  203. }
  204. } else {
  205. FuriString* card_name = furi_string_alloc_set(name);
  206. size_t filename_start = furi_string_search_rchar(card_name, '/') + 1;
  207. furi_string_right(card_name, filename_start);
  208. model->mifare_card_dsc = furi_string_get_cstr(card_name);
  209. }
  210. },
  211. true);
  212. }
  213. /// @brief Set attack type
  214. /// @param mifare_fuzzer_emulator
  215. /// @param mifare_attack
  216. void mifare_fuzzer_emulator_set_attack(
  217. MifareFuzzerEmulator* mifare_fuzzer_emulator,
  218. MifareFuzzerAttack mifare_attack) {
  219. furi_assert(mifare_fuzzer_emulator);
  220. furi_assert(mifare_attack);
  221. with_view_model(
  222. mifare_fuzzer_emulator->view,
  223. MifareFuzzerEmulatorModel * model,
  224. {
  225. model->attack = mifare_attack;
  226. switch(mifare_attack) {
  227. case MifareFuzzerAttackTestValues:
  228. model->attack_dsc = "Test values";
  229. break;
  230. case MifareFuzzerAttackRandomValues:
  231. model->attack_dsc = "Random values";
  232. break;
  233. case MifareFuzzerAttackLoadUidsFromFile:
  234. model->attack_dsc = "Load Uids From File";
  235. break;
  236. }
  237. },
  238. true);
  239. }
  240. /// @brief mifare_fuzzer_emulator_set_nfc_dev_data
  241. /// @param mifare_fuzzer_emulator
  242. /// @param nfc_dev_data
  243. void mifare_fuzzer_emulator_set_nfc_data(
  244. MifareFuzzerEmulator* mifare_fuzzer_emulator,
  245. Iso14443_3aData nfc_data) {
  246. furi_assert(mifare_fuzzer_emulator);
  247. with_view_model(
  248. mifare_fuzzer_emulator->view,
  249. MifareFuzzerEmulatorModel * model,
  250. { model->nfc_data = nfc_data; },
  251. true);
  252. }
  253. /// @brief mifare_fuzzer_emulator_set_ticks_between_cards
  254. /// @param mifare_fuzzer_emulator
  255. /// @param ticks
  256. void mifare_fuzzer_emulator_set_ticks_between_cards(
  257. MifareFuzzerEmulator* mifare_fuzzer_emulator,
  258. uint8_t ticks) {
  259. furi_assert(mifare_fuzzer_emulator);
  260. with_view_model(
  261. mifare_fuzzer_emulator->view,
  262. MifareFuzzerEmulatorModel * model,
  263. { model->ticks_between_cards = ticks; },
  264. true);
  265. }
  266. /// @brief mifare_fuzzer_emulator_set_tick_num
  267. /// @param mifare_fuzzer_emulator
  268. /// @param tick_num
  269. void mifare_fuzzer_emulator_set_tick_num(
  270. MifareFuzzerEmulator* mifare_fuzzer_emulator,
  271. uint8_t tick_num) {
  272. furi_assert(mifare_fuzzer_emulator);
  273. with_view_model(
  274. mifare_fuzzer_emulator->view,
  275. MifareFuzzerEmulatorModel * model,
  276. { model->tick_num = tick_num; },
  277. true);
  278. }