Skip to content
This repository has been archived by the owner on Jun 2, 2023. It is now read-only.

Commit

Permalink
#8 Add support for unencrypted archives at the media storage level
Browse files Browse the repository at this point in the history
  • Loading branch information
www committed Apr 24, 2022
1 parent 6b5289f commit ef2511b
Show file tree
Hide file tree
Showing 25 changed files with 643 additions and 589 deletions.
20 changes: 20 additions & 0 deletions Common/Directory.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
#include "stdafx.h"
#include "Directory.h"

using namespace std;

void Directory::Create(const std::wstring& folderPath)
{
CreateDirectory(folderPath.c_str(), nullptr);
}

vector<wstring> Directory::GetFiles(const wstring& folderPath, const wstring& pattern)
{
vector<wstring> files;
Expand All @@ -18,3 +24,17 @@ vector<wstring> Directory::GetFiles(const wstring& folderPath, const wstring& pa
FindClose(hFind);
return files;
}

wstring Directory::GetTempDirectory()
{
DWORD pathLength = GetTempPath(0, nullptr);
if (pathLength == 0)
return L"";

wstring path;
path.resize(pathLength);
GetTempPath(path.size(), path.data());

path.resize(path.size() - 1);
return path;
}
4 changes: 3 additions & 1 deletion Common/Directory.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,7 @@
class Directory
{
public:
static std::vector<std::wstring> GetFiles (const std::wstring& folderPath, const std::wstring& pattern);
static void Create (const std::wstring& folderPath);
static std::vector<std::wstring> GetFiles (const std::wstring& folderPath, const std::wstring& pattern);
static std::wstring GetTempDirectory ();
};
2 changes: 1 addition & 1 deletion Common/MemoryUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,6 @@ void* MemoryUtil::FindData(const void* pHaystack, int haystackLength, const void

void MemoryUtil::WritePointer(void** ptr, void* value)
{
PageUnprotector unprotector(ptr, 4);
PageUnprotector unprotector(ptr, sizeof(value));
*ptr = value;
}
10 changes: 10 additions & 0 deletions Common/Path.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,16 @@ wstring Path::GetModuleFolderPath(HMODULE hModule)
return GetDirectoryName(GetModuleFilePath(hModule));
}

wstring Path::GetFullPath(const wstring& path)
{
DWORD length = GetFullPathName(path.c_str(), 0, nullptr, nullptr);
wstring fullPath;
fullPath.resize(length);
GetFullPathName(path.c_str(), fullPath.size(), fullPath.data(), nullptr);
fullPath.resize(fullPath.size() - 1);
return fullPath;
}

int Path::GetExtensionIndex(const wstring& filePath)
{
int lastSlashPos = filePath.find_last_of(L'\\');
Expand Down
2 changes: 2 additions & 0 deletions Common/Path.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class Path
static std::wstring GetModuleFilePath (HMODULE hModule);
static std::wstring GetModuleFolderPath (HMODULE hModule);

static std::wstring GetFullPath (const std::wstring& path);

private:
static int GetExtensionIndex (const std::wstring& filePath);
};
34 changes: 0 additions & 34 deletions Common/StringUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,6 @@

using namespace std;

string StringUtil::Format(const char* pFormat, ...)
{
va_list args;

va_start(args, pFormat);
int length = snprintf(nullptr, 0, pFormat, args);
va_end(args);

va_start(args, pFormat);
string result;
result.resize(length);
sprintf(const_cast<char*>(result.c_str()), pFormat, args);
va_end(args);

return result;
}

wstring StringUtil::Format(const wchar_t* pFormat, ...)
{
va_list args;

va_start(args, pFormat);
int length = _vsnwprintf(nullptr, 0, pFormat, args);
va_end(args);

va_start(args, pFormat);
wstring result;
result.resize(length);
wvsprintf(const_cast<wchar_t*>(result.c_str()), pFormat, args);
va_end(args);

return result;
}

wstring StringUtil::ToUTF16(const string& str)
{
std::wstring wstr;
Expand Down
128 changes: 124 additions & 4 deletions Common/StringUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,130 @@

class StringUtil
{
private:
struct CFunctions
{
template<typename TChar>
static TChar ToLower(TChar c);

template<>
static char ToLower(char c)
{
return (char)tolower(c);
}

template<>
static wchar_t ToLower(wchar_t c)
{
return (wchar_t)towlower(c);
}

template<typename TChar>
static TChar ToUpper(TChar c);

template<>
static char ToUpper(char c)
{
return (char)toupper(c);
}

template<>
static wchar_t ToUpper(wchar_t c)
{
return (wchar_t)towupper(c);
}

static int StringPrintf(char* pBuffer, int bufferSize, const char* pFormat, va_list args)
{
return vsnprintf(pBuffer, bufferSize, pFormat, args);
}

static int StringPrintf(wchar_t* pBuffer, int bufferSize, const wchar_t* pFormat, va_list args)
{
return _vsnwprintf(pBuffer, bufferSize, pFormat, args);
}
};

public:
static std::string Format (const char* pFormat, ...);
static std::wstring Format (const wchar_t* pFormat, ...);
static std::wstring ToUTF16 (const std::string& str);
static std::string ToUTF8 (const std::wstring& wstr);

template<typename TChar>
static std::basic_string<TChar> Format(const TChar* pFormat, va_list args)
{
va_list argsForLength = args;
int length = CFunctions::StringPrintf(nullptr, 0, pFormat, argsForLength);

va_list argsForText = args;
std::basic_string<TChar> result;
result.resize(length);
CFunctions::StringPrintf(result.data(), result.size(), pFormat, argsForText);

return result;
}

template<typename TChar>
static std::basic_string<TChar> Format(const TChar* pFormat, ...)
{
va_list args;
va_start(args, pFormat);
return Format(pFormat, args);
}

template<typename TChar>
static std::basic_string<TChar> ToLower(const std::basic_string<TChar>& str)
{
std::basic_string<TChar> result;
result.resize(str.size());
std::ranges::transform(str, result.begin(), CFunctions::ToLower<TChar>);
return result;
}

template<typename TChar>
static std::basic_string<TChar> ToUpper(const std::basic_string<TChar>& str)
{
std::basic_string<TChar> result;
result.resize(str.size());
std::ranges::transform(str, result.begin(), CFunctions::ToUpper<TChar>);
return result;
}

template<typename TChar>
static std::vector<std::basic_string<TChar>> Split(const std::basic_string<TChar>& str, const std::basic_string<TChar>& delimiter)
{
std::vector<std::basic_string<TChar>> result;
int start = 0;
while (start < str.size())
{
int end = str.find(delimiter.c_str(), start);
if (end < 0)
end = str.size();

result.push_back(str.substr(start, end - start));
start = end + delimiter.size();
}
return result;
}

template<typename TChar>
static std::basic_string<TChar> Join(const std::vector<std::basic_string<TChar>>& elements, const std::basic_string<TChar>& delimiter)
{
std::basic_string<TChar> result;
for (int i = 0; i < elements.size(); i++)
{
if (i > 0)
result += delimiter;

result += elements[i];
}
return result;
}

static std::wstring ToUTF16 (const std::string& str);
static std::string ToUTF8 (const std::wstring& wstr);
template<typename TChar>
static std::basic_string<TChar> Replace(const std::basic_string<TChar>& str, TChar oldChar, TChar newChar)
{
std::basic_string<TChar> result(str);
std::ranges::replace(result, oldChar, newChar);
return result;
}
};
50 changes: 33 additions & 17 deletions KirikiriUnencryptedArchive/CompilerSpecific/CompilerHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ using namespace std;

void CompilerHelper::Init()
{
GameModuleHandle = GetModuleHandle(nullptr);
GameModuleSize = DetourGetModuleSize(GameModuleHandle);
GameSections = PE::GetSections(GameModuleHandle);
HMODULE hGame = GetModuleHandle(nullptr);
vector<PE::Section> gameSections = PE::GetSections(hGame);

const PE::Section& textSection = GameSections[0];
const PE::Section& textSection = gameSections[0];
if (MemoryUtil::FindData(textSection.Start, textSection.Size, "Borland", 7) != nullptr)
CompilerType = CompilerType::Borland;
else
Expand All @@ -17,47 +16,64 @@ void CompilerHelper::Init()

void** CompilerHelper::FindVTable(const string& className)
{
const PE::Section& textSection = GameSections[0];
return FindVTable(GetModuleHandle(nullptr), CompilerType, className);
}

void** CompilerHelper::FindVTable(HMODULE hModule, ::CompilerType compilerType, const std::string& className)
{
void* pModuleStart = (void*)hModule;
void* pModuleEnd = (BYTE*)pModuleStart + DetourGetModuleSize(hModule);

vector<PE::Section> sections = PE::GetSections(hModule);
const PE::Section& textSection = sections[0];
void* pCodeStart = textSection.Start;
void* pCodeEnd = (BYTE*)textSection.Start + textSection.Size;

for (int i = 1; i < GameSections.size(); i++)
string typeDescriptorClassName;
switch (compilerType)
{
case CompilerType::Borland:
typeDescriptorClassName = className;
break;

case CompilerType::Msvc:
vector<string> parts = StringUtil::Split<char>(className, "::");
std::ranges::reverse(parts);
typeDescriptorClassName = StringUtil::Join<char>(parts, "@");
break;
}

for (int i = 1; i < sections.size(); i++)
{
const PE::Section& section = GameSections[i];
const PE::Section& section = sections[i];
void* pSectionStart = section.Start;
void* pSectionEnd = (BYTE*)section.Start + section.Size;
for (void** ppFunc = (void**)pSectionStart + 3; ppFunc < pSectionEnd; ppFunc++)
{
if (*ppFunc < pCodeStart || *ppFunc >= pCodeEnd)
continue;

if (CompilerType == CompilerType::Borland && HasBorlandTypeDescriptor(ppFunc, className))
if (compilerType == CompilerType::Borland && HasBorlandTypeDescriptor(ppFunc, typeDescriptorClassName, pModuleStart, pModuleEnd))
return ppFunc;

if (CompilerType == CompilerType::Msvc && HasMsvcTypeDescriptor(ppFunc, className))
if (compilerType == CompilerType::Msvc && HasMsvcTypeDescriptor(ppFunc, typeDescriptorClassName, pModuleStart, pModuleEnd))
return ppFunc;
}
}
return nullptr;
}

bool CompilerHelper::HasBorlandTypeDescriptor(void** pVTable, const string& className)
bool CompilerHelper::HasBorlandTypeDescriptor(void** pVTable, const string& className, void* pModuleStart, void* pModuleEnd)
{
void* pModuleStart = GameModuleHandle;
void* pModuleEnd = (BYTE*)GameModuleHandle + GameModuleSize;

BorlandTypeDescriptor* pTypeDescriptor = (BorlandTypeDescriptor*)pVTable[-3];
if (pTypeDescriptor < pModuleStart || pTypeDescriptor >= pModuleEnd || pTypeDescriptor + 1 + className.size() > pModuleEnd)
return false;

return memcmp(pTypeDescriptor->Name, className.c_str(), className.size() + 1) == 0;
}

bool CompilerHelper::HasMsvcTypeDescriptor(void** pVTable, const string& className)
bool CompilerHelper::HasMsvcTypeDescriptor(void** pVTable, const string& className, void* pModuleStart, void* pModuleEnd)
{
void* pModuleStart = GameModuleHandle;
void* pModuleEnd = (BYTE*)GameModuleHandle + GameModuleSize;

MsvcRttiCompleteObjectLocator* pLocator = (MsvcRttiCompleteObjectLocator*)pVTable[-1];
if (pLocator < pModuleStart || pLocator >= pModuleEnd || pLocator + 1 > pModuleEnd ||
pLocator->Signature != 0 ||
Expand Down
10 changes: 4 additions & 6 deletions KirikiriUnencryptedArchive/CompilerSpecific/CompilerHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ class CompilerHelper
{
public:
static void Init ();

static void** FindVTable (const std::string& className);
static void** FindVTable (HMODULE hModule, CompilerType compilerType, const std::string& className);

static inline CompilerType CompilerType{};

Expand Down Expand Up @@ -183,10 +185,6 @@ class CompilerHelper
}
};

static inline HMODULE GameModuleHandle{};
static inline int GameModuleSize{};
static inline std::vector<PE::Section> GameSections{};

static bool HasBorlandTypeDescriptor (void** pVTable, const std::string& className);
static bool HasMsvcTypeDescriptor (void** pVTable, const std::string& className);
static bool HasBorlandTypeDescriptor (void** pVTable, const std::string& className, void* pModuleStart, void* pModuleEnd);
static bool HasMsvcTypeDescriptor (void** pVTable, const std::string& className, void* pModuleStart, void* pModuleEnd);
};
4 changes: 1 addition & 3 deletions KirikiriUnencryptedArchive/CxdecHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ bool CxdecHelper::IsCxdecUrl(const ttstr& url)

ttstr CxdecHelper::CxdecUrlToXp3FilePath(const ttstr& url)
{
wchar_t exePath[MAX_PATH];
GetModuleFileName(NULL, exePath, sizeof(exePath));
wstring folderPath = Path::GetDirectoryName(exePath);
wstring folderPath = Path::GetModuleFolderPath(nullptr);

const wchar_t* pPathStart = url.c_str() + strlen("archive://");
const wchar_t* pPathEnd = wcschr(pPathStart, L'/');
Expand Down
Loading

0 comments on commit ef2511b

Please sign in to comment.