/Warden DLL/crevold.c

https://github.com/Hdx/Battle.net-Warden · C · 207 lines · 160 code · 28 blank · 19 comment · 66 complexity · 9e7297e3c02087b360a537164f035769 MD5 · raw file

  1. #include "crevold.h"
  2. /*void wwrite_to_file(const uint8_t *data){
  3. FILE *fp;
  4. fopen_s(&fp, "WardenLog.txt", "a");
  5. fwrite(data, 1, strlen(data), fp);
  6. fclose(fp);
  7. }*/
  8. uint32_t __stdcall crev_ver1(uint8_t *archive_time, uint8_t *archive_name, uint8_t *seed, uint8_t *ini_file, uint8_t *ini_header, uint32_t *version, uint32_t *checksum, uint8_t *result){
  9. return crev_old(0, archive_name[7] - '0', seed, ini_file, ini_header, version, checksum, result);
  10. }
  11. uint32_t __stdcall crev_ver2(uint8_t *archive_time, uint8_t *archive_name, uint8_t *seed, uint8_t *ini_file, uint8_t *ini_header, uint32_t *version, uint32_t *checksum, uint8_t *result){
  12. return crev_old(1, archive_name[9] - '0', seed, ini_file, ini_header, version, checksum, result);
  13. }
  14. uint32_t __stdcall crev_old(uint32_t padd, uint8_t archive_ver, uint8_t *seed, uint8_t *ini_file, uint8_t *ini_header, uint32_t *version, uint32_t *checksum, uint8_t *result){
  15. uint64_t A = 0;
  16. uint64_t B = 0;
  17. uint64_t C = 0;
  18. uint32_t S = 0;
  19. uint32_t x = 0;
  20. uint32_t y = 0;
  21. uint32_t file_size = 0;
  22. uint8_t ops[4];
  23. uint8_t *files[4];
  24. uint8_t *buff = safe_malloc(MAX_PATH);
  25. const uint8_t *keys[] = {"Exe", "Util", "Network"};
  26. const uint32_t seeds[] = {0xE7F4CB62, 0xF6A14FFC, 0xAA5504AF, 0x871FCDC2, 0x11BF6A18, 0xC57292E6, 0x7927D27E, 0x2FEC8733};
  27. uint8_t *tok;
  28. uint8_t *tok_pos;
  29. //uint8_t *tmp = safe_malloc(MAX_PATH * 2);
  30. if(archive_ver > 7){
  31. free(buff);
  32. return CREV_UNKNOWN_REVISION;
  33. }
  34. tok = strtok_s(seed, " ", &tok_pos);
  35. for(x = 0; x < 3; x++){
  36. if(tok == NULL)
  37. return CREV_MALFORMED_SEED;
  38. if(tok[1] == '='){
  39. if(tok[0] == 'A' || tok[0] == 'a') A = strtoul((uint8_t*)&tok[2], NULL, 10);
  40. if(tok[0] == 'B' || tok[0] == 'b') B = strtoul((uint8_t*)&tok[2], NULL, 10);
  41. if(tok[0] == 'C' || tok[0] == 'c') C = strtoul((uint8_t*)&tok[2], NULL, 10);
  42. }else{
  43. return CREV_MALFORMED_SEED;
  44. }
  45. tok = strtok_s(NULL, " ", &tok_pos);
  46. }
  47. /*
  48. *sprintf_s(tmp, MAX_PATH * 2, "A: %lu\n", A); wwrite_to_file(tmp);
  49. *sprintf_s(tmp, MAX_PATH * 2, "B: %lu\n", B); wwrite_to_file(tmp);
  50. *sprintf_s(tmp, MAX_PATH * 2, "C: %lu\n", C); wwrite_to_file(tmp);
  51. */
  52. tok = strtok_s(NULL, " ", &tok_pos); //Skip the '4'
  53. for(x = 0; x < 4; x++){
  54. if(tok == NULL)
  55. return CREV_MALFORMED_SEED;
  56. ops[x] = tok[3];
  57. tok[3] = '.';
  58. switch(x){
  59. case 0: if(_stricmp(tok, "A=A.S") != 0) return CREV_MALFORMED_SEED; break;
  60. case 1: if(_stricmp(tok, "B=B.C") != 0) return CREV_MALFORMED_SEED; break;
  61. case 2: if(_stricmp(tok, "C=C.A") != 0) return CREV_MALFORMED_SEED; break;
  62. case 3: if(_stricmp(tok, "A=A.B") != 0) return CREV_MALFORMED_SEED; break;
  63. }
  64. tok = strtok_s(NULL, " ", &tok_pos);
  65. }
  66. //sprintf_s(tmp, MAX_PATH * 2, "Ops: %c%c%c%c\n", ops[0], ops[1], ops[2], ops[3]); wwrite_to_file(tmp);
  67. read_ini_new(ini_file, ini_header, "Path", "", buff, MAX_PATH);
  68. files[0] = safe_malloc(MAX_PATH);
  69. combine_paths(buff, "", files[0], MAX_PATH);
  70. for(x = 1; x < 4; x++){
  71. read_ini_new(ini_file, ini_header, (uint8_t*)keys[x-1], "\xFF", buff, MAX_PATH);
  72. if(buff[0] == 0xFF){
  73. for(y = 0; y < x; y++)
  74. if(files[y] != NULL) free(files[y]);
  75. sprintf_s(result, crev_max_result(), "%s\x00", keys[x-1]);
  76. return CREV_MISSING_FILENAME;
  77. }
  78. files[x] = safe_malloc(MAX_PATH);
  79. combine_paths(files[0], buff, files[x], MAX_PATH);
  80. }
  81. free(buff);
  82. /*
  83. *sprintf_s(tmp, MAX_PATH * 2, "Path: %s\n", files[0]); wwrite_to_file(tmp);
  84. *sprintf_s(tmp, MAX_PATH * 2, "Exe: %s %d\n", files[1], get_file_size(files[1])); wwrite_to_file(tmp);
  85. *sprintf_s(tmp, MAX_PATH * 2, "Util: %s %d\n", files[2], get_file_size(files[2])); wwrite_to_file(tmp);
  86. *sprintf_s(tmp, MAX_PATH * 2, "Network: %s %d\n", files[3], get_file_size(files[3])); wwrite_to_file(tmp);
  87. */
  88. A ^= seeds[archive_ver];
  89. for(x = 1; x < 4; x++){
  90. file_size = get_file_size(files[x]);
  91. if((file_size % 1024) != 0){
  92. if(padd == 1) file_size += (1024 - (file_size % 1024));
  93. else file_size -= (file_size % 1024);
  94. }
  95. if(file_size == 0){
  96. sprintf_s(result, CREV_MAX_RESULT, files[x]);
  97. return CREV_MISSING_FILE;
  98. }
  99. buff = safe_malloc(file_size);
  100. get_file_data(files[x], buff, file_size, padd);
  101. for(y = 0; y < file_size; y+= 4){
  102. S = (*(uint32_t*)&buff[y]);
  103. switch (ops[0]) {
  104. case '^': A ^= S; break;
  105. case '+': A += S; break;
  106. case '-': A -= S; break;
  107. case '*': A *= S; break;
  108. case '/': A /= S; break;
  109. }
  110. switch (ops[1]){
  111. case '^': B ^= C; break;
  112. case '+': B += C; break;
  113. case '-': B -= C; break;
  114. case '*': B *= C; break;
  115. case '/': B /= C; break;
  116. }
  117. switch (ops[2]){
  118. case '^': C ^= A; break;
  119. case '+': C += A; break;
  120. case '-': C -= A; break;
  121. case '*': C *= A; break;
  122. case '/': C /= A; break;
  123. }
  124. switch (ops[3]){
  125. case '^': A ^= B; break;
  126. case '+': A += B; break;
  127. case '-': A -= B; break;
  128. case '*': A *= B; break;
  129. case '/': A /= B; break;
  130. }
  131. }
  132. free(buff);
  133. }
  134. *checksum = (uint32_t)(C & 0x00000000FFFFFFFF);
  135. *version = crev_get_file_version(files[1]);
  136. S = crev_get_file_information(files[1], result, CREV_MAX_RESULT);
  137. for(x = 0; x < 4; x++){
  138. if(files[x] != NULL)
  139. free(files[x]);
  140. }
  141. return S;
  142. }
  143. uint32_t crev_get_file_information(uint8_t *file, uint8_t *buffer, uint32_t size){
  144. uint8_t *file_name;
  145. uint32_t x = 0;
  146. uint32_t len = 0;
  147. FILETIME ft;
  148. SYSTEMTIME st;
  149. HANDLE fhandle;
  150. sprintf_s(buffer, size, file);
  151. len = strlen(file);
  152. if(len == 0) return CREV_FILE_INFO_ERROR;
  153. file_name = safe_malloc(len);
  154. for(x = len; x != 0; x--){
  155. if(file[x] == '\\' || file[x] == '/')
  156. break;
  157. }
  158. memcpy(file_name, (uint8_t*)(&file[x+1]), len - x + 1);
  159. fhandle = CreateFile(file, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  160. if(fhandle == INVALID_HANDLE_VALUE){
  161. free(file_name);
  162. return CREV_FILE_INFO_ERROR;
  163. }
  164. if(GetFileTime(fhandle, NULL, &ft, NULL) == 0){
  165. free(file_name);
  166. CloseHandle(fhandle);
  167. return CREV_FILE_INFO_ERROR;
  168. }
  169. len = GetFileSize(fhandle, NULL);
  170. CloseHandle(fhandle);
  171. if(FileTimeToSystemTime(&ft, &st) == 0){
  172. free(file_name);
  173. return CREV_FILE_INFO_ERROR;
  174. }
  175. sprintf_s(buffer, size, "%s %02u/%02u/%02u %02u:%02u:%02u %lu",
  176. file_name, st.wMonth, st.wDay, (st.wYear % 100), st.wHour, st.wMinute, st.wSecond, len);
  177. free(file_name);
  178. return CREV_SUCCESS;
  179. }