subbrute_protocols.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456
  1. #include "subbrute_protocols.h"
  2. #define TAG "SubBruteProtocols"
  3. /**
  4. * CAME 12bit 303MHz
  5. */
  6. const SubBruteProtocol subbrute_protocol_came_12bit_303 = {
  7. .frequency = 303875000,
  8. .bits = 12,
  9. .te = 0,
  10. .repeat = 3,
  11. .preset = FuriHalSubGhzPresetOok650Async,
  12. .file = CAMEFileProtocol};
  13. /**
  14. * CAME 12bit 307MHz
  15. */
  16. const SubBruteProtocol subbrute_protocol_came_12bit_307 = {
  17. .frequency = 307800000,
  18. .bits = 12,
  19. .te = 0,
  20. .repeat = 3,
  21. .preset = FuriHalSubGhzPresetOok650Async,
  22. .file = CAMEFileProtocol};
  23. /**
  24. * CAME 12bit 433MHz
  25. */
  26. const SubBruteProtocol subbrute_protocol_came_12bit_433 = {
  27. .frequency = 433920000,
  28. .bits = 12,
  29. .te = 0,
  30. .repeat = 3,
  31. .preset = FuriHalSubGhzPresetOok650Async,
  32. .file = CAMEFileProtocol};
  33. /**
  34. * CAME 12bit 868MHz
  35. */
  36. const SubBruteProtocol subbrute_protocol_came_12bit_868 = {
  37. .frequency = 868350000,
  38. .bits = 12,
  39. .te = 0,
  40. .repeat = 3,
  41. .preset = FuriHalSubGhzPresetOok650Async,
  42. .file = CAMEFileProtocol};
  43. /**
  44. * NICE 12bit 433MHz
  45. */
  46. const SubBruteProtocol subbrute_protocol_nice_12bit_433 = {
  47. .frequency = 433920000,
  48. .bits = 12,
  49. .te = 0,
  50. .repeat = 3,
  51. .preset = FuriHalSubGhzPresetOok650Async,
  52. .file = NICEFileProtocol};
  53. /**
  54. * NICE 12bit 868MHz
  55. */
  56. const SubBruteProtocol subbrute_protocol_nice_12bit_868 = {
  57. .frequency = 868350000,
  58. .bits = 12,
  59. .te = 0,
  60. .repeat = 3,
  61. .preset = FuriHalSubGhzPresetOok650Async,
  62. .file = NICEFileProtocol};
  63. /**
  64. * Chamberlain 9bit 300MHz
  65. */
  66. const SubBruteProtocol subbrute_protocol_chamberlain_9bit_300 = {
  67. .frequency = 300000000,
  68. .bits = 9,
  69. .te = 0,
  70. .repeat = 3,
  71. .preset = FuriHalSubGhzPresetOok650Async,
  72. .file = ChamberlainFileProtocol};
  73. /**
  74. * Chamberlain 9bit 315MHz
  75. */
  76. const SubBruteProtocol subbrute_protocol_chamberlain_9bit_315 = {
  77. .frequency = 315000000,
  78. .bits = 9,
  79. .te = 0,
  80. .repeat = 3,
  81. .preset = FuriHalSubGhzPresetOok650Async,
  82. .file = ChamberlainFileProtocol};
  83. /**
  84. * Chamberlain 9bit 390MHz
  85. */
  86. const SubBruteProtocol subbrute_protocol_chamberlain_9bit_390 = {
  87. .frequency = 390000000,
  88. .bits = 9,
  89. .te = 0,
  90. .repeat = 3,
  91. .preset = FuriHalSubGhzPresetOok650Async,
  92. .file = ChamberlainFileProtocol};
  93. /**
  94. * Linear 10bit 300MHz
  95. */
  96. const SubBruteProtocol subbrute_protocol_linear_10bit_300 = {
  97. .frequency = 300000000,
  98. .bits = 10,
  99. .te = 0,
  100. .repeat = 5,
  101. .preset = FuriHalSubGhzPresetOok650Async,
  102. .file = LinearFileProtocol};
  103. /**
  104. * Linear 10bit 310MHz
  105. */
  106. const SubBruteProtocol subbrute_protocol_linear_10bit_310 = {
  107. .frequency = 310000000,
  108. .bits = 10,
  109. .te = 0,
  110. .repeat = 5,
  111. .preset = FuriHalSubGhzPresetOok650Async,
  112. .file = LinearFileProtocol};
  113. /**
  114. * BF existing dump
  115. */
  116. const SubBruteProtocol subbrute_protocol_load_file =
  117. {0, 0, 0, 3, FuriHalSubGhzPresetOok650Async, RAWFileProtocol};
  118. //static const SubBruteProtocol subbrute_protocols[SubBruteAttackTotalCount] = {
  119. // [SubBruteAttackCAME12bit303] =
  120. // {303875000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol},
  121. // [SubBruteAttackCAME12bit307] =
  122. // {307800000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol},
  123. // [SubBruteAttackCAME12bit433] =
  124. // {433920000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol},
  125. // [SubBruteAttackCAME12bit868] =
  126. // {868350000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, CAMEFileProtocol},
  127. // [SubBruteAttackNICE12bit433] =
  128. // {433920000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, NICEFileProtocol},
  129. // [SubBruteAttackNICE12bit868] =
  130. // {868350000, 12, 0, 3, FuriHalSubGhzPresetOok650Async, NICEFileProtocol},
  131. // [SubBruteAttackChamberlain9bit300] =
  132. // {300000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol},
  133. // [SubBruteAttackChamberlain9bit315] =
  134. // {315000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol},
  135. // [SubBruteAttackChamberlain9bit390] =
  136. // {390000000, 9, 0, 3, FuriHalSubGhzPresetOok650Async, ChamberlainFileProtocol},
  137. // [SubBruteAttackLinear10bit300] =
  138. // {300000000, 10, 0, 5, FuriHalSubGhzPresetOok650Async, LinearFileProtocol},
  139. // [SubBruteAttackLinear10bit310] =
  140. // {300000000, 10, 0, 5, FuriHalSubGhzPresetOok650Async, LinearFileProtocol},
  141. // [SubBruteAttackLoadFile] = {0, 0, 0, 3, FuriHalSubGhzPresetOok650Async, RAWFileProtocol},
  142. //};
  143. static const char* subbrute_protocol_names[] = {
  144. [SubBruteAttackCAME12bit303] = "CAME 12bit 303MHz",
  145. [SubBruteAttackCAME12bit307] = "CAME 12bit 307MHz",
  146. [SubBruteAttackCAME12bit433] = "CAME 12bit 433MHz",
  147. [SubBruteAttackCAME12bit868] = "CAME 12bit 868MHz",
  148. [SubBruteAttackNICE12bit433] = "NICE 12bit 433MHz",
  149. [SubBruteAttackNICE12bit868] = "NICE 12bit 868MHz",
  150. [SubBruteAttackChamberlain9bit300] = "Chamberlain 9bit 300MHz",
  151. [SubBruteAttackChamberlain9bit315] = "Chamberlain 9bit 315MHz",
  152. [SubBruteAttackChamberlain9bit390] = "Chamberlain 9bit 390MHz",
  153. [SubBruteAttackLinear10bit300] = "Linear 10bit 300MHz",
  154. [SubBruteAttackLinear10bit310] = "Linear 10bit 310MHz",
  155. [SubBruteAttackLoadFile] = "BF existing dump",
  156. [SubBruteAttackTotalCount] = "Total Count",
  157. };
  158. static const char* subbrute_protocol_presets[] = {
  159. [FuriHalSubGhzPresetIDLE] = "FuriHalSubGhzPresetIDLE",
  160. [FuriHalSubGhzPresetOok270Async] = "FuriHalSubGhzPresetOok270Async",
  161. [FuriHalSubGhzPresetOok650Async] = "FuriHalSubGhzPresetOok650Async",
  162. [FuriHalSubGhzPreset2FSKDev238Async] = "FuriHalSubGhzPreset2FSKDev238Async",
  163. [FuriHalSubGhzPreset2FSKDev476Async] = "FuriHalSubGhzPreset2FSKDev476Async",
  164. [FuriHalSubGhzPresetMSK99_97KbAsync] = "FuriHalSubGhzPresetMSK99_97KbAsync",
  165. [FuriHalSubGhzPresetGFSK9_99KbAsync] = "FuriHalSubGhzPresetGFSK9_99KbAsync",
  166. };
  167. const SubBruteProtocol* subbrute_protocol_registry[] = {
  168. [SubBruteAttackCAME12bit303] = &subbrute_protocol_came_12bit_303,
  169. [SubBruteAttackCAME12bit307] = &subbrute_protocol_came_12bit_307,
  170. [SubBruteAttackCAME12bit433] = &subbrute_protocol_came_12bit_433,
  171. [SubBruteAttackCAME12bit868] = &subbrute_protocol_came_12bit_868,
  172. [SubBruteAttackNICE12bit433] = &subbrute_protocol_nice_12bit_433,
  173. [SubBruteAttackNICE12bit868] = &subbrute_protocol_nice_12bit_868,
  174. [SubBruteAttackChamberlain9bit300] = &subbrute_protocol_chamberlain_9bit_300,
  175. [SubBruteAttackChamberlain9bit315] = &subbrute_protocol_chamberlain_9bit_315,
  176. [SubBruteAttackChamberlain9bit390] = &subbrute_protocol_chamberlain_9bit_390,
  177. [SubBruteAttackLinear10bit300] = &subbrute_protocol_linear_10bit_300,
  178. [SubBruteAttackLinear10bit310] = &subbrute_protocol_linear_10bit_310,
  179. [SubBruteAttackLoadFile] = &subbrute_protocol_load_file};
  180. static const char* subbrute_protocol_file_types[] = {
  181. [CAMEFileProtocol] = "CAME",
  182. [NICEFileProtocol] = "Nice FLO",
  183. [ChamberlainFileProtocol] = "Cham_Code",
  184. [LinearFileProtocol] = "Linear",
  185. [PrincetonFileProtocol] = "Princeton",
  186. [RAWFileProtocol] = "RAW"};
  187. /**
  188. * Values to not use less memory for packet parse operations
  189. */
  190. static const char* subbrute_key_file_start_no_tail =
  191. "Filetype: Flipper SubGhz Key File\nVersion: 1\nFrequency: %u\nPreset: %s\nProtocol: %s\nBit: %d\nKey: %s\nRepeat: %d\n";
  192. static const char* subbrute_key_file_start_with_tail =
  193. "Filetype: Flipper SubGhz Key File\nVersion: 1\nFrequency: %u\nPreset: %s\nProtocol: %s\nBit: %d\nKey: %s\nTE: %d\nRepeat: %d\n";
  194. static const char* subbrute_key_small_no_tail = "Bit: %d\nKey: %s\nRepeat: %d\nRepeat: %d\n";
  195. static const char* subbrute_key_small_with_tail = "Bit: %d\nKey: %s\nTE: %d\nRepeat: %d\n";
  196. const char* subbrute_protocol_name(SubBruteAttacks index) {
  197. return subbrute_protocol_names[index];
  198. }
  199. const SubBruteProtocol* subbrute_protocol(SubBruteAttacks index) {
  200. return subbrute_protocol_registry[index];
  201. }
  202. const char* subbrute_protocol_preset(FuriHalSubGhzPreset preset) {
  203. return subbrute_protocol_presets[preset];
  204. }
  205. const char* subbrute_protocol_file(SubBruteFileProtocol protocol) {
  206. return subbrute_protocol_file_types[protocol];
  207. }
  208. FuriHalSubGhzPreset subbrute_protocol_convert_preset(FuriString* preset_name) {
  209. for(size_t i = FuriHalSubGhzPresetIDLE; i < FuriHalSubGhzPresetCustom; i++) {
  210. if(furi_string_cmp_str(preset_name, subbrute_protocol_presets[i]) == 0) {
  211. return i;
  212. }
  213. }
  214. return FuriHalSubGhzPresetIDLE;
  215. }
  216. SubBruteFileProtocol subbrute_protocol_file_protocol_name(FuriString* name) {
  217. for(size_t i = CAMEFileProtocol; i < TotalFileProtocol - 1; i++) {
  218. if(furi_string_cmp_str(name, subbrute_protocol_file_types[i]) == 0) {
  219. return i;
  220. }
  221. }
  222. return RAWFileProtocol;
  223. }
  224. FuriString*
  225. subbrute_protocol_default_payload(uint64_t step, uint8_t bits, uint8_t te, uint8_t repeat) {
  226. FuriString* candidate = furi_string_alloc_set_str(" ");
  227. FuriString* buffer = furi_string_alloc_printf("%16llX", step);
  228. int j = 0;
  229. for(uint8_t i = 0; i < 16; i++) {
  230. if(furi_string_get_char(buffer, i) != ' ') {
  231. furi_string_set_char(candidate, i + j, furi_string_get_char(buffer, i));
  232. } else {
  233. furi_string_set_char(candidate, i + j, '0');
  234. }
  235. if(i % 2 != 0) {
  236. j++;
  237. }
  238. }
  239. furi_string_free(buffer);
  240. #ifdef FURI_DEBUG
  241. FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step);
  242. #endif
  243. FuriString* result;
  244. if(te) {
  245. result = furi_string_alloc_printf(
  246. subbrute_key_small_with_tail, bits, furi_string_get_cstr(candidate), te, repeat);
  247. } else {
  248. result = furi_string_alloc_printf(
  249. subbrute_key_small_no_tail, bits, furi_string_get_cstr(candidate), repeat);
  250. }
  251. #ifdef FURI_DEBUG
  252. FURI_LOG_D(TAG, "result: %s", furi_string_get_cstr(result));
  253. #endif
  254. furi_string_free(candidate);
  255. return result;
  256. }
  257. FuriString* subbrute_protocol_file_payload(
  258. uint64_t step,
  259. uint8_t bits,
  260. uint8_t te,
  261. uint8_t repeat,
  262. uint8_t load_index,
  263. const char* file_key) {
  264. FuriString* candidate = furi_string_alloc();
  265. if(step >= sizeof(file_key)) {
  266. return false;
  267. }
  268. char subbrute_payload_byte[4];
  269. furi_string_set_str(candidate, file_key);
  270. snprintf(subbrute_payload_byte, 4, "%02X ", (uint8_t)step);
  271. furi_string_replace_at(candidate, load_index * 3, 3, subbrute_payload_byte);
  272. #ifdef FURI_DEBUG
  273. FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step);
  274. #endif
  275. FuriString* result;
  276. if(te) {
  277. result = furi_string_alloc_printf(
  278. subbrute_key_small_with_tail, bits, furi_string_get_cstr(candidate), te, repeat);
  279. } else {
  280. result = furi_string_alloc_printf(
  281. subbrute_key_small_no_tail, bits, furi_string_get_cstr(candidate), repeat);
  282. }
  283. #ifdef FURI_DEBUG
  284. FURI_LOG_D(TAG, "result: %s", furi_string_get_cstr(result));
  285. #endif
  286. furi_string_free(candidate);
  287. return result;
  288. }
  289. FuriString* subbrute_protocol_default_generate_file(
  290. uint32_t frequency,
  291. FuriHalSubGhzPreset preset,
  292. SubBruteFileProtocol file,
  293. uint64_t step,
  294. uint8_t bits,
  295. uint8_t te,
  296. uint8_t repeat) {
  297. FuriString* candidate = furi_string_alloc_set_str(" ");
  298. FuriString* buffer = furi_string_alloc_printf("%16llX", step);
  299. int j = 0;
  300. for(uint8_t i = 0; i < 16; i++) {
  301. if(furi_string_get_char(buffer, i) != ' ') {
  302. furi_string_set_char(candidate, i + j, furi_string_get_char(buffer, i));
  303. } else {
  304. furi_string_set_char(candidate, i + j, '0');
  305. }
  306. if(i % 2 != 0) {
  307. j++;
  308. }
  309. }
  310. furi_string_free(buffer);
  311. #ifdef FURI_DEBUG
  312. FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step);
  313. #endif
  314. FuriString* result;
  315. if(te) {
  316. result = furi_string_alloc_printf(
  317. subbrute_key_file_start_with_tail,
  318. frequency,
  319. preset,
  320. file,
  321. bits,
  322. furi_string_get_cstr(candidate),
  323. te,
  324. repeat);
  325. } else {
  326. result = furi_string_alloc_printf(
  327. subbrute_key_file_start_no_tail,
  328. frequency,
  329. preset,
  330. file,
  331. bits,
  332. furi_string_get_cstr(candidate),
  333. repeat);
  334. }
  335. #ifdef FURI_DEBUG
  336. FURI_LOG_D(TAG, "result: %s", furi_string_get_cstr(result));
  337. #endif
  338. furi_string_free(candidate);
  339. return result;
  340. }
  341. FuriString* subbrute_protocol_file_generate_file(
  342. uint32_t frequency,
  343. FuriHalSubGhzPreset preset,
  344. SubBruteFileProtocol file,
  345. uint64_t step,
  346. uint8_t bits,
  347. uint8_t te,
  348. uint8_t repeat,
  349. uint8_t load_index,
  350. const char* file_key) {
  351. FuriString* candidate = furi_string_alloc();
  352. if(step >= sizeof(file_key)) {
  353. return false;
  354. }
  355. char subbrute_payload_byte[4];
  356. furi_string_set_str(candidate, file_key);
  357. snprintf(subbrute_payload_byte, 4, "%02X ", (uint8_t)step);
  358. furi_string_replace_at(candidate, load_index * 3, 3, subbrute_payload_byte);
  359. #ifdef FURI_DEBUG
  360. FURI_LOG_D(TAG, "candidate: %s, step: %lld", furi_string_get_cstr(candidate), step);
  361. #endif
  362. FuriString* result;
  363. if(te) {
  364. result = furi_string_alloc_printf(
  365. subbrute_key_file_start_with_tail,
  366. frequency,
  367. preset,
  368. file,
  369. bits,
  370. furi_string_get_cstr(candidate),
  371. te,
  372. repeat);
  373. } else {
  374. result = furi_string_alloc_printf(
  375. subbrute_key_file_start_no_tail,
  376. frequency,
  377. preset,
  378. file,
  379. bits,
  380. furi_string_get_cstr(candidate),
  381. repeat);
  382. }
  383. #ifdef FURI_DEBUG
  384. FURI_LOG_D(TAG, "result: %s", furi_string_get_cstr(result));
  385. #endif
  386. furi_string_free(candidate);
  387. return result;
  388. }
  389. uint64_t subbrute_protocol_calc_max_value(SubBruteAttacks attack_type, uint8_t bits) {
  390. uint64_t max_value;
  391. if(attack_type == SubBruteAttackLoadFile) {
  392. max_value = 0x3F;
  393. } else {
  394. FuriString* max_value_s;
  395. max_value_s = furi_string_alloc();
  396. for(uint8_t i = 0; i < bits; i++) {
  397. furi_string_cat_printf(max_value_s, "1");
  398. }
  399. max_value = (uint64_t)strtol(furi_string_get_cstr(max_value_s), NULL, 2);
  400. furi_string_free(max_value_s);
  401. }
  402. return max_value;
  403. }