PatchSolution1.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #include "PatchSolutions.hpp"
  2. #include "Misc.hpp"
  3. #include <memory.h>
  4. namespace nkg {
  5. const uint8_t PatchSolution1::Keyword[0x188] = {
  6. 0xfe, 0xfd, 0xfc, 0xf4, 0xfe, 0xd2, 0xf8, 0xf4, 0xf1, 0xd3, 0xde, 0xc7, 0xdf, 0xd3, 0xd0, 0xfd,
  7. 0x8a, 0xc3, 0x85, 0xf4, 0xf6, 0xe9, 0xfc, 0xfc, 0xf2, 0xf5, 0xfa, 0xf5, 0xf6, 0xe9, 0x81, 0xfb,
  8. 0xfe, 0xfd, 0xfc, 0xf4, 0xf4, 0xdf, 0xf2, 0xf9, 0xf2, 0xe5, 0xf0, 0xf7, 0xc0, 0x89, 0xdd, 0xcb,
  9. 0xf5, 0x87, 0xe6, 0xdd, 0xf4, 0xd9, 0xf8, 0xfb, 0xde, 0xf9, 0xcf, 0xc5, 0x8f, 0x80, 0x80, 0xf3,
  10. 0xc2, 0xd0, 0xe2, 0x8f, 0xfa, 0x8a, 0xdd, 0xf3, 0xd7, 0xdc, 0x86, 0xdc, 0xf0, 0x81, 0xc0, 0xea,
  11. 0xd0, 0xd9, 0xf9, 0xd8, 0xda, 0xf2, 0xd0, 0xfd, 0xc3, 0xf6, 0xf3, 0x82, 0xf2, 0x81, 0xef, 0xf2,
  12. 0xe0, 0xf9, 0xf2, 0xd3, 0x8f, 0xd7, 0xe9, 0xfb, 0xca, 0x86, 0xde, 0xfc, 0xf3, 0xd5, 0xdd, 0xf4,
  13. 0xc7, 0x80, 0xf7, 0xd5, 0xf2, 0xc1, 0xde, 0xcc, 0xc0, 0xc7, 0xf0, 0xd0, 0xd0, 0xd1, 0xd7, 0xcc,
  14. 0xd2, 0x81, 0xc1, 0x83, 0xdd, 0xd5, 0x8a, 0x8f, 0x81, 0xe1, 0xf4, 0xd9, 0xf3, 0xd7, 0xca, 0xef,
  15. 0xf9, 0xdf, 0xe1, 0xee, 0xf0, 0xe9, 0xd1, 0xca, 0xf2, 0xe3, 0xf8, 0xf0, 0x83, 0xde, 0xfb, 0xd7,
  16. 0xf1, 0xc4, 0xfa, 0x85, 0xf2, 0xdd, 0xdd, 0xfd, 0x85, 0x86, 0xc7, 0xf9, 0xc4, 0xc9, 0xf4, 0xf8,
  17. 0xd4, 0xd9, 0xe6, 0xd2, 0xf6, 0xc1, 0xc1, 0xf9, 0xe0, 0xe4, 0xf7, 0xe4, 0xfd, 0xf1, 0xf6, 0xfc,
  18. 0xe1, 0x84, 0xe4, 0xd1, 0xed, 0xfe, 0xdb, 0xe8, 0xdd, 0xe1, 0x85, 0xd0, 0xc5, 0xd2, 0x8a, 0x8e,
  19. 0xd5, 0xdd, 0xe3, 0xdb, 0xd0, 0xe1, 0xd0, 0xf6, 0xc6, 0xee, 0xe6, 0xf7, 0xda, 0xf1, 0xdb, 0xc9,
  20. 0x8b, 0xee, 0xcd, 0xdf, 0xff, 0xe8, 0xdd, 0xca, 0x82, 0xdb, 0xf1, 0x82, 0xc3, 0xed, 0xc9, 0xcc,
  21. 0xc0, 0xf2, 0xd6, 0xdf, 0x83, 0xe9, 0xf3, 0xce, 0xea, 0xfa, 0xdf, 0xf8, 0xd9, 0xff, 0xec, 0x88,
  22. 0xe4, 0xe4, 0xfd, 0x80, 0xc5, 0xce, 0xfa, 0xd2, 0xf4, 0xd8, 0x84, 0xff, 0xe5, 0xf3, 0xcb, 0xc2,
  23. 0xfe, 0xc0, 0xc4, 0xfa, 0xde, 0xdd, 0xd5, 0xc9, 0xc5, 0xd5, 0xdf, 0xe3, 0xdd, 0xc1, 0xcb, 0xdd,
  24. 0xfc, 0xf7, 0x83, 0xf8, 0xda, 0xc1, 0xd4, 0xe3, 0xfe, 0xc2, 0xef, 0xf8, 0xf2, 0xea, 0x8a, 0xd2,
  25. 0xc7, 0xf2, 0xf0, 0xc2, 0xfb, 0x89, 0xdc, 0xeb, 0xd1, 0xf7, 0xcc, 0xe2, 0xd1, 0xfc, 0xd4, 0xce,
  26. 0xea, 0xcd, 0xe4, 0x87, 0xe0, 0xcc, 0x8d, 0xf5, 0xc7, 0x85, 0x87, 0xda, 0xcf, 0xde, 0x89, 0xcd,
  27. 0xe5, 0xfd, 0xe7, 0x83, 0xda, 0xdb, 0xfe, 0xf4, 0x84, 0xec, 0xf6, 0xee, 0xfd, 0xea, 0xf1, 0xf5,
  28. 0xf5, 0xfc, 0xe6, 0xd0, 0x86, 0xdf, 0xc3, 0xe2, 0xe4, 0xd5, 0xd7, 0xe4, 0xe4, 0xce, 0xd4, 0xce,
  29. 0x82, 0xda, 0xc7, 0xda, 0x80, 0xcb, 0xee, 0x8c, 0xd0, 0xde, 0xcd, 0xda, 0xdd, 0xcd, 0xcc, 0xeb,
  30. 0xd2, 0xc3, 0xfc, 0xf2, 0xf6, 0xe9, 0xf8, 0xf8
  31. };
  32. PatchSolution1::PatchSolution1(const X64ImageInterpreter& Image) :
  33. m_Image(Image) {}
  34. [[nodiscard]]
  35. bool PatchSolution1::FindPatchOffset() noexcept {
  36. try {
  37. void* lpPatch = nullptr;
  38. for (size_t i = 0; i < m_Image.NumberOfSections(); ++i) {
  39. auto section = m_Image.ImageSection(i);
  40. if (section->size >= sizeof(Keyword)) {
  41. lpPatch = m_Image.SearchSection(section, [](const void* base, size_t i, size_t size) {
  42. if (i + sizeof(Keyword) <= size) {
  43. return memcmp(ARL::AddressOffset(base, i), Keyword, sizeof(Keyword)) == 0;
  44. } else {
  45. return false;
  46. }
  47. });
  48. if (lpPatch) {
  49. m_PatchOffset = m_Image.ConvertPtrToOffset(lpPatch);
  50. break;
  51. }
  52. }
  53. }
  54. if (lpPatch) {
  55. printf("[+] PatchSolution1 ...... Ready to apply.\n");
  56. printf(" Keyword offset = +0x%.8x\n", m_PatchOffset.value());
  57. return true;
  58. } else {
  59. throw ARL::Exception(__FILE__, __LINE__, "not found.");
  60. }
  61. } catch (...) {
  62. printf("[-] PatchSolution1 ...... Omitted.\n");
  63. return false;
  64. }
  65. }
  66. [[nodiscard]]
  67. bool PatchSolution1::CheckKey(const RSACipher& Cipher) const noexcept {
  68. try {
  69. return Cipher.Bits() == 2048;
  70. } catch (...) {
  71. return false;
  72. }
  73. }
  74. void PatchSolution1::MakePatch(const RSACipher& Cipher) const {
  75. if (m_PatchOffset.has_value()) {
  76. auto szPublicKeyPEM = Cipher.ExportKeyString<RSAKeyType::PublicKey, RSAKeyFormat::PEM>();
  77. for (auto pos = szPublicKeyPEM.find("-----BEGIN PUBLIC KEY-----"); pos != std::string::npos; pos = szPublicKeyPEM.find("-----BEGIN PUBLIC KEY-----", pos)) {
  78. szPublicKeyPEM.erase(pos, strlen("-----BEGIN PUBLIC KEY-----"));
  79. }
  80. for (auto pos = szPublicKeyPEM.find("-----END PUBLIC KEY-----"); pos != std::string::npos; pos = szPublicKeyPEM.find("-----END PUBLIC KEY-----", pos)) {
  81. szPublicKeyPEM.erase(pos, strlen("-----END PUBLIC KEY-----"));
  82. }
  83. for (auto pos = szPublicKeyPEM.find('\n'); pos != std::string::npos; pos = szPublicKeyPEM.find('\n', pos)) {
  84. szPublicKeyPEM.erase(pos, 1);
  85. }
  86. for (size_t i = 0, key = 8; i < szPublicKeyPEM.length(); ++i, --key) {
  87. if (key == 0) {
  88. key = 8;
  89. }
  90. szPublicKeyPEM[i] ^= static_cast<char>(0xBB - key);
  91. }
  92. while (szPublicKeyPEM.length() < sizeof(Keyword)) {
  93. szPublicKeyPEM.push_back('\x00');
  94. }
  95. auto lpPatch = m_Image.ImageOffset(m_PatchOffset.value());
  96. puts("**************************************************************");
  97. puts("* PatchSolution1 *");
  98. puts("**************************************************************");
  99. printf("[*] Previous:\n");
  100. Misc::PrintMemory(lpPatch, sizeof(Keyword), m_Image.ImageBase());
  101. memcpy(lpPatch, szPublicKeyPEM.data(), sizeof(Keyword));
  102. printf("[*] After:\n");
  103. Misc::PrintMemory(lpPatch, sizeof(Keyword), m_Image.ImageBase());
  104. printf("\n");
  105. } else {
  106. throw ARL::Exception(__FILE__, __LINE__, "PatchSolution1: not ready yet.");
  107. }
  108. }
  109. }