Move some functions to Helper.cpp

This commit is contained in:
Double Sine 2018-09-22 11:58:31 +08:00
parent ac271858f0
commit 28c2cfa290
No known key found for this signature in database
GPG Key ID: 44460E4F43EA8633
3 changed files with 309 additions and 41 deletions

View File

@ -1,13 +0,0 @@
// to avoid "AES_KEY" definaition conflict
#include "NavicatCrypto/NavicatCrypto.hpp"
namespace patcher {
static Navicat11Crypto cipher("23970790", 8);
std::string EncryptPublicKey(const char* public_key, size_t len) {
auto&& temp = cipher.EncryptString(public_key, len);
return std::string(temp.begin(), temp.end());
}
}

153
navicat-patcher/Helper.cpp Normal file
View File

@ -0,0 +1,153 @@
#include "def.hpp"
#include "NavicatCrypto.hpp"
namespace Helper {
static Navicat11Crypto NavicatCipher("23970790", 8);
std::string EncryptPublicKey(const std::string& PublicKeyString) {
return NavicatCipher.EncryptString(PublicKeyString.c_str(),
PublicKeyString.length());
}
bool ConvertToUTF8(LPCSTR from, std::string& to) {
bool bSuccess = false;
int RequireLength = 0;
LPWSTR lpUnicodeString = nullptr;
RequireLength = MultiByteToWideChar(CP_ACP, NULL, from, -1, nullptr, 0);
if (RequireLength == 0)
goto ON_ConvertToUTF8_0_ERROR;
lpUnicodeString = reinterpret_cast<LPWSTR>(HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
RequireLength * sizeof(WCHAR)));
if (lpUnicodeString == nullptr)
goto ON_ConvertToUTF8_0_ERROR;
if (!MultiByteToWideChar(CP_ACP, NULL, from, -1, lpUnicodeString, RequireLength))
goto ON_ConvertToUTF8_0_ERROR;
RequireLength = WideCharToMultiByte(CP_UTF8, NULL, lpUnicodeString, -1, nullptr, 0, nullptr, nullptr);
if (RequireLength == 0)
goto ON_ConvertToUTF8_0_ERROR;
to.resize(RequireLength);
if (!WideCharToMultiByte(CP_UTF8, NULL, lpUnicodeString, -1, to.data(), RequireLength, nullptr, nullptr))
goto ON_ConvertToUTF8_0_ERROR;
while (to.back() == 0)
to.pop_back();
bSuccess = true;
ON_ConvertToUTF8_0_ERROR:
if (lpUnicodeString)
HeapFree(GetProcessHeap(), NULL, lpUnicodeString);
return bSuccess;
}
bool ConvertToUTF8(LPCWSTR from, std::string& to) {
bool bSuccess = false;
int RequireLength = 0;
RequireLength = WideCharToMultiByte(CP_UTF8, NULL, from, -1, nullptr, 0, nullptr, nullptr);
if (RequireLength == 0)
goto ON_ConvertToUTF8_1_ERROR;
to.resize(RequireLength);
if (!WideCharToMultiByte(CP_UTF8, NULL, from, -1, to.data(), RequireLength, nullptr, nullptr))
goto ON_ConvertToUTF8_1_ERROR;
while (to.back() == 0)
to.pop_back();
bSuccess = true;
ON_ConvertToUTF8_1_ERROR:
return bSuccess;
}
bool ConvertToUTF8(std::string& str) {
bool bSuccess = false;
std::string temp;
bSuccess = ConvertToUTF8(str.c_str(), temp);
if (bSuccess)
str = temp;
return bSuccess;
}
void ErrorReport(LPCTSTR at, UINT line, LPCTSTR msg) {
_tprintf_s(TEXT("@%s LINE: %u\n"), at, line);
_tprintf_s(TEXT("%s\n"), msg);
}
void ErrorReport(LPCTSTR at, UINT line, LPCTSTR msg, DWORD err_code) {
_tprintf_s(TEXT("@%s LINE: %u\n"), at, line);
_tprintf_s(TEXT("%s CODE: 0x%08X\n"), msg, err_code);
}
template<typename _Type>
static __forceinline bool ProbeForRead(const void* p, void* out) {
__try {
*reinterpret_cast<_Type*>(out) = *reinterpret_cast<const _Type*>(p);
return true;
} __except (1) {
return false;
}
}
void PrintMemory(const void* a, const void* b, const void* base) {
const uint8_t* start = reinterpret_cast<const uint8_t*>(a);
const uint8_t* end = reinterpret_cast<const uint8_t*>(b);
const uint8_t* base_ptr = reinterpret_cast<const uint8_t*>(base);
if (start >= end)
return;
while (reinterpret_cast<uintptr_t>(start) % 16)
start--;
while (reinterpret_cast<uintptr_t>(start) % 16)
end++;
while (start < end) {
uint16_t value[16] = {};
if (base_ptr)
_tprintf(TEXT("+0x%p "), reinterpret_cast<const void*>(start - base_ptr));
else
_tprintf(TEXT("0x%p "), start);
for (int i = 0; i < 16; ++i) {
if (ProbeForRead<uint8_t>(start + i, value + i)) {
_tprintf(TEXT("%02x "), value[i]);
} else {
value[i] = -1;
_tprintf(TEXT("?? "));
}
}
_tprintf(TEXT(" "));
for (int i = 0; i < 16; ++i) {
if (value[i] < 0x20) {
_tprintf(TEXT("."));
} else if (value[i] > 0x7e) {
_tprintf(TEXT("."));
} else {
_tprintf(TEXT("%c"), value[i]);
}
}
_tprintf(TEXT("\n"));
start += 0x10;
}
}
}

View File

@ -2,41 +2,169 @@
#include <tchar.h>
#include <windows.h>
#include <string>
#include "RSACipher.hpp"
#pragma comment(lib, "version.lib") // GetFileVersionInfoSize, GetFileVersionInfo, VerQueryValue are in this lib
namespace std {
#ifdef UNICODE
typedef wstring Tstring;
namespace std { typedef wstring Tstring; }
#else
typedef string Tstring;
#endif // UNICODE
namespace std { typedef string Tstring; }
#endif
namespace Helper {
std::string EncryptPublicKey(const std::string& PublicKeyString);
bool ConvertToUTF8(LPCSTR from, std::string& to);
bool ConvertToUTF8(LPCWSTR from, std::string& to);
bool ConvertToUTF8(std::string& str);
void ErrorReport(LPCTSTR at, UINT line, LPCTSTR msg);
void ErrorReport(LPCTSTR at, UINT line, LPCTSTR msg, DWORD err_code);
void PrintMemory(const void* a, const void* b, const void* base);
}
namespace patcher {
#define REPORT_ERROR(msg) Helper::ErrorReport(TEXT(__FUNCTION__), __LINE__, TEXT(msg))
#define REPORT_ERROR_WITH_CODE(msg, err_code) Helper::ErrorReport(TEXT(__FUNCTION__), __LINE__, TEXT(msg), (err_code))
std::string EncryptPublicKey(const char* public_key, size_t len);
#define PRINT_MESSAGE(msg) _tprintf_s(TEXT("%s\n"), TEXT(msg))
#define PRINT_LPCTSTR(msg) _tprintf_s(TEXT("%s\n"), (msg))
#define PRINT_LPCSTR(msg) printf_s("%s\n", (msg))
#define PRINT_LPCWSTR(msg) wprintf_s(L"%s\n", (msg))
namespace Solution0 {
BOOL Init(const std::Tstring& Path);
BOOL CheckKey(RSACipher* cipher);
BOOL FindTargetFile();
BOOL CheckFile();
BOOL BackupFile();
BOOL Do(RSACipher* cipher);
BOOL GetVersion(LPDWORD lpMajorVer, LPDWORD lpMinorVer);
VOID Finalize();
}
namespace Patcher {
namespace Solution1 {
BOOL Init(const std::Tstring& Path);
BOOL CheckKey(RSACipher* cipher);
BOOL FindTargetFile();
BOOL FindOffset();
BOOL BackupFile();
BOOL Do(RSACipher* cipher);
VOID Finalize();
}
// Solution0 will replace the RSA public key stored in main application.
class Solution0 {
private:
static const char Keyword[461];
static constexpr int KeywordLength = 460;
}
std::Tstring InstallationPath;
std::Tstring MainAppName;
HANDLE MainAppHandle;
HANDLE MainAppMappingHandle;
PVOID MainAppMappingView;
off_t PatchOffset;
public:
Solution0() : InstallationPath(),
MainAppName(),
MainAppHandle(INVALID_HANDLE_VALUE),
MainAppMappingHandle(NULL),
MainAppMappingView(nullptr),
PatchOffset(-1) {}
BOOL SetPath(const std::Tstring& Path);
// Solution0 does not have any requirements for RSA-2048 key
BOOL CheckKey(RSACipher* cipher) const;
// Return error code
// It may return
// ERROR_SUCCESS (target has been set successfully)
// ERROR_FILE_NOT_FOUND (try another name)
// ERROR_ACCESS_DENIED (you need Administrator privilege)
// ...
DWORD TryFile(const std::Tstring& MainAppName);
// Return error code
// It may return
// ERROR_SUCCESS (target has been mapped successfully)
// ...
DWORD MapFile();
// Return TRUE if found, other return FALSE
BOOL FindPatchOffset();
// Return error code
// It may return
// ERROR_SUCCESS (file has been backed up successfully)
// ERROR_FILE_EXISTS (you should remove backup file first)
// ERROR_ACCESS_DENIED (you need Administrator privilege)
// ...
DWORD BackupFile();
// Make a patch based on RSA private key
// Return TRUE if success, otherwise return FALSE
BOOL MakePatch(RSACipher* cipher);
// Return error code
// Return ERROR_SUCCESS if success
DWORD GetMainAppVersion(LPDWORD lpMajorVer, LPDWORD lpMinorVer);
const std::Tstring& GetMainAppName();
// Close handle returned by CreateFile with a implicit call towards ReleaseMap
void ReleaseFile();
// Unmap view returned by MapViewOfFile and
// close handle returned by CreateFileMapping
void ReleaseMap();
~Solution0();
};
// Solution0 will replace the RSA public key stored in libcc.dll
class Solution1 {
private:
static const char* Keywords[5];
static const int KeywordsLength[5];
std::Tstring InstallationPath;
std::Tstring LibccName;
HANDLE LibccHandle;
HANDLE LibccMappingHandle;
PVOID LibccMappingView;
off_t PatchOffsets[5];
public:
Solution1() : InstallationPath(),
LibccName(),
LibccHandle(INVALID_HANDLE_VALUE),
LibccMappingHandle(NULL),
LibccMappingView(nullptr),
PatchOffsets{-1, -1, -1, -1, -1} {}
BOOL SetPath(const std::Tstring& Path);
// Solution0 does not have any requirements for RSA-2048 key
BOOL CheckKey(RSACipher* cipher) const;
// Return error code
// It may return
// ERROR_SUCCESS (target has been set successfully)
// ERROR_FILE_NOT_FOUND (try another name)
// ERROR_ACCESS_DENIED (you need Administrator privilege)
// ...
DWORD TryFile(const std::Tstring& MainAppName);
// Return error code
// It may return
// ERROR_SUCCESS (target has been mapped successfully)
// ...
DWORD MapFile();
// Return TRUE if found, other return FALSE
BOOL FindPatchOffset();
// Return error code
// It may return
// ERROR_SUCCESS (file has been backed up successfully)
// ERROR_FILE_EXISTS (you should remove backup file first)
// ERROR_ACCESS_DENIED (you need Administrator privilege)
// ...
DWORD BackupFile();
// Make a patch based on RSA private key
// Return TRUE if success, otherwise return FALSE
BOOL MakePatch(RSACipher* cipher);
// Close handle returned by CreateFile with a implicit call towards ReleaseMap
void ReleaseFile();
// Unmap view returned by MapViewOfFile and
// close handle returned by CreateFileMapping
void ReleaseMap();
~Solution1();
};
}