SerialNumberGenerator.cpp 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. #include "SerialNumberGenerator.hpp"
  2. #include <Exception.hpp>
  3. #include <openssl/des.h>
  4. #include <NTSecAPI.h>
  5. #include <iostream>
  6. #pragma comment(lib, "Advapi32")
  7. #undef NKG_CURRENT_SOURCE_FILE
  8. #undef NKG_CURRENT_SOURCE_LINE
  9. #define NKG_CURRENT_SOURCE_FILE() TEXT(".\\navicat-keygen\\NavicatKeygen.cpp")
  10. #define NKG_CURRENT_SOURCE_LINE() __LINE__
  11. namespace std {
  12. #if defined(_UNICODE) || defined(UNICODE)
  13. static auto & xcin = wcin;
  14. static auto& xcout = wcout;
  15. static auto& xcerr = wcerr;
  16. #else
  17. static auto& xcin = cin;
  18. static auto& xcout = cout;
  19. static auto& xcerr = cerr;
  20. #endif
  21. }
  22. namespace nkg {
  23. SerialNumberGenerator::SerialNumberGenerator() noexcept :
  24. _Data{ 0x68 , 0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32 } {}
  25. void SerialNumberGenerator::SetLanguageSignature(NavicatLanguage Language) noexcept {
  26. switch (Language) {
  27. case NavicatLanguage::English:
  28. _Data[5] = 0xAC; // Must be 0xAC for English version.
  29. _Data[6] = 0x88; // Must be 0x88 for English version.
  30. break;
  31. case NavicatLanguage::SimplifiedChinese:
  32. _Data[5] = 0xCE; // Must be 0xCE for Simplified Chinese version.
  33. _Data[6] = 0x32; // Must be 0x32 for Simplified Chinese version.
  34. break;
  35. case NavicatLanguage::TraditionalChinese:
  36. _Data[5] = 0xAA; // Must be 0xAA for Traditional Chinese version.
  37. _Data[6] = 0x99; // Must be 0x99 for Traditional Chinese version.
  38. break;
  39. case NavicatLanguage::Japanese:
  40. _Data[5] = 0xAD; // Must be 0xAD for Japanese version. Discoverer: @dragonflylee
  41. _Data[6] = 0x82; // Must be 0x82 for Japanese version. Discoverer: @dragonflylee
  42. break;
  43. case NavicatLanguage::Polish:
  44. _Data[5] = 0xBB; // Must be 0xBB for Polish version. Discoverer: @dragonflylee
  45. _Data[6] = 0x55; // Must be 0x55 for Polish version. Discoverer: @dragonflylee
  46. break;
  47. case NavicatLanguage::Spanish:
  48. _Data[5] = 0xAE; // Must be 0xAE for Spanish version. Discoverer: @dragonflylee
  49. _Data[6] = 0x10; // Must be 0x10 for Spanish version. Discoverer: @dragonflylee
  50. break;
  51. case NavicatLanguage::French:
  52. _Data[5] = 0xFA; // Must be 0xFA for French version. Discoverer: @Deltafox79
  53. _Data[6] = 0x20; // Must be 0x20 for French version. Discoverer: @Deltafox79
  54. break;
  55. case NavicatLanguage::German:
  56. _Data[5] = 0xB1; // Must be 0xB1 for German version. Discoverer: @dragonflylee
  57. _Data[6] = 0x60; // Must be 0x60 for German version. Discoverer: @dragonflylee
  58. break;
  59. case NavicatLanguage::Korean:
  60. _Data[5] = 0xB5; // Must be 0xB5 for Korean version. Discoverer: @dragonflylee
  61. _Data[6] = 0x60; // Must be 0x60 for Korean version. Discoverer: @dragonflylee
  62. break;
  63. case NavicatLanguage::Russian:
  64. _Data[5] = 0xEE; // Must be 0xB5 for Russian version. Discoverer: @dragonflylee
  65. _Data[6] = 0x16; // Must be 0x60 for Russian version. Discoverer: @dragonflylee
  66. break;
  67. case NavicatLanguage::Portuguese:
  68. _Data[5] = 0xCD; // Must be 0xCD for Portuguese version. Discoverer: @dragonflylee
  69. _Data[6] = 0x49; // Must be 0x49 for Portuguese version. Discoverer: @dragonflylee
  70. break;
  71. default:
  72. break;
  73. }
  74. }
  75. void SerialNumberGenerator::SetLanguageSignature(BYTE LanguageSignature0, BYTE LanguageSignature1) noexcept {
  76. _Data[5] = LanguageSignature0;
  77. _Data[6] = LanguageSignature1;
  78. }
  79. void SerialNumberGenerator::SetProductSignature(NavicatProductType ProductType) noexcept {
  80. switch (ProductType) {
  81. case NavicatProductType::DataModeler:
  82. _Data[7] = 0x84;
  83. break;
  84. case NavicatProductType::Premium:
  85. _Data[7] = 0x65;
  86. break;
  87. case NavicatProductType::MySQL:
  88. _Data[7] = 0x68;
  89. break;
  90. case NavicatProductType::PostgreSQL:
  91. _Data[7] = 0x6C;
  92. break;
  93. case NavicatProductType::Oracle:
  94. _Data[7] = 0x70;
  95. break;
  96. case NavicatProductType::SQLServer:
  97. _Data[7] = 0x74;
  98. break;
  99. case NavicatProductType::SQLite:
  100. _Data[7] = 0x78;
  101. break;
  102. case NavicatProductType::MariaDB:
  103. _Data[7] = 0x7C;
  104. break;
  105. case NavicatProductType::MongoDB:
  106. _Data[7] = 0x80;
  107. break;
  108. case NavicatProductType::ReportViewer:
  109. _Data[7] = 0xb;
  110. default:
  111. break;
  112. }
  113. }
  114. void SerialNumberGenerator::SetProductSignature(BYTE ProductSignature) noexcept {
  115. _Data[7] = ProductSignature;
  116. }
  117. void SerialNumberGenerator::SetVersion(BYTE Version) {
  118. if (Version < 0x10) {
  119. _Data[8] = static_cast<BYTE>(Version << 4);
  120. } else {
  121. throw Exception(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), TEXT("Invalid version for Navicat."));
  122. }
  123. }
  124. void SerialNumberGenerator::Generate() {
  125. static const TCHAR EncodeTable[] = TEXT("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567");
  126. RtlGenRandom(_Data + 2, 3);
  127. const_DES_cblock key = { 0x64, 0xAD, 0xF3, 0x2F, 0xAE, 0xF2, 0x1A, 0x27 };
  128. DES_key_schedule schedule;
  129. DES_set_key_unchecked(&key, &schedule);
  130. DES_ecb_encrypt(
  131. reinterpret_cast<const_DES_cblock*>(_Data + 2),
  132. reinterpret_cast<const_DES_cblock*>(_Data + 2),
  133. &schedule,
  134. DES_ENCRYPT
  135. );
  136. _SerialNumberShort.resize(16);
  137. _SerialNumberShort[0] = EncodeTable[_Data[0] >> 3];
  138. _SerialNumberShort[1] = EncodeTable[(_Data[0] & 0x07) << 2 | _Data[1] >> 6];
  139. _SerialNumberShort[2] = EncodeTable[_Data[1] >> 1 & 0x1F];
  140. _SerialNumberShort[3] = EncodeTable[(_Data[1] & 0x1) << 4 | _Data[2] >> 4];
  141. _SerialNumberShort[4] = EncodeTable[(_Data[2] & 0xF) << 1 | _Data[3] >> 7];
  142. _SerialNumberShort[5] = EncodeTable[_Data[3] >> 2 & 0x1F];
  143. _SerialNumberShort[6] = EncodeTable[_Data[3] << 3 & 0x1F | _Data[4] >> 5];
  144. _SerialNumberShort[7] = EncodeTable[_Data[4] & 0x1F];
  145. _SerialNumberShort[8] = EncodeTable[_Data[5] >> 3];
  146. _SerialNumberShort[9] = EncodeTable[(_Data[5] & 0x07) << 2 | _Data[6] >> 6];
  147. _SerialNumberShort[10] = EncodeTable[_Data[6] >> 1 & 0x1F];
  148. _SerialNumberShort[11] = EncodeTable[(_Data[6] & 0x1) << 4 | _Data[7] >> 4];
  149. _SerialNumberShort[12] = EncodeTable[(_Data[7] & 0xF) << 1 | _Data[8] >> 7];
  150. _SerialNumberShort[13] = EncodeTable[_Data[8] >> 2 & 0x1F];
  151. _SerialNumberShort[14] = EncodeTable[_Data[8] << 3 & 0x1F | _Data[9] >> 5];
  152. _SerialNumberShort[15] = EncodeTable[_Data[9] & 0x1F];
  153. _SerialNumberLong = std::xstring::format(
  154. TEXT("%.4s-%.4s-%.4s-%.4s"),
  155. _SerialNumberShort.c_str() + 0,
  156. _SerialNumberShort.c_str() + 4,
  157. _SerialNumberShort.c_str() + 8,
  158. _SerialNumberShort.c_str() + 12
  159. );
  160. }
  161. [[nodiscard]]
  162. const std::xstring& SerialNumberGenerator::GetSerialNumberShort() const noexcept {
  163. return _SerialNumberShort;
  164. }
  165. [[nodiscard]]
  166. const std::xstring& SerialNumberGenerator::GetSerialNumberLong() const noexcept {
  167. return _SerialNumberLong;
  168. }
  169. void SerialNumberGenerator::ShowInConsole() const {
  170. std::xcout << TEXT("[*] Serial number:") << std::endl;
  171. std::xcout << _SerialNumberLong << std::endl;
  172. std::xcout << std::endl;
  173. }
  174. }