PatchSolutions.hpp 6.6 KB

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