_tmain.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. #include "def.hpp"
  2. bool ConvertToUTF8(LPCSTR from, std::string& to) {
  3. bool bSuccess = false;
  4. int len = 0;
  5. LPWSTR lpUnicodeString = nullptr;
  6. len = MultiByteToWideChar(CP_ACP, NULL, from, -1, NULL, 0);
  7. if (len == 0)
  8. goto ON_ConvertToUTF8_0_ERROR;
  9. lpUnicodeString = reinterpret_cast<LPWSTR>(HeapAlloc(GetProcessHeap(),
  10. HEAP_ZERO_MEMORY,
  11. len * sizeof(WCHAR)));
  12. if (lpUnicodeString == nullptr)
  13. goto ON_ConvertToUTF8_0_ERROR;
  14. if (!MultiByteToWideChar(CP_ACP, NULL, from, -1, lpUnicodeString, len))
  15. goto ON_ConvertToUTF8_0_ERROR;
  16. len = WideCharToMultiByte(CP_UTF8, NULL, lpUnicodeString, -1, NULL, 0, NULL, NULL);
  17. if (len == 0)
  18. goto ON_ConvertToUTF8_0_ERROR;
  19. to.resize(len);
  20. if (!WideCharToMultiByte(CP_UTF8, NULL, lpUnicodeString, -1, to.data(), len, NULL, NULL))
  21. goto ON_ConvertToUTF8_0_ERROR;
  22. while (to.back() == 0)
  23. to.pop_back();
  24. bSuccess = true;
  25. ON_ConvertToUTF8_0_ERROR:
  26. if (lpUnicodeString)
  27. HeapFree(GetProcessHeap(), NULL, lpUnicodeString);
  28. return bSuccess;
  29. }
  30. bool ConvertToUTF8(LPCWSTR from, std::string& to) {
  31. bool bSuccess = false;
  32. int len = 0;
  33. len = WideCharToMultiByte(CP_UTF8, NULL, from, -1, NULL, 0, NULL, NULL);
  34. if (len == 0)
  35. goto ON_ConvertToUTF8_1_ERROR;
  36. to.resize(len);
  37. if (!WideCharToMultiByte(CP_UTF8, NULL, from, -1, to.data(), len, NULL, NULL))
  38. goto ON_ConvertToUTF8_1_ERROR;
  39. while (to.back() == 0)
  40. to.pop_back();
  41. bSuccess = true;
  42. ON_ConvertToUTF8_1_ERROR:
  43. return bSuccess;
  44. }
  45. bool ConvertToUTF8(std::string& str) {
  46. bool bSuccess = false;
  47. std::string temp;
  48. bSuccess = ConvertToUTF8(str.c_str(), temp);
  49. if (!bSuccess)
  50. return false;
  51. str = temp;
  52. return true;
  53. }
  54. int _tmain(int argc, TCHAR* argv[]) {
  55. if (argc != 2 && argc != 3) {
  56. _tprintf_s(TEXT("Usage:\n"));
  57. _tprintf_s(TEXT(" navicat-patcher.exe <Navicat installation path> [RSA-2048 PEM file]\n"));
  58. return 0;
  59. }
  60. RSACipher* cipher = NULL;
  61. DWORD dwMajorVer = 0;
  62. DWORD dwMinorVer = 0;
  63. cipher = RSACipher::Create();
  64. if (cipher == NULL) {
  65. _tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
  66. _tprintf_s(TEXT("RSACipher::Create failed.\n"));
  67. goto ON_tmain_ERROR;
  68. }
  69. if (!patcher::Solution0::Init(argv[1]))
  70. goto ON_tmain_ERROR;
  71. if (!patcher::Solution1::Init(argv[1]))
  72. goto ON_tmain_ERROR;
  73. if (argc == 3) {
  74. std::string PrivateKeyFileName;
  75. if (!ConvertToUTF8(argv[2], PrivateKeyFileName)) {
  76. _tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
  77. _tprintf_s(TEXT("ERROR: ConvertToUTF8 failed.\n"));
  78. goto ON_tmain_ERROR;
  79. }
  80. if (!cipher->ImportKeyFromFile<RSACipher::KeyType::PrivateKey, RSACipher::KeyFormat::PEM>(PrivateKeyFileName)) {
  81. _tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
  82. _tprintf_s(TEXT("ERROR: cipher->ImportKeyFromFile failed.\n"));
  83. goto ON_tmain_ERROR;
  84. }
  85. if (patcher::Solution0::CheckKey(cipher) == FALSE || patcher::Solution1::CheckKey(cipher) == FALSE) {
  86. _tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
  87. _tprintf_s(TEXT("ERROR: RSA private key specified cannot be used.\n"));
  88. goto ON_tmain_ERROR;
  89. }
  90. } else {
  91. _tprintf_s(TEXT("Generating new RSA private key, it may take long time.\n"));
  92. do {
  93. cipher->GenerateKey(2048);
  94. } while (!patcher::Solution0::CheckKey(cipher) || !patcher::Solution1::CheckKey(cipher)); // re-generate RSA key if one of CheckKey return FALSE
  95. if (!cipher->ExportKeyToFile<RSACipher::KeyType::PrivateKey, RSACipher::KeyFormat::NotSpecified>("RegPrivateKey.pem")) {
  96. _tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
  97. _tprintf_s(TEXT("ERROR: Failed to save RSA private key.\n"));
  98. goto ON_tmain_ERROR;
  99. }
  100. _tprintf_s(TEXT("New RSA private key has been saved to RegPrivateKey.pem.\n"));
  101. }
  102. // ------------------
  103. // begin Solution0
  104. // ------------------
  105. if (!patcher::Solution0::FindTargetFile()) {
  106. _tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
  107. _tprintf_s(TEXT("ERROR: Cannot find main program. Are you sure the path you specified is correct?\n"));
  108. goto ON_tmain_ERROR;
  109. }
  110. if (!patcher::Solution0::GetVersion(&dwMajorVer, &dwMinorVer))
  111. goto ON_tmain_ERROR;
  112. if (!patcher::Solution0::CheckFile())
  113. goto ON_tmain_ERROR;
  114. if (!patcher::Solution0::BackupFile())
  115. goto ON_tmain_ERROR;
  116. if (!patcher::Solution0::Do(cipher))
  117. goto ON_tmain_ERROR;
  118. _tprintf_s(TEXT("RSA public key has been replaced by\n"));
  119. printf_s("%s\n", cipher->ExportKeyString<RSACipher::KeyType::PublicKey, RSACipher::KeyFormat::PEM>().c_str());
  120. _tprintf_s(TEXT("Solution0 has been done successfully.\n"));
  121. _tprintf_s(TEXT("\n"));
  122. // for ver <= 12.0.24
  123. if (dwMajorVer == 0x000c0000 && dwMinorVer < 0x00180000)
  124. goto ON_tmain_ERROR; // you don't need Solution1 patch.
  125. // ------------------
  126. // begin Solution1
  127. // ------------------
  128. if (!patcher::Solution1::FindTargetFile()) {
  129. _tprintf_s(TEXT("@%s LINE: %u\n"), TEXT(__FUNCTION__), __LINE__);
  130. _tprintf_s(TEXT("ERROR: Cannot find libcc.dll. Are you sure the path you specified is correct?\n"));
  131. goto ON_tmain_ERROR;
  132. }
  133. if (!patcher::Solution1::FindOffset())
  134. goto ON_tmain_ERROR;
  135. if (!patcher::Solution1::BackupFile())
  136. goto ON_tmain_ERROR;
  137. if (!patcher::Solution1::Do(cipher))
  138. goto ON_tmain_ERROR;
  139. _tprintf_s(TEXT("Solution1 has been done successfully.\n"));
  140. _tprintf_s(TEXT("\n"));
  141. ON_tmain_ERROR:
  142. patcher::Solution1::Finalize();
  143. patcher::Solution0::Finalize();
  144. delete cipher;
  145. return 0;
  146. }