Refactor helper functions

This commit is contained in:
Double Sine 2019-01-14 14:29:14 +08:00
parent 072734f041
commit f7618bd3bc
No known key found for this signature in database
GPG Key ID: 44460E4F43EA8633
3 changed files with 243 additions and 102 deletions

View File

@ -1,94 +1,102 @@
#include "def.hpp"
#include "NavicatCrypto.hpp"
#include <tchar.h>
#include "Helper.hpp"
#include "ResourceGuard.hpp"
#include "Exceptions.hpp"
namespace Helper {
static Navicat11Crypto NavicatCipher("23970790", 8);
std::string EncryptPublicKey(const std::string& PublicKeyString) {
return NavicatCipher.EncryptString(PublicKeyString.c_str(),
PublicKeyString.length());
std::string ConvertToUTF8(PCSTR From, DWORD CodePage) {
std::string result;
int RequiredLength = 0;
ResourceGuard<CppDynamicArrayTraits<WCHAR>> pszUnicodeString;
RequiredLength = MultiByteToWideChar(CP_ACP,
NULL,
From,
-1,
nullptr,
0);
if (RequiredLength == 0)
throw Patcher::SystemError(__BASE_FILE__, __LINE__, GetLastError(),
"MultiByteToWideChar fails.");
pszUnicodeString.TakeHoldOf(new WCHAR[RequiredLength]());
if (!MultiByteToWideChar(CP_ACP,
NULL,
From,
-1,
pszUnicodeString,
RequiredLength))
throw Patcher::SystemError(__BASE_FILE__, __LINE__, GetLastError(),
"MultiByteToWideChar fails.");
RequiredLength = WideCharToMultiByte(CP_UTF8,
NULL,
pszUnicodeString,
-1,
nullptr,
0,
nullptr,
nullptr);
if (RequiredLength == 0)
throw Patcher::SystemError(__BASE_FILE__, __LINE__, GetLastError(),
"WideCharToMultiByte fails.");
result.resize(RequiredLength);
if (!WideCharToMultiByte(CP_UTF8,
NULL,
pszUnicodeString,
-1,
result.data(),
RequiredLength,
nullptr,
nullptr))
throw Patcher::SystemError(__BASE_FILE__, __LINE__, GetLastError(),
"WideCharToMultiByte fails.");
while (result.back() == 0)
result.pop_back();
return result;
}
bool ConvertToUTF8(LPCSTR from, std::string& to) {
bool bSuccess = false;
int RequireLength = 0;
LPWSTR lpUnicodeString = nullptr;
std::string ConvertToUTF8(PCWSTR From) {
std::string result;
int RequiredLength = 0;
RequireLength = MultiByteToWideChar(CP_ACP, NULL, from, -1, nullptr, 0);
if (RequireLength == 0)
goto ON_ConvertToUTF8_0_ERROR;
RequiredLength = WideCharToMultiByte(CP_UTF8,
NULL,
From,
-1,
nullptr,
0,
nullptr,
nullptr);
if (RequiredLength == 0)
throw Patcher::SystemError(__BASE_FILE__, __LINE__, GetLastError(),
"WideCharToMultiByte fails.");
lpUnicodeString = reinterpret_cast<LPWSTR>(HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
RequireLength * sizeof(WCHAR)));
if (lpUnicodeString == nullptr)
goto ON_ConvertToUTF8_0_ERROR;
result.resize(RequiredLength);
if (!MultiByteToWideChar(CP_ACP, NULL, from, -1, lpUnicodeString, RequireLength))
goto ON_ConvertToUTF8_0_ERROR;
if (!WideCharToMultiByte(CP_UTF8,
NULL,
From,
-1,
result.data(),
RequiredLength,
nullptr,
nullptr))
throw Patcher::SystemError(__BASE_FILE__, __LINE__, GetLastError(),
"WideCharToMultiByte fails.");
RequireLength = WideCharToMultiByte(CP_UTF8, NULL, lpUnicodeString, -1, nullptr, 0, nullptr, nullptr);
if (RequireLength == 0)
goto ON_ConvertToUTF8_0_ERROR;
while (result.back() == 0)
result.pop_back();
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);
return result;
}
//
@ -109,7 +117,7 @@ namespace Helper {
// Print memory data in [from, to) at least
// If `base` is not nullptr, print address as offset. Otherwise, as absolute address.
// NOTICE:
// `base` must >= `from`
// `base` must <= `from`
//
void PrintMemory(const void* from, const void* to, const void* base) {
const uint8_t* start = reinterpret_cast<const uint8_t*>(from);
@ -160,26 +168,4 @@ namespace Helper {
}
}
PIMAGE_SECTION_HEADER ImageSectionHeader(PVOID lpBase, LPCSTR lpSectionName) {
PIMAGE_DOS_HEADER pFileHeader = NULL;
PIMAGE_NT_HEADERS pNtHeader = NULL;
IMAGE_SECTION_HEADER* pSectionHeaders = NULL;
pFileHeader = (IMAGE_DOS_HEADER*)lpBase;
if (pFileHeader->e_magic != IMAGE_DOS_SIGNATURE)
return NULL;
pNtHeader = (IMAGE_NT_HEADERS*)((BYTE*)lpBase + pFileHeader->e_lfanew);
if (pNtHeader->Signature != IMAGE_NT_SIGNATURE)
return NULL;
pSectionHeaders = (IMAGE_SECTION_HEADER*)((BYTE*)pNtHeader +
offsetof(IMAGE_NT_HEADERS, OptionalHeader) +
pNtHeader->FileHeader.SizeOfOptionalHeader);
for (WORD i = 0; i < pNtHeader->FileHeader.NumberOfSections; ++i)
if (_stricmp((const char*)pSectionHeaders[i].Name, lpSectionName) == 0)
return pSectionHeaders + i;
return NULL;
}
}

View File

@ -0,0 +1,65 @@
#pragma once
#include <windows.h>
#include <string>
#include <sys/types.h>
#include "NavicatCrypto.hpp"
namespace Helper {
extern Navicat11Crypto NavicatCipher;
//
// Print memory data in [from, to) at least
// If `base` is not nullptr, print address as offset. Otherwise, as absolute address.
// NOTICE:
// `base` must <= `from`
//
void PrintMemory(const void* from, const void* to, const void* base = nullptr);
template<typename _Type, bool _Ascending = true>
void QuickSort(_Type* pArray, off_t begin, off_t end) {
if (end - begin <= 1)
return;
off_t i = begin;
off_t j = end - 1;
_Type seperator = static_cast<_Type&&>(pArray[begin]);
while (i < j) {
if (_Ascending) {
while (i < j && seperator <= pArray[j])
--j;
if (i < j)
pArray[i++] = static_cast<_Type&&>(pArray[j]);
while (i < j && pArray[i] <= seperator)
++i;
if (i < j)
pArray[j--] = static_cast<_Type&&>(pArray[i]);
} else {
while (i < j && seperator >= pArray[j])
--j;
if (i < j)
pArray[i++] = static_cast<_Type&&>(pArray[j]);
while (i < j && pArray[i] >= seperator)
++i;
if (i < j)
pArray[j--] = static_cast<_Type&&>(pArray[i]);
}
}
pArray[i] = static_cast<_Type&&>(seperator);
QuickSort<_Type, _Ascending>(pArray, begin, i);
QuickSort<_Type, _Ascending>(pArray, i + 1, end);
}
std::string ConvertToUTF8(PCSTR From, DWORD CodePage = CP_ACP);
std::string ConvertToUTF8(PCWSTR From);
}

View File

@ -0,0 +1,90 @@
#pragma once
#include <type_traits>
#include <windows.h>
inline
PIMAGE_DOS_HEADER GetImageDosHeader(PVOID pImageBase) {
return reinterpret_cast<PIMAGE_DOS_HEADER>(pImageBase);
}
inline
PIMAGE_NT_HEADERS GetImageNtHeaders(PVOID pImageBase) {
char* pImageBytes = reinterpret_cast<char*>(pImageBase);
return reinterpret_cast<PIMAGE_NT_HEADERS>(
pImageBytes + GetImageDosHeader(pImageBase)->e_lfanew
);
}
inline
PIMAGE_FILE_HEADER GetImageCoffHeader(PVOID pImageBase) {
return &GetImageNtHeaders(pImageBase)->FileHeader;
}
inline
PIMAGE_OPTIONAL_HEADER GetImageOptionalHeader(PVOID pImageBase) {
return &GetImageNtHeaders(pImageBase)->OptionalHeader;
}
inline
PIMAGE_SECTION_HEADER GetSectionHeaderList(PVOID pImageBase) {
return
reinterpret_cast<PIMAGE_SECTION_HEADER>(
reinterpret_cast<char*>(&GetImageNtHeaders(pImageBase)->OptionalHeader) +
GetImageNtHeaders(pImageBase)->FileHeader.SizeOfOptionalHeader
);
}
inline
PIMAGE_SECTION_HEADER GetSectionHeaderByName(PVOID pImageBase, LPCSTR lpSectionName) {
PIMAGE_NT_HEADERS pNtHeader = GetImageNtHeaders(pImageBase);
PIMAGE_SECTION_HEADER pSectionHeaders = GetSectionHeaderList(pImageBase);
for (WORD i = 0; i < pNtHeader->FileHeader.NumberOfSections; ++i)
if (_stricmp(reinterpret_cast<char*>(pSectionHeaders[i].Name), lpSectionName) == 0)
return &pSectionHeaders[i];
return NULL;
}
inline
PIMAGE_SECTION_HEADER GetSectionHeaderFromRva(SIZE_T Rva, PVOID pImageBase) {
PIMAGE_NT_HEADERS pNtHeader = GetImageNtHeaders(pImageBase);
PIMAGE_SECTION_HEADER pSectionHeaderList = GetSectionHeaderList(pImageBase);
for (DWORD i = 0; i < pNtHeader->FileHeader.NumberOfSections; ++i) {
if (pSectionHeaderList[i].VirtualAddress <= Rva &&
Rva < pSectionHeaderList[i].VirtualAddress + pSectionHeaderList[i].SizeOfRawData)
{
return &pSectionHeaderList[i];
}
}
return NULL;
}
inline
bool IsRvaInSection(SIZE_T Rva, PIMAGE_SECTION_HEADER pSectionHeader) {
if (pSectionHeader->VirtualAddress <= Rva &&
Rva < pSectionHeader->VirtualAddress + pSectionHeader->SizeOfRawData)
{
return true;
} else {
return false;
}
}
template<typename __ReturnType = PVOID>
__ReturnType RvaToPointer(SIZE_T Rva, PVOID pImageBase, PIMAGE_SECTION_HEADER pHintSection = NULL) {
static_assert(std::is_pointer<__ReturnType>::value);
if (pHintSection == NULL || IsRvaInSection(Rva, pHintSection) == false)
pHintSection = GetSectionHeaderFromRva(Rva, pImageBase);
if (pHintSection == NULL) {
return NULL;
} else {
PIMAGE_NT_HEADERS pNtHeader = GetImageNtHeaders(pImageBase);
return reinterpret_cast<__ReturnType>(
reinterpret_cast<char*>(pImageBase) + pHintSection->PointerToRawData +
(Rva - pHintSection->VirtualAddress)
);
}
}