nameflood.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include "nameflood.h"
  2. #include "_protocols.h"
  3. #include <storage/storage.h>
  4. #include <toolbox/stream/file_stream.h>
  5. // Hacked together by @Willy-JL
  6. static char names[256][sizeof(((NamefloodCfg*)0)->name)];
  7. static uint8_t names_count = 0;
  8. static const char* get_name(const Payload* payload) {
  9. UNUSED(payload);
  10. return "NameFlood";
  11. }
  12. static const char* random_name() {
  13. if(names_count == 0) {
  14. // Fill random names
  15. Storage* storage = furi_record_open(RECORD_STORAGE);
  16. Stream* stream = file_stream_alloc(storage);
  17. FuriString* line = furi_string_alloc();
  18. if(!storage_file_exists(storage, APP_DATA_PATH("nameflood.txt"))) {
  19. // Copy default names
  20. storage_common_copy(
  21. storage, APP_ASSETS_PATH("nameflood.txt"), APP_DATA_PATH("nameflood.txt"));
  22. }
  23. if(file_stream_open(
  24. stream, APP_DATA_PATH("nameflood.txt"), FSAM_READ, FSOM_OPEN_EXISTING)) {
  25. while(stream_read_line(stream, line)) {
  26. furi_string_replace_all(line, "\r", "");
  27. furi_string_replace_all(line, "\n", "");
  28. if(furi_string_size(line)) {
  29. strlcpy(names[names_count++], furi_string_get_cstr(line), sizeof(names[0]));
  30. }
  31. }
  32. }
  33. furi_string_free(line);
  34. file_stream_close(stream);
  35. stream_free(stream);
  36. furi_record_close(RECORD_STORAGE);
  37. if(names_count == 0) {
  38. // Add fallback if list is empty
  39. strlcpy(names[names_count++], "NameFlood", sizeof(names[0]));
  40. }
  41. }
  42. return names[rand() % names_count];
  43. }
  44. static void make_packet(uint8_t* _size, uint8_t** _packet, Payload* payload) {
  45. NamefloodCfg* cfg = payload ? &payload->cfg.nameflood : NULL;
  46. const char* name;
  47. switch(cfg ? payload->mode : PayloadModeRandom) {
  48. case PayloadModeRandom:
  49. default:
  50. name = random_name();
  51. break;
  52. case PayloadModeValue:
  53. name = cfg->name;
  54. break;
  55. }
  56. uint8_t name_len = strlen(name);
  57. uint8_t size = 12 + name_len;
  58. uint8_t* packet = malloc(size);
  59. uint8_t i = 0;
  60. packet[i++] = 2; // Size
  61. packet[i++] = 0x01; // AD Type (Flags)
  62. packet[i++] = 0x06; // Flags
  63. packet[i++] = name_len + 1; // Size
  64. packet[i++] = 0x09; // AD Type (Complete Local Name)
  65. memcpy(&packet[i], name, name_len); // Device Name
  66. i += name_len;
  67. packet[i++] = 3; // Size
  68. packet[i++] = 0x02; // AD Type (Incomplete Service UUID List)
  69. packet[i++] = 0x12; // Service UUID (Human Interface Device)
  70. packet[i++] = 0x18; // ...
  71. packet[i++] = 2; // Size
  72. packet[i++] = 0x0A; // AD Type (Tx Power Level)
  73. packet[i++] = 0x00; // 0dBm
  74. *_size = size;
  75. *_packet = packet;
  76. }
  77. enum {
  78. _ConfigExtraStart = ConfigExtraStart,
  79. ConfigName,
  80. ConfigInfoSettings,
  81. ConfigCOUNT,
  82. };
  83. static void config_callback(void* _ctx, uint32_t index) {
  84. Ctx* ctx = _ctx;
  85. scene_manager_set_scene_state(ctx->scene_manager, SceneConfig, index);
  86. switch(index) {
  87. case ConfigName:
  88. scene_manager_next_scene(ctx->scene_manager, SceneNamefloodName);
  89. break;
  90. case ConfigInfoSettings:
  91. break;
  92. default:
  93. ctx->fallback_config_enter(ctx, index);
  94. break;
  95. }
  96. }
  97. static void extra_config(Ctx* ctx) {
  98. Payload* payload = &ctx->attack->payload;
  99. NamefloodCfg* cfg = &payload->cfg.nameflood;
  100. VariableItemList* list = ctx->variable_item_list;
  101. VariableItem* item;
  102. item = variable_item_list_add(list, "Display Name", 0, NULL, NULL);
  103. variable_item_set_current_value_text(
  104. item, payload->mode == PayloadModeRandom ? "Random" : cfg->name);
  105. variable_item_list_add(list, "See in phone BT settings", 0, NULL, NULL);
  106. variable_item_list_set_enter_callback(list, config_callback, ctx);
  107. }
  108. static uint8_t config_count(const Payload* payload) {
  109. UNUSED(payload);
  110. return ConfigCOUNT - ConfigExtraStart - 1;
  111. }
  112. const Protocol protocol_nameflood = {
  113. .icon = &I_ble_spam,
  114. .get_name = get_name,
  115. .make_packet = make_packet,
  116. .extra_config = extra_config,
  117. .config_count = config_count,
  118. };
  119. static void name_callback(void* _ctx) {
  120. Ctx* ctx = _ctx;
  121. Payload* payload = &ctx->attack->payload;
  122. payload->mode = PayloadModeValue;
  123. view_dispatcher_send_custom_event(ctx->view_dispatcher, 0);
  124. }
  125. void scene_nameflood_name_on_enter(void* _ctx) {
  126. Ctx* ctx = _ctx;
  127. Payload* payload = &ctx->attack->payload;
  128. NamefloodCfg* cfg = &payload->cfg.nameflood;
  129. TextInput* text_input = ctx->text_input;
  130. text_input_set_header_text(text_input, "Press back for random");
  131. text_input_set_result_callback(
  132. text_input, name_callback, ctx, cfg->name, sizeof(cfg->name), true);
  133. text_input_set_minimum_length(text_input, 0);
  134. view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewTextInput);
  135. }
  136. bool scene_nameflood_name_on_event(void* _ctx, SceneManagerEvent event) {
  137. Ctx* ctx = _ctx;
  138. Payload* payload = &ctx->attack->payload;
  139. if(event.type == SceneManagerEventTypeCustom) {
  140. scene_manager_previous_scene(ctx->scene_manager);
  141. return true;
  142. }
  143. if(event.type == SceneManagerEventTypeBack) {
  144. payload->mode = PayloadModeRandom;
  145. }
  146. return false;
  147. }
  148. void scene_nameflood_name_on_exit(void* _ctx) {
  149. Ctx* ctx = _ctx;
  150. text_input_reset(ctx->text_input);
  151. }