123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- #include <tchar.h>
- #include <windows.h>
- #include "Exception.hpp"
- #include "PatchSolution.hpp"
- #include "Helper.hpp"
- #undef __BASE_FILE__
- #define __BASE_FILE__ "_tmain.cpp"
- #define PRINT_MESSAGE_LITERAL(m) _putts(TEXT(m))
- #define PRINT_PTSTR(m) _putts(m)
- #define PRINT_PCSTR(m) puts(m)
- #define PRINT_PCWSTR(m) _putws(m)
- String InstallationPath;
- String MainAppName;
- String LibccName = TEXT("libcc.dll");
- static void Welcome() {
- PRINT_MESSAGE_LITERAL("***************************************************");
- PRINT_MESSAGE_LITERAL("* Navicat Patcher by @DoubleLabyrinth *");
- _tprintf_s(TEXT("* Release date: %-24s*\n"), TEXT(__DATE__));
- PRINT_MESSAGE_LITERAL("***************************************************");
- PRINT_MESSAGE_LITERAL("");
- PRINT_MESSAGE_LITERAL("Press Enter to continue or Ctrl + C to abort.");
- _gettchar();
- }
- static void Help() {
- PRINT_MESSAGE_LITERAL("Usage:");
- PRINT_MESSAGE_LITERAL(" navicat-patcher.exe <Navicat installation path> [RSA-2048 PEM file]");
- }
- static void SetPath(PTSTR pszPath) {
- DWORD Attr;
- Attr = GetFileAttributes(pszPath);
- if (Attr == INVALID_FILE_ATTRIBUTES)
- throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
- "GetFileAttributes fails.");
- if ((Attr & FILE_ATTRIBUTE_DIRECTORY) == 0)
- throw Exception(__BASE_FILE__, __LINE__,
- "Path does not point to a directory.");
- InstallationPath = pszPath;
- if (InstallationPath.back() != TEXT('\\') && InstallationPath.back() != TEXT('/'))
- InstallationPath.push_back(TEXT('/')); // for Linux compatible
- }
- static void BackupFile(const String& From, const String& To) {
- if (::CopyFile(From.c_str(), To.c_str(), TRUE) == FALSE)
- throw SystemError(__BASE_FILE__, __LINE__, GetLastError(),
- "CopyFile fails.");
- }
- static void LoadKey(RSACipher* pCipher, PTSTR FileName,
- PatchSolution* pSolution0,
- PatchSolution* pSolution1,
- PatchSolution* pSolution2,
- PatchSolution* pSolution3) {
- if (FileName) {
- std::string PrivateKeyFileName = Helper::ConvertToUTF8(FileName);
- pCipher->ImportKeyFromFile<RSACipher::KeyType::PrivateKey, RSACipher::KeyFormat::PEM>(PrivateKeyFileName);
- if (pSolution0 && !pSolution0->CheckKey(pCipher) ||
- pSolution1 && !pSolution1->CheckKey(pCipher) ||
- pSolution2 && !pSolution2->CheckKey(pCipher) ||
- pSolution3 && !pSolution3->CheckKey(pCipher))
- throw Exception(__BASE_FILE__, __LINE__,
- "The RSA private key you provide cannot be used.");
- } else {
- PRINT_MESSAGE_LITERAL("MESSAGE: Generating new RSA private key, it may take a long time.");
- do {
- pCipher->GenerateKey(2048);
- } while (pSolution0 && !pSolution0->CheckKey(pCipher) ||
- pSolution1 && !pSolution1->CheckKey(pCipher) ||
- pSolution2 && !pSolution2->CheckKey(pCipher) ||
- pSolution3 && !pSolution3->CheckKey(pCipher)); // re-generate RSA key if CheckKey return false
- pCipher->ExportKeyToFile<RSACipher::KeyType::PrivateKey, RSACipher::KeyFormat::NotSpecified>("RegPrivateKey.pem");
- PRINT_MESSAGE_LITERAL("MESSAGE: New RSA private key has been saved to RegPrivateKey.pem.");
- }
- std::string PublicKeyString = pCipher->ExportKeyString<RSACipher::KeyType::PublicKey, RSACipher::KeyFormat::PEM>();
- PRINT_MESSAGE_LITERAL("");
- PRINT_MESSAGE_LITERAL("Your RSA public key:");
- PRINT_PCSTR(PublicKeyString.c_str());
- }
- static void ExceptionReport(const Exception& e) noexcept {
- printf_s("ERROR: @ %s - Line %d\n", e.SourceFile(), e.SourceLine());
- if (e.HasErrorCode()) {
- const char* aa = e.ErrorString();
- printf_s("ErrorCode = 0x%08lx\n", e.ErrorCode());
- printf_s("ErrorString: %s\n", e.ErrorString());
- } else {
- printf_s("%s\n", e.CustomMessage());
- }
- }
- int _tmain(int argc, PTSTR argv[]) {
- if (argc != 2 && argc != 3) {
- Help();
- return 0;
- }
- Welcome();
- ResourceGuard<CppObjectTraits<RSACipher>> pCipher;
- ResourceGuard<CppObjectTraits<FileMapper>> pMainExe;
- ResourceGuard<CppObjectTraits<FileMapper>> pLibccDLL;
- ResourceGuard<CppObjectTraits<PatchSolution>> pSolution0;
- ResourceGuard<CppObjectTraits<PatchSolution>> pSolution1;
- ResourceGuard<CppObjectTraits<PatchSolution>> pSolution2;
- ResourceGuard<CppObjectTraits<PatchSolution>> pSolution3;
- pCipher.TakeHoldOf(new RSACipher());
- try {
- SetPath(argv[1]);
- } catch (Exception& e) {
- ExceptionReport(e);
- PRINT_MESSAGE_LITERAL("Are you sure the path you specified is correct?");
- PRINT_MESSAGE_LITERAL("The path you specified:");
- PRINT_PTSTR(argv[1]);
- return 0;
- }
- // -----------
- // decide which PatchSolution
- // -----------
- do {
- pLibccDLL.TakeHoldOf(new FileMapper());
- try {
- pLibccDLL.GetHandle()->MapFile(InstallationPath + TEXT("libcc.dll"));
- pSolution3.TakeHoldOf(new PatchSolution3());
- pSolution3.GetHandle()->SetFile(pLibccDLL);
- if (pSolution3.GetHandle()->FindPatchOffset() == false) {
- PRINT_MESSAGE_LITERAL("MESSAGE: PatchSolution3 will be omitted.");
- pSolution3.Release();
- } else {
- break;
- }
- pSolution2.TakeHoldOf(new PatchSolution2());
- pSolution2.GetHandle()->SetFile(pLibccDLL);
- if (pSolution2.GetHandle()->FindPatchOffset() == false) {
- PRINT_MESSAGE_LITERAL("MESSAGE: PatchSolution2 will be omitted.");
- pSolution2.Release();
- } else {
- break;
- }
- pSolution1.TakeHoldOf(new PatchSolution1());
- pSolution1.GetHandle()->SetFile(pLibccDLL);
- if (pSolution1.GetHandle()->FindPatchOffset() == false) {
- PRINT_MESSAGE_LITERAL("MESSAGE: PatchSolution1 will be omitted.");
- pSolution2.Release();
- } else {
- break;
- }
- pLibccDLL.Release();
- } catch (Exception& e) {
- if (e.HasErrorCode() && e.ErrorCode() == ERROR_FILE_NOT_FOUND) {
- PRINT_MESSAGE_LITERAL("MESSAGE: libcc.dll is not found.");
- PRINT_MESSAGE_LITERAL(" PatchSolution1 will be omitted.");
- PRINT_MESSAGE_LITERAL(" PatchSolution2 will be omitted.");
- PRINT_MESSAGE_LITERAL(" PatchSolution3 will be omitted.");
- pLibccDLL.Release();
- } else {
- ExceptionReport(e);
- if (e.HasErrorCode() && e.ErrorCode() == ERROR_ACCESS_DENIED)
- PRINT_MESSAGE_LITERAL("Please re-run with Administrator privilege.");
- return 0;
- }
- }
- pMainExe.TakeHoldOf(new FileMapper());
- do {
- try {
- pMainExe.GetHandle()->MapFile(InstallationPath + TEXT("Navicat.exe"));
- MainAppName = TEXT("Navicat.exe");
- break;
- } catch (Exception& e) {
- if (!e.HasErrorCode() || e.ErrorCode() != ERROR_FILE_NOT_FOUND) {
- ExceptionReport(e);
- if (e.HasErrorCode() && e.ErrorCode() == ERROR_ACCESS_DENIED)
- PRINT_MESSAGE_LITERAL("Please re-run with Administrator privilege.");
- return 0;
- }
- }
- try {
- pMainExe.GetHandle()->MapFile(InstallationPath + TEXT("Modeler.exe"));
- MainAppName = TEXT("Modeler.exe");
- break;
- } catch (Exception& e) {
- if (!e.HasErrorCode() || e.ErrorCode() != ERROR_FILE_NOT_FOUND) {
- ExceptionReport(e);
- if (e.HasErrorCode() && e.ErrorCode() == ERROR_ACCESS_DENIED)
- PRINT_MESSAGE_LITERAL("Please re-run with Administrator privilege.");
- return 0;
- }
- }
- try {
- pMainExe.GetHandle()->MapFile(InstallationPath + TEXT("Rviewer.exe"));
- MainAppName = TEXT("Rviewer.exe");
- break;
- } catch (Exception& e) {
- if (!e.HasErrorCode() || e.ErrorCode() != ERROR_FILE_NOT_FOUND) {
- ExceptionReport(e);
- if (e.HasErrorCode() && e.ErrorCode() == ERROR_ACCESS_DENIED)
- PRINT_MESSAGE_LITERAL("Please re-run with Administrator privilege.");
- return 0;
- }
- }
- pMainExe.Release();
- } while (false);
- } while (false);
- // -------------
- // LoadKey
- // BackupFile
- // MakePatch
- // -------------
- try {
- LoadKey(pCipher, argc == 3 ? argv[2] : nullptr,
- pSolution0,
- pSolution1,
- pSolution2,
- pSolution3);
- if (pLibccDLL) {
- BackupFile(InstallationPath + LibccName, InstallationPath + LibccName + TEXT(".backup"));
- } else {
- BackupFile(InstallationPath + MainAppName, InstallationPath + MainAppName + TEXT(".backup"));
- }
- if (pSolution3.IsValid())
- pSolution3.GetHandle()->MakePatch(pCipher);
- if (pSolution2.IsValid())
- pSolution2.GetHandle()->MakePatch(pCipher);
- if (pSolution1.IsValid())
- pSolution1.GetHandle()->MakePatch(pCipher);
- if (pSolution0.IsValid())
- pSolution0.GetHandle()->MakePatch(pCipher);
- } catch (Exception& e) {
- ExceptionReport(e);
- if (e.HasErrorCode() && e.ErrorCode() == ERROR_FILE_EXISTS) {
- if (pLibccDLL.IsValid()) {
- _tprintf_s(TEXT("The backup of %s has been found.\n"), LibccName.c_str());
- _tprintf_s(TEXT("Please remove %s.backup in Navicat installation path if you're sure %s has not been patched.\n"),
- LibccName.c_str(),
- LibccName.c_str());
- _tprintf_s(TEXT("Otherwise please restore %s by %s.backup and remove %s.backup then try again.\n"),
- LibccName.c_str(),
- LibccName.c_str(),
- LibccName.c_str());
- } else {
- _tprintf_s(TEXT("The backup of %s has been found.\n"), MainAppName.c_str());
- _tprintf_s(TEXT("Please remove %s.backup in Navicat installation path if you're sure %s has not been patched.\n"),
- MainAppName.c_str(),
- MainAppName.c_str());
- _tprintf_s(TEXT("Otherwise please restore %s by %s.backup and remove %s.backup then try again.\n"),
- MainAppName.c_str(),
- MainAppName.c_str(),
- MainAppName.c_str());
- }
- }
- return 0;
- }
- PRINT_MESSAGE_LITERAL("");
- PRINT_MESSAGE_LITERAL("MESSAGE: Patch has been done successfully.");
- return 0;
- }
|