mifare_fuzzer_emulator.c 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  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. }
  201. } else {
  202. FuriString* card_name = furi_string_alloc_set(name);
  203. size_t filename_start = furi_string_search_rchar(card_name, '/') + 1;
  204. furi_string_right(card_name, filename_start);
  205. model->mifare_card_dsc = furi_string_get_cstr(card_name);
  206. }
  207. },
  208. true);
  209. }
  210. /// @brief Set attack type
  211. /// @param mifare_fuzzer_emulator
  212. /// @param mifare_attack
  213. void mifare_fuzzer_emulator_set_attack(
  214. MifareFuzzerEmulator* mifare_fuzzer_emulator,
  215. MifareFuzzerAttack mifare_attack) {
  216. furi_assert(mifare_fuzzer_emulator);
  217. furi_assert(mifare_attack);
  218. with_view_model(
  219. mifare_fuzzer_emulator->view,
  220. MifareFuzzerEmulatorModel * model,
  221. {
  222. model->attack = mifare_attack;
  223. switch(mifare_attack) {
  224. case MifareFuzzerAttackTestValues:
  225. model->attack_dsc = "Test values";
  226. break;
  227. case MifareFuzzerAttackRandomValues:
  228. model->attack_dsc = "Random values";
  229. break;
  230. case MifareFuzzerAttackLoadUidsFromFile:
  231. model->attack_dsc = "Load Uids From File";
  232. break;
  233. }
  234. },
  235. true);
  236. }
  237. /// @brief mifare_fuzzer_emulator_set_nfc_dev_data
  238. /// @param mifare_fuzzer_emulator
  239. /// @param nfc_dev_data
  240. void mifare_fuzzer_emulator_set_nfc_data(
  241. MifareFuzzerEmulator* mifare_fuzzer_emulator,
  242. Iso14443_3aData nfc_data) {
  243. furi_assert(mifare_fuzzer_emulator);
  244. with_view_model(
  245. mifare_fuzzer_emulator->view,
  246. MifareFuzzerEmulatorModel * model,
  247. { model->nfc_data = nfc_data; },
  248. true);
  249. }
  250. /// @brief mifare_fuzzer_emulator_set_ticks_between_cards
  251. /// @param mifare_fuzzer_emulator
  252. /// @param ticks
  253. void mifare_fuzzer_emulator_set_ticks_between_cards(
  254. MifareFuzzerEmulator* mifare_fuzzer_emulator,
  255. uint8_t ticks) {
  256. furi_assert(mifare_fuzzer_emulator);
  257. with_view_model(
  258. mifare_fuzzer_emulator->view,
  259. MifareFuzzerEmulatorModel * model,
  260. { model->ticks_between_cards = ticks; },
  261. true);
  262. }
  263. /// @brief mifare_fuzzer_emulator_set_tick_num
  264. /// @param mifare_fuzzer_emulator
  265. /// @param tick_num
  266. void mifare_fuzzer_emulator_set_tick_num(
  267. MifareFuzzerEmulator* mifare_fuzzer_emulator,
  268. uint8_t tick_num) {
  269. furi_assert(mifare_fuzzer_emulator);
  270. with_view_model(
  271. mifare_fuzzer_emulator->view,
  272. MifareFuzzerEmulatorModel * model,
  273. { model->tick_num = tick_num; },
  274. true);
  275. }