main.cpp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. #include <fstream>
  2. #include <iostream>
  3. #include <vector>
  4. #include <map>
  5. #include <cstring>
  6. #ifdef BOINC_APPLICATION
  7. #include "boinc_api.h"
  8. #endif
  9. using namespace std;
  10. typedef unsigned char int8;
  11. typedef unsigned short int16;
  12. typedef unsigned int int32;
  13. typedef unsigned char uint8;
  14. typedef signed char sint8;
  15. typedef unsigned short uint16;
  16. typedef signed short sint16;
  17. typedef unsigned int uint32;
  18. typedef signed int sint32;
  19. typedef unsigned char uchar;
  20. int processBlock(int8* alldata, int8 key1, int8 key2, int8 key3, int8 key4, int8 key5, int8 key6, FILE* outFile);
  21. int entries = 0;
  22. std::map<int32, std::string> filenames;
  23. int main(int argc, char** argv)
  24. {
  25. std::string outputKey("");
  26. #ifdef BOINC_APPLICATION
  27. boinc_init();
  28. #endif
  29. FILE* file = fopen("testbin.dat", "r+b");
  30. fread(&entries, sizeof(int32), 1, file);
  31. if(entries < 1) {
  32. return 0;
  33. }
  34. string resolved_name("");
  35. FILE* outFile = NULL;
  36. #ifdef BOINC_APPLICATION
  37. int retval = boinc_resolve_filename_s("out", resolved_name);
  38. if (!retval) {
  39. outFile = boinc_fopen(resolved_name.c_str(), "w+");
  40. }
  41. #endif
  42. //printf("Entries found %u\n",entries);
  43. int8* mp3s = new int8[entries*10];
  44. int offset = 0;
  45. for(int i=0;i<entries;i++) {
  46. int filenamelength = 0;
  47. fread(&filenamelength, sizeof(int32), 1, file);
  48. char filename[256];
  49. fread(filename, sizeof(char), filenamelength, file);
  50. filename[filenamelength] = '\0';
  51. std::string fileNameStr = std::string(filename);
  52. // printf("Entry adding (%u) %s\n",filenamelength,fileNameStr.c_str());
  53. filenames.insert(make_pair(i, fileNameStr));
  54. fread(&mp3s[offset], sizeof(unsigned char), 10, file);
  55. offset += 10;
  56. }
  57. fclose(file);
  58. int8 key[8];
  59. key[0] = 0xff;
  60. key[1] = 0xff;
  61. key[2] = 0xfF;
  62. key[3] = 0xff;
  63. key[4] = 0xFF;
  64. key[5] = 0xFF;
  65. key[6] = 0xFF;
  66. key[7] = 0xFF;
  67. bool bigtask = false;
  68. if (argc > 5) {
  69. for (int8 i = 0; i < 7; i++) {
  70. if (i >= argc - 1)
  71. break;
  72. key[i] = strtol(argv[i + 1], NULL, 16);
  73. }
  74. int total_found = processBlock(mp3s, key[0], key[1], key[2], key[3], key[4], key[5], outFile);
  75. if(outFile) {
  76. if(total_found > 0) {
  77. // do nothing
  78. }
  79. else {
  80. fwrite("0", sizeof(char), 1, outFile);
  81. }
  82. fclose(outFile);
  83. }
  84. #ifdef BOINC_APPLICATION
  85. boinc_finish(0);
  86. #endif
  87. return 0;
  88. }
  89. else{
  90. cout << "Usage: eq2_voice_recover [key1] [key2] [key3] [key4] [key5] [key6]\n";
  91. cout << "Example: eq2_voice_recover 91 CD E3 8F A6 93\n\n";
  92. cout << "NOTE: If you want to test it, rename all_data.bin to something else and rename all_data.bin.TEST to all_data.bin.\nOnce that is done the above example should find a match very quickly.\n";
  93. }
  94. if(outFile) {
  95. fwrite("0", sizeof(char), 1, outFile);
  96. fclose(outFile);
  97. }
  98. #ifdef BOINC_APPLICATION
  99. boinc_finish(0);
  100. #endif
  101. return 0;
  102. }
  103. int processBlock(int8* alldata, int8 key1, int8 key2, int8 key3, int8 key4, int8 key5, int8 key6, FILE* outFile) {
  104. int total_found = 0;
  105. int8 key[8];
  106. key[0] = key1;
  107. key[1] = key2;
  108. key[2] = key3;
  109. key[3] = key4;
  110. key[4] = key5;
  111. key[5] = key6;
  112. key[6] = 255;
  113. key[7] = 255;
  114. int8 S[256];
  115. int8 keyinit[256];
  116. int8 expected_result[8] = { 0x49, 0x44, 0x33, 0x03, 0x00, 0x00, 0x00, 0x00 };
  117. map<int8, map<int8, map<int8, vector<int32>>>> expected_result_lookup;
  118. int32 pos = 0;
  119. int8 test_byte = 0;
  120. int8 test_byte2 = 0;
  121. int8 test_byte3 = 0;
  122. int8* data = 0;
  123. int32 keys_tried = 0;
  124. for (int16 z = 0; z < entries; z++) {
  125. pos = z * 10;
  126. data = alldata + pos;
  127. test_byte = data[0] ^ expected_result[0];
  128. test_byte2 = data[1] ^ expected_result[1];
  129. test_byte3 = data[2] ^ expected_result[2];
  130. expected_result_lookup[test_byte][test_byte2][test_byte3].push_back(pos);
  131. }
  132. for (int i = 0; i < 256; i++)
  133. keyinit[i] = i;
  134. int16 total_work = 255 * 15;
  135. if (key6 != 255)
  136. total_work -= (255 - key6);
  137. int16 current_work = 0;
  138. int8 loop_count = 15;
  139. if (key[4] == 15)
  140. loop_count = 16; //we need to work on 0 as well, we start at 255
  141. for (int e = 0; e < loop_count;e++) {
  142. //cout << "key6: " << (int)key6 << ", key5: " << (int)key[4] << endl;
  143. for (sint16 f = key6; f >= 0; f--) {
  144. key[5] = f;
  145. for (sint16 g = 255; g >= 0; g--) {
  146. key[6] = g;
  147. for (sint16 h = 255; h >= 0; h--) {
  148. keys_tried++;
  149. key[7] = h;
  150. memcpy(S, keyinit, 256);
  151. int16 j = 0;
  152. int8 tmp = 0;
  153. for (int i = 0; i < 256; i++) {
  154. j = (j + S[i] + key[i % 8]) % 256;
  155. tmp = S[j];
  156. S[j] = S[i];
  157. S[i] = tmp;
  158. }
  159. int16 i = 0;
  160. j = 0;
  161. tmp = 0;
  162. int8 test_bytes[8];
  163. bool success = false;
  164. bool first_pass = false;
  165. for (int x = 0; x < 8; x++) {
  166. i = (i + 1);
  167. j = (j + S[i]) % 256;
  168. tmp = S[j];
  169. S[j] = S[i];
  170. S[i] = tmp;
  171. test_bytes[x] = S[(S[i] + S[j]) % 256];
  172. if (x < 3) {
  173. if (x == 0 && expected_result_lookup.count(test_bytes[x]) == 0)
  174. break;
  175. if (x == 1 && expected_result_lookup[test_bytes[0]].count(test_bytes[x]) == 0)
  176. break;
  177. if (x == 2) {
  178. if (expected_result_lookup[test_bytes[0]][test_bytes[1]].count(test_bytes[x]) == 0)
  179. break;
  180. else
  181. first_pass = true;
  182. }
  183. }
  184. }
  185. int whichKey = 0;
  186. if (first_pass) {
  187. vector<int32>::iterator data_itr;
  188. for (data_itr = expected_result_lookup[test_bytes[0]][test_bytes[1]][test_bytes[2]].begin(); data_itr != expected_result_lookup[test_bytes[0]][test_bytes[1]][test_bytes[2]].end(); data_itr++) {
  189. whichKey = *data_itr / 10;
  190. int8* data = alldata + *data_itr;
  191. for (int8 x = 3; x < 8; x++) {
  192. if ((test_bytes[x] ^ data[x]) != expected_result[x])
  193. break;
  194. if (x == 7)
  195. success = true;
  196. }
  197. }
  198. }
  199. if (success) {
  200. string foundkey = "";
  201. char output[4];
  202. for (int o = 0; o < 8; o++) {
  203. snprintf(output, 3, "%02X", (unsigned char)key[o]);
  204. foundkey.append(output);
  205. }
  206. if(outFile) {
  207. std::string data("FOUND KEY: " + foundkey + " based on key " + filenames[whichKey]);
  208. fwrite(data.c_str(),sizeof(char),data.size(),outFile);
  209. }
  210. cout << "FOUND KEY: " << foundkey.c_str() << " based on key " << filenames[whichKey] << endl;
  211. total_found += 1;
  212. }
  213. }
  214. }
  215. current_work++;
  216. }
  217. double fraction = ((double)(current_work)) / ((double)total_work);
  218. if(fraction > 1.0) {
  219. fraction = 1.0;
  220. }
  221. #ifdef BOINC_APPLICATION
  222. boinc_fraction_done(fraction);
  223. #endif
  224. cout << "percent done: " << ((double)(current_work)) / ((double)total_work) << " keys tried " << keys_tried << endl;
  225. key6 = 255;
  226. if(key[4] > 0)
  227. key[4]--;
  228. }
  229. return total_found;
  230. }