PatchSolution1.cpp 12 KB

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