mifare_fuzzer_emulator.c 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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_dev_data.uid_len; i++) {
  35. if (i > 0) {
  36. uid[cpos] = ':';
  37. cpos++;
  38. }
  39. snprintf(uid_char, sizeof(uid_char), "%02X", model->nfc_dev_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, 90, 22, "t:");
  55. canvas_draw_str(canvas, 100, 22, 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(MifareFuzzerEventIncrementTicks, mifare_fuzzer_emulator->context);
  83. };
  84. consumed = true;
  85. } else if(event->key == InputKeyLeft) {
  86. if (!mifare_fuzzer_emulator->is_attacking) {
  87. mifare_fuzzer_emulator->callback(MifareFuzzerEventDecrementTicks, mifare_fuzzer_emulator->context);
  88. };
  89. consumed = true;
  90. } else if(event->key == InputKeyUp) {
  91. consumed = true;
  92. } else if(event->key == InputKeyDown) {
  93. consumed = true;
  94. } else if(event->key == InputKeyOk) {
  95. // Toggle attack
  96. if (mifare_fuzzer_emulator->is_attacking) {
  97. mifare_fuzzer_emulator->is_attacking = false;
  98. mifare_fuzzer_emulator->callback(MifareFuzzerEventStopAttack, mifare_fuzzer_emulator->context);
  99. } else {
  100. mifare_fuzzer_emulator->is_attacking = true;
  101. mifare_fuzzer_emulator->callback(MifareFuzzerEventStartAttack, mifare_fuzzer_emulator->context);
  102. }
  103. with_view_model(
  104. mifare_fuzzer_emulator->view,
  105. MifareFuzzerEmulatorModel* model,
  106. {
  107. model->is_attacking = mifare_fuzzer_emulator->is_attacking;
  108. }, true
  109. );
  110. consumed = true;
  111. }
  112. }
  113. return consumed;
  114. }
  115. /// @brief mifare_fuzzer_emulator_enter_callback
  116. /// @param context
  117. static void mifare_fuzzer_emulator_enter_callback(void* context) {
  118. //FURI_LOG_D(TAG, "mifare_fuzzer_emulator_enter_callback()");
  119. furi_assert(context);
  120. MifareFuzzerEmulator* mifare_fuzzer_emulator = context;
  121. //UNUSED(mifare_fuzzer_emulator);
  122. mifare_fuzzer_emulator->is_attacking = false;
  123. with_view_model(
  124. mifare_fuzzer_emulator->view,
  125. MifareFuzzerEmulatorModel* model,
  126. {
  127. model->is_attacking = false;
  128. },
  129. true
  130. );
  131. }
  132. /// @brief mifare_fuzzer_emulator_alloc
  133. /// @return
  134. MifareFuzzerEmulator* mifare_fuzzer_emulator_alloc() {
  135. MifareFuzzerEmulator* mifare_fuzzer_emulator = malloc(sizeof(MifareFuzzerEmulator));
  136. mifare_fuzzer_emulator->view = view_alloc();
  137. view_set_context(mifare_fuzzer_emulator->view, mifare_fuzzer_emulator);
  138. view_allocate_model(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. {
  146. model->title = "Mifare Fuzzer (emulator)";
  147. },
  148. true
  149. );
  150. return mifare_fuzzer_emulator;
  151. }
  152. /// @brief mifare_fuzzer_emulator_free
  153. /// @param context
  154. void mifare_fuzzer_emulator_free(MifareFuzzerEmulator* context) {
  155. //FURI_LOG_D(TAG, "mifare_fuzzer_emulator_free()");
  156. furi_assert(context);
  157. MifareFuzzerEmulator* mifare_fuzzer_emulator = context;
  158. /*
  159. with_view_model(
  160. mifare_fuzzer_emulator->view,
  161. MifareFuzzerEmulatorModel* model,
  162. {
  163. UNUSED(model);
  164. },
  165. true
  166. );
  167. */
  168. view_free(mifare_fuzzer_emulator->view);
  169. free(mifare_fuzzer_emulator);
  170. }
  171. /// @brief mifare_fuzzer_emulator_get_view
  172. /// @param mifare_fuzzer_emulator
  173. /// @return
  174. View* mifare_fuzzer_emulator_get_view(MifareFuzzerEmulator* mifare_fuzzer_emulator) {
  175. furi_assert(mifare_fuzzer_emulator);
  176. return mifare_fuzzer_emulator->view;
  177. }
  178. /// @brief Set card type
  179. /// @param mifare_fuzzer_emulator
  180. /// @param mifare_card
  181. void mifare_fuzzer_emulator_set_card(MifareFuzzerEmulator* mifare_fuzzer_emulator, MifareCard mifare_card) {
  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. switch(mifare_card) {
  190. case MifareCardClassic1k:
  191. model->mifare_card_dsc = "Classic 1k";
  192. break;
  193. case MifareCardClassic4k:
  194. model->mifare_card_dsc = "Classic 4k";
  195. break;
  196. case MifareCardUltralight:
  197. model->mifare_card_dsc = "Ultralight";
  198. break;
  199. }
  200. },
  201. true
  202. );
  203. }
  204. /// @brief Set attack type
  205. /// @param mifare_fuzzer_emulator
  206. /// @param mifare_attack
  207. void mifare_fuzzer_emulator_set_attack(MifareFuzzerEmulator* mifare_fuzzer_emulator, MifareFuzzerAttack mifare_attack) {
  208. furi_assert(mifare_fuzzer_emulator);
  209. furi_assert(mifare_attack);
  210. with_view_model(
  211. mifare_fuzzer_emulator->view,
  212. MifareFuzzerEmulatorModel* model,
  213. {
  214. model->attack = mifare_attack;
  215. switch(mifare_attack) {
  216. case MifareFuzzerAttackTestValues:
  217. model->attack_dsc = "Test values";
  218. break;
  219. case MifareFuzzerAttackRandomValues:
  220. model->attack_dsc = "Random values";
  221. break;
  222. case MifareFuzzerAttackLoadUidsFromFile:
  223. model->attack_dsc = "Load Uids From File";
  224. break;
  225. }
  226. },
  227. true
  228. );
  229. }
  230. /// @brief mifare_fuzzer_emulator_set_nfc_dev_data
  231. /// @param mifare_fuzzer_emulator
  232. /// @param nfc_dev_data
  233. void mifare_fuzzer_emulator_set_nfc_dev_data(MifareFuzzerEmulator* mifare_fuzzer_emulator, FuriHalNfcDevData nfc_dev_data) {
  234. furi_assert(mifare_fuzzer_emulator);
  235. with_view_model(
  236. mifare_fuzzer_emulator->view,
  237. MifareFuzzerEmulatorModel* model,
  238. {
  239. model->nfc_dev_data = nfc_dev_data;
  240. }, true
  241. );
  242. }
  243. /// @brief mifare_fuzzer_emulator_set_ticks_between_cards
  244. /// @param mifare_fuzzer_emulator
  245. /// @param ticks
  246. void mifare_fuzzer_emulator_set_ticks_between_cards(MifareFuzzerEmulator* mifare_fuzzer_emulator, uint8_t ticks) {
  247. furi_assert(mifare_fuzzer_emulator);
  248. with_view_model(
  249. mifare_fuzzer_emulator->view,
  250. MifareFuzzerEmulatorModel* model,
  251. {
  252. model->ticks_between_cards = ticks;
  253. }, true
  254. );
  255. }
  256. /// @brief mifare_fuzzer_emulator_set_tick_num
  257. /// @param mifare_fuzzer_emulator
  258. /// @param tick_num
  259. void mifare_fuzzer_emulator_set_tick_num(MifareFuzzerEmulator* mifare_fuzzer_emulator, uint8_t tick_num) {
  260. furi_assert(mifare_fuzzer_emulator);
  261. with_view_model(
  262. mifare_fuzzer_emulator->view,
  263. MifareFuzzerEmulatorModel* model,
  264. {
  265. model->tick_num = tick_num;
  266. }, true
  267. );
  268. }