PatchSolution1.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. #include "PatchSolution.hpp"
  2. #include <tchar.h>
  3. #include "Helper.hpp"
  4. #undef __BASE_FILE__
  5. #define __BASE_FILE__ "PatchSolution1.cpp"
  6. const PatchSolution1::KeywordInfo PatchSolution1::Keywords[5] = {
  7. {
  8. "D75125B70767B94145B47C1CB3C0755E"
  9. "7CCB8825C5DCE0C58ACF944E08280140"
  10. "9A02472FAFFD1CD77864BB821AE36766"
  11. "FEEDE6A24F12662954168BFA314BD950"
  12. "32B9D82445355ED7BC0B880887D650F5",
  13. 160,
  14. STRING_DATA
  15. },
  16. {
  17. "\xfe\xea\xbc\x01",
  18. 4,
  19. IMM_DATA
  20. },
  21. {
  22. "E1CED09B9C2186BF71A70C0FE2F1E0AE"
  23. "F3BD6B75277AAB20DFAF3D110F75912B"
  24. "FB63AC50EC4C48689D1502715243A79F"
  25. "39FF2DE2BF15CE438FF885745ED54573"
  26. "850E8A9F40EE2FF505EB7476F95ADB78"
  27. "3B28CA374FAC4632892AB82FB3BF4715"
  28. "FCFE6E82D03731FC3762B6AAC3DF1C3B"
  29. "C646FE9CD3C62663A97EE72DB932A301"
  30. "312B4A7633100C8CC357262C39A2B3A6"
  31. "4B224F5276D5EDBDF0804DC3AC4B8351"
  32. "62BB1969EAEBADC43D2511D6E0239287"
  33. "81B167A48273B953378D3D2080CC0677"
  34. "7E8A2364F0234B81064C5C739A8DA28D"
  35. "C5889072BF37685CBC94C2D31D0179AD"
  36. "86D8E3AA8090D4F0B281BE37E0143746"
  37. "E6049CCC06899401264FA471C016A96C"
  38. "79815B55BBC26B43052609D9D175FBCD"
  39. "E455392F10E51EC162F51CF732E6BB39"
  40. "1F56BBFD8D957DF3D4C55B71CEFD54B1"
  41. "9C16D458757373E698D7E693A8FC3981"
  42. "5A8BF03BA05EA8C8778D38F9873D62B4"
  43. "460F41ACF997C30E7C3AF025FA171B5F"
  44. "5AD4D6B15E95C27F6B35AD61875E5505"
  45. "449B4E",
  46. 742,
  47. STRING_DATA
  48. },
  49. {
  50. "\x59\x08\x01\x00",
  51. 4,
  52. IMM_DATA
  53. },
  54. {
  55. "92933",
  56. 5,
  57. STRING_DATA
  58. }
  59. };
  60. bool PatchSolution1::CheckKey(RSACipher* cipher) const {
  61. std::string RSAPublicKeyPEM =
  62. cipher->ExportKeyString<RSACipher::KeyType::PublicKey, RSACipher::KeyFormat::PEM>();
  63. Helper::ReplaceSubString(RSAPublicKeyPEM, "\n", "\r\n");
  64. std::string EncryptedPem =
  65. Helper::NavicatCipher.EncryptString(RSAPublicKeyPEM);
  66. if (EncryptedPem.length() != 920)
  67. return false;
  68. // we require the chars in [p1, p2) of EncryptedPem must be number chars
  69. size_t p1, p2;
  70. p1 = _Patches[0].MaxPatchSize;
  71. p2 = Keywords[0].Length + 8; // 8 = strlen("29158142")
  72. if (p1 >= p2)
  73. p1 = p2 - 1;
  74. if (('1' <= EncryptedPem[p1] && EncryptedPem[p1] <= '9') == false)
  75. return false;
  76. for (size_t i = p1 + 1; i < p2; ++i)
  77. if (('0' <= EncryptedPem[i] && EncryptedPem[i] <= '9') == false)
  78. return false;
  79. _Patches[0].PatchSize = p1;
  80. p1 = Keywords[0].Length + 8 + _Patches[2].MaxPatchSize;
  81. p2 = Keywords[0].Length + 8 + Keywords[2].Length + 5;
  82. if (p1 >= p2)
  83. p1 = p2 - 1;
  84. if (('1' <= EncryptedPem[p1] && EncryptedPem[p1] <= '9') == false)
  85. return false;
  86. for (size_t i = p1 + 1; i < p2; ++i)
  87. if (('0' <= EncryptedPem[i] && EncryptedPem[i] <= '9') == false)
  88. return false;
  89. _Patches[2].PatchSize = p1 - Keywords[0].Length - 8;
  90. _Patches[4].PatchSize = Keywords[4].Length;
  91. return true;
  92. }
  93. bool PatchSolution1::FindPatchOffset() noexcept {
  94. PIMAGE_SECTION_HEADER SectionHeader_text = _TargetFile.GetSectionHeader(".text");
  95. PIMAGE_SECTION_HEADER SectionHeader_rdata = _TargetFile.GetSectionHeader(".rdata");
  96. uint8_t* PtrToSection_text = _TargetFile.GetSectionView<uint8_t>(".text");
  97. uint8_t* PtrToSection_rdata = _TargetFile.GetSectionView<uint8_t>(".rdata");
  98. PatchPointInfo TempPatches[KeywordsCount] = {};
  99. if (SectionHeader_text == nullptr)
  100. return false;
  101. if (SectionHeader_rdata == nullptr)
  102. return false;
  103. // -------------------------
  104. // try to search Keywords[0]
  105. // -------------------------
  106. for (DWORD i = 0; i < SectionHeader_rdata->SizeOfRawData; ++i) {
  107. if (memcmp(PtrToSection_rdata + i, Keywords[0].PtrToData, Keywords[0].Length) == 0) {
  108. TempPatches[0].PtrToPatch = PtrToSection_rdata + i;
  109. size_t j = Keywords[0].Length;
  110. while (TempPatches[0].PtrToPatch[j] == 0)
  111. ++j;
  112. TempPatches[0].MaxPatchSize = j - 1;
  113. break;
  114. }
  115. }
  116. if (TempPatches[0].PtrToPatch == nullptr)
  117. return false;
  118. // -------------------------
  119. // try to search Keywords[2]
  120. // -------------------------
  121. for (DWORD i = 0; i < SectionHeader_rdata->SizeOfRawData; ++i) {
  122. if (memcmp(PtrToSection_rdata + i, Keywords[2].PtrToData, Keywords[2].Length) == 0) {
  123. TempPatches[2].PtrToPatch = PtrToSection_rdata + i;
  124. size_t j = Keywords[2].Length;
  125. while (TempPatches[2].PtrToPatch[j] == 0)
  126. ++j;
  127. TempPatches[2].MaxPatchSize = j - 1;
  128. break;
  129. }
  130. }
  131. if (TempPatches[2].PtrToPatch == nullptr)
  132. return false;
  133. // -------------------------
  134. // try to search Keywords[4]
  135. // -------------------------
  136. for (DWORD i = 0; i < SectionHeader_rdata->SizeOfRawData; ++i) {
  137. if (memcmp(PtrToSection_rdata + i, Keywords[4].PtrToData, Keywords[4].Length) == 0) {
  138. TempPatches[4].PtrToPatch = PtrToSection_rdata + i;
  139. size_t j = Keywords[4].Length;
  140. while (TempPatches[4].PtrToPatch[j] == 0)
  141. ++j;
  142. TempPatches[4].MaxPatchSize = j - 1;
  143. break;
  144. }
  145. }
  146. if (TempPatches[4].PtrToPatch == nullptr)
  147. return false;
  148. // -------------------------
  149. // try to search Keywords[1] and Keywords[3]
  150. // -------------------------
  151. for (DWORD i = 0; i < SectionHeader_text->SizeOfRawData; ++i) {
  152. if (memcmp(PtrToSection_text + i, Keywords[1].PtrToData, Keywords[1].Length) == 0) {
  153. // Keywords[3] must be close to Keywords[1]
  154. for (DWORD j = i - 64; j < i + 64; ++j) {
  155. if (memcmp(PtrToSection_text + j, Keywords[3].PtrToData, Keywords[3].Length) == 0) {
  156. TempPatches[1].PtrToPatch = PtrToSection_text + i;
  157. TempPatches[1].PatchSize = Keywords[1].Length;
  158. TempPatches[1].MaxPatchSize = Keywords[1].Length;
  159. TempPatches[3].PtrToPatch = PtrToSection_text + j;
  160. TempPatches[3].PatchSize = Keywords[3].Length;
  161. TempPatches[3].MaxPatchSize = Keywords[3].Length;
  162. break;
  163. }
  164. }
  165. if (TempPatches[3].PtrToPatch)
  166. break;
  167. }
  168. }
  169. if (TempPatches[1].PtrToPatch == nullptr || TempPatches[3].PtrToPatch == nullptr)
  170. return false;
  171. for (size_t i = 0; i < KeywordsCount; ++i) {
  172. _Patches[i] = TempPatches[i];
  173. _tprintf_s(TEXT("MESSAGE: PatchSolution1: Keywords[%zu] has been found: offset = +0x%08zx.\n"),
  174. i,
  175. _Patches[i].PtrToPatch - _TargetFile.GetImageBaseView<uint8_t>());
  176. }
  177. return true;
  178. }
  179. void PatchSolution1::MakePatch(RSACipher* pCipher) const {
  180. uint8_t* pFileView = _TargetFile.GetImageBaseView<uint8_t>();
  181. std::string PublicKeyPEM =
  182. pCipher->ExportKeyString<RSACipher::KeyType::PublicKey, RSACipher::KeyFormat::PEM>();
  183. Helper::ReplaceSubString(PublicKeyPEM, "\n", "\r\n");
  184. std::string EncryptedPEM = Helper::NavicatCipher.EncryptString(PublicKeyPEM);
  185. // split encrypted_pem_pubkey to 5 part: |160 chars|8 chars|742 chars|5 chars|5 chars|
  186. // | |
  187. // \ / \ /
  188. // ImmValue1 ImmValue3
  189. size_t p0, p1, p2, p3, p4, p5;
  190. p0 = 0;
  191. p1 = p0 + _Patches[0].PatchSize;
  192. p2 = Keywords[0].Length + 8;
  193. p3 = p2 + _Patches[2].PatchSize;
  194. p4 = Keywords[0].Length + 8 + Keywords[2].Length + 5;
  195. p5 = 920;
  196. std::string EncryptedPEM0(EncryptedPEM.begin() + p0, EncryptedPEM.begin() + p1);
  197. std::string EncryptedPEM1(EncryptedPEM.begin() + p1, EncryptedPEM.begin() + p2);
  198. std::string EncryptedPEM2(EncryptedPEM.begin() + p2, EncryptedPEM.begin() + p3);
  199. std::string EncryptedPEM3(EncryptedPEM.begin() + p3, EncryptedPEM.begin() + p4);
  200. std::string EncryptedPEM4(EncryptedPEM.begin() + p4, EncryptedPEM.begin() + p5);
  201. uint32_t ImmValue1 = std::stoul(EncryptedPEM1.c_str());
  202. uint32_t ImmValue3 = std::stoul(EncryptedPEM3.c_str());
  203. _putts(TEXT("******************************************"));
  204. _putts(TEXT("* PatchSulution1 *"));
  205. _putts(TEXT("******************************************"));
  206. // ----------------------------------
  207. // process PatchOffsets[0]
  208. // ----------------------------------
  209. _tprintf_s(TEXT("@ +0x%08zx\nPrevious:\n"), _Patches[0].PtrToPatch - pFileView);
  210. Helper::PrintMemory(_Patches[0].PtrToPatch,
  211. _Patches[0].PtrToPatch + _Patches[0].PatchSize,
  212. pFileView);
  213. memcpy(_Patches[0].PtrToPatch, EncryptedPEM0.c_str(), _Patches[0].PatchSize);
  214. _putts(TEXT("After:"));
  215. Helper::PrintMemory(_Patches[0].PtrToPatch,
  216. _Patches[0].PtrToPatch + _Patches[0].PatchSize,
  217. pFileView);
  218. _putts(TEXT(""));
  219. // ----------------------------------
  220. // process PatchOffsets[1]
  221. // ----------------------------------
  222. _tprintf_s(TEXT("@ +0x%08zx\nPrevious:\n"), _Patches[1].PtrToPatch - pFileView);
  223. Helper::PrintMemory(_Patches[1].PtrToPatch,
  224. _Patches[1].PtrToPatch + _Patches[1].PatchSize,
  225. pFileView);
  226. memcpy(_Patches[1].PtrToPatch, &ImmValue1, sizeof(uint32_t));
  227. _putts(TEXT("After:"));
  228. Helper::PrintMemory(_Patches[1].PtrToPatch,
  229. _Patches[1].PtrToPatch + _Patches[1].PatchSize,
  230. pFileView);
  231. _putts(TEXT(""));
  232. // ----------------------------------
  233. // process PatchOffsets[2]
  234. // ----------------------------------
  235. _tprintf_s(TEXT("@ +0x%08zx\nPrevious:\n"), _Patches[2].PtrToPatch - pFileView);
  236. Helper::PrintMemory(_Patches[2].PtrToPatch,
  237. _Patches[2].PtrToPatch + _Patches[2].PatchSize,
  238. pFileView);
  239. memcpy(_Patches[2].PtrToPatch, EncryptedPEM2.c_str(), _Patches[2].PatchSize);
  240. _putts(TEXT("After:"));
  241. Helper::PrintMemory(_Patches[2].PtrToPatch,
  242. _Patches[2].PtrToPatch + _Patches[2].PatchSize,
  243. pFileView);
  244. _putts(TEXT(""));
  245. // ----------------------------------
  246. // process PatchOffsets[3]
  247. // ----------------------------------
  248. _tprintf_s(TEXT("@ +0x%08zx\nPrevious:\n"), _Patches[3].PtrToPatch - pFileView);
  249. Helper::PrintMemory(_Patches[3].PtrToPatch,
  250. _Patches[3].PtrToPatch + _Patches[3].PatchSize,
  251. pFileView);
  252. memcpy(_Patches[3].PtrToPatch, &ImmValue3, sizeof(uint32_t));
  253. _putts(TEXT("After:"));
  254. Helper::PrintMemory(_Patches[3].PtrToPatch,
  255. _Patches[3].PtrToPatch + _Patches[3].PatchSize,
  256. pFileView);
  257. _putts(TEXT(""));
  258. // ----------------------------------
  259. // process PatchOffsets[4]
  260. // ----------------------------------
  261. _tprintf_s(TEXT("@ +0x%08zx\nPrevious:\n"), _Patches[4].PtrToPatch - pFileView);
  262. Helper::PrintMemory(_Patches[4].PtrToPatch,
  263. _Patches[4].PtrToPatch + _Patches[4].PatchSize,
  264. pFileView);
  265. memcpy(_Patches[4].PtrToPatch, EncryptedPEM4.c_str(), _Patches[4].PatchSize);
  266. _putts(TEXT("After:"));
  267. Helper::PrintMemory(_Patches[4].PtrToPatch,
  268. _Patches[4].PtrToPatch + _Patches[4].PatchSize,
  269. pFileView);
  270. }