PatchSolutions.hpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. #pragma once
  2. #include <RSACipher.hpp>
  3. #include "ImageInterpreter.hpp"
  4. #include "CapstoneDisassembler.hpp"
  5. #include "Misc.hpp"
  6. namespace nkg {
  7. class PatchSolution {
  8. protected:
  9. static constexpr size_t InvalidOffset = -1;
  10. public:
  11. [[nodiscard]]
  12. virtual bool FindPatchOffset() noexcept = 0;
  13. [[nodiscard]]
  14. virtual bool CheckKey(const RSACipher& Cipher) const noexcept = 0;
  15. virtual void MakePatch(const RSACipher& Cipher) const = 0;
  16. virtual ~PatchSolution() = default;
  17. };
  18. //
  19. // PatchSolution0 will replace the RSA public key stored in navicat.exe
  20. //
  21. class PatchSolution0 final : public PatchSolution {
  22. private:
  23. static const char Keyword[461];
  24. const ImageInterpreter& _Image;
  25. size_t _PatchOffset;
  26. public:
  27. PatchSolution0(const ImageInterpreter& Image) noexcept :
  28. _Image(Image),
  29. _PatchOffset(InvalidOffset) {}
  30. PatchSolution0(const ImageInterpreter* lpImage) noexcept :
  31. _Image(*lpImage),
  32. _PatchOffset(InvalidOffset) {}
  33. [[nodiscard]]
  34. virtual bool FindPatchOffset() noexcept override;
  35. [[nodiscard]]
  36. virtual bool CheckKey(const RSACipher& Cipher) const noexcept override;
  37. virtual void MakePatch(const RSACipher& Cipher) const override;
  38. };
  39. //
  40. // PatchSolution1 will replace the RSA public key stored in libcc.dll
  41. //
  42. class PatchSolution1 final : public PatchSolution {
  43. private:
  44. static const char Keyword0[160 + 1];
  45. static const char Keyword1[4 + 1];
  46. static const char Keyword2[742 + 1];
  47. static const char Keyword3[4 + 1];
  48. static const char Keyword4[5 + 1];
  49. const ImageInterpreter& _Image;
  50. size_t _PatchOffset[5];
  51. size_t _PatchSize[5];
  52. public:
  53. PatchSolution1(const ImageInterpreter& Image) noexcept :
  54. _Image(Image),
  55. _PatchOffset{ InvalidOffset , InvalidOffset , InvalidOffset , InvalidOffset , InvalidOffset },
  56. _PatchSize{} {}
  57. PatchSolution1(const ImageInterpreter* lpImage) noexcept :
  58. _Image(*lpImage),
  59. _PatchOffset{ InvalidOffset , InvalidOffset , InvalidOffset , InvalidOffset , InvalidOffset },
  60. _PatchSize{} {}
  61. [[nodiscard]]
  62. virtual bool FindPatchOffset() noexcept override;
  63. [[nodiscard]]
  64. virtual bool CheckKey(const RSACipher& Cipher) const noexcept override;
  65. virtual void MakePatch(const RSACipher& Cipher) const override;
  66. };
  67. //
  68. // PatchSolution2 will replace the RSA public key stored in libcc.dll
  69. //
  70. class PatchSolution2 final : public PatchSolution {
  71. private:
  72. static const char KeywordMeta[0x188 + 1];
  73. static const uint8_t Keyword[0x188][5];
  74. const ImageInterpreter& _Image;
  75. size_t _PatchOffset[0x188];
  76. public:
  77. PatchSolution2(const ImageInterpreter& Image) noexcept :
  78. _Image(Image),
  79. _PatchOffset{}
  80. {
  81. for (size_t i = 0; i < _countof(_PatchOffset); ++i) {
  82. _PatchOffset[i] = InvalidOffset;
  83. }
  84. }
  85. PatchSolution2(const ImageInterpreter* lpImage) noexcept :
  86. _Image(*lpImage),
  87. _PatchOffset{}
  88. {
  89. for (size_t i = 0; i < _countof(_PatchOffset); ++i) {
  90. _PatchOffset[i] = InvalidOffset;
  91. }
  92. }
  93. [[nodiscard]]
  94. virtual bool FindPatchOffset() noexcept override;
  95. [[nodiscard]]
  96. virtual bool CheckKey(const RSACipher& Cipher) const noexcept override;
  97. virtual void MakePatch(const RSACipher& Cipher) const override;
  98. };
  99. //
  100. // PatchSolution3 will replace the RSA public key stored in libcc.dll
  101. //
  102. class PatchSolution3 final : public PatchSolution {
  103. private:
  104. using KeywordValueType = uint8_t[8];
  105. using KeywordSizeType = size_t;
  106. enum KeywordTypeEnum { IMM_DATA, STRING_DATA };
  107. struct KeywordInfo {
  108. KeywordValueType Value;
  109. KeywordSizeType Size;
  110. KeywordTypeEnum Type;
  111. bool NotRecommendedToModify;
  112. };
  113. struct PatchInfo {
  114. uint64_t OpcodeRva;
  115. void* lpOpcode;
  116. void* lpPatch;
  117. size_t cbPatch;
  118. char* lpOriginalString;
  119. char* lpReplaceString;
  120. };
  121. static const KeywordInfo Keyword[111];
  122. const ImageInterpreter& _Image;
  123. CapstoneEngine _Engine;
  124. mutable PatchInfo _Patch[111];
  125. [[nodiscard]]
  126. static bool IsPrintable(const void* p, size_t s) noexcept;
  127. [[nodiscard]]
  128. bool CheckIfMatchPattern(const cs_insn* lpInsn) const noexcept;
  129. [[nodiscard]]
  130. bool CheckIfFound(const cs_insn* lpInsn, size_t KeywordIdx) const noexcept;
  131. [[nodiscard]]
  132. PatchInfo CreatePatchPoint(const void* lpOpcode, const cs_insn* lpInsn, size_t KeywordIdx) const noexcept;
  133. [[nodiscard]]
  134. CapstoneContext GetJumpedBranch(const CapstoneContext& Bifurcation, const cs_insn* lpJxxInsn) const;
  135. [[nodiscard]]
  136. CapstoneContext SelectBranch(const CapstoneContext& NotJumpedBranch, const CapstoneContext& JumpedBranch, size_t KeywordIdx) const;
  137. public:
  138. PatchSolution3(const ImageInterpreter& Image);
  139. PatchSolution3(const ImageInterpreter* lpImage);
  140. [[nodiscard]]
  141. virtual bool FindPatchOffset() noexcept override;
  142. [[nodiscard]]
  143. virtual bool CheckKey(const RSACipher& Cipher) const noexcept override;
  144. virtual void MakePatch(const RSACipher& Cipher) const override;
  145. };
  146. }