Skip to content

Commit

Permalink
Add sanity checks and logs when patching KAGE::StartupEngine from the…
Browse files Browse the repository at this point in the history
… loader
  • Loading branch information
Sylmir committed Nov 16, 2024
1 parent 7247412 commit 902273e
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 13 deletions.
8 changes: 6 additions & 2 deletions libzhl/ASMPatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,14 @@ void* ASMPatcher::PatchFromSig(const char* sig, const char* with) {
return PatchAt(scan.GetAddress(), with);
}

void* ASMPatcher::PatchAt(void* at, ASMPatch* with) {
void* ASMPatcher::PatchAt(void* at, ASMPatch* with, size_t* len) {
void* targetPage = GetAllocPage(with->Length(), true);
std::unique_ptr<char[]> text = with->ToASM(targetPage);
return Patch(at, targetPage, text.get(), with->Length());
size_t patchLen = with->Length();
if (len) {
*len = patchLen;
}
return Patch(at, targetPage, text.get(), patchLen);
}

void* ASMPatcher::PatchAt(void* at, const char* with, size_t len) {
Expand Down
8 changes: 4 additions & 4 deletions libzhl/ASMPatcher.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include "libzhl.h"

extern "C" {
__declspec(dllexport) int InitZHL(void (*ptr)());
__declspec(dllexport) int InitZHL(void (__stdcall*ptr)());
}

class LIBZHL_API ASMPatcher
Expand Down Expand Up @@ -72,7 +72,7 @@ class LIBZHL_API ASMPatcher
void* AttemptPatchFunction(const char* beginSig, const char* endSig, const char* patchSig, const char* with);
void* PatchFromSig(const char* sig, const char* with);
void* PatchAt(void* at, const char* with, size_t len = 0);
void* PatchAt(void* at, ASMPatch* with);
void* PatchAt(void* at, ASMPatch* with, size_t* len = NULL);
void* Patch(void* at, void* page, const char* with, size_t len);

void FlatPatch(void* at, ASMPatch* with, bool nopRest = false);
Expand Down Expand Up @@ -222,7 +222,7 @@ class LIBZHL_API ASMPatch

private:
friend ASMPatch;
friend __declspec(dllexport) int InitZHL(void (*ptr)());
friend __declspec(dllexport) int InitZHL(void (__stdcall*ptr)());

void Restore();
uint32_t GetMask() const;
Expand Down Expand Up @@ -467,7 +467,7 @@ class LIBZHL_API ASMPatch
void* _target;
};

friend __declspec(dllexport) int InitZHL(void (*ptr)());
friend __declspec(dllexport) int InitZHL(void (__stdcall*ptr)());
static void _Init();

uint8_t RegisterTox86(Registers reg);
Expand Down
22 changes: 18 additions & 4 deletions libzhl/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
#include <filesystem>
#include <sstream>

void (*loaderFinish)() = NULL;
void (__stdcall*loaderFinish)() = NULL;

void __stdcall SanityCheckInitZHL() {
ZHL::Log("SanityCheckInitZHL: patch should be okay\n");
}

/* Because ZHL is not initialized when we enter InitZHL, we cannot hook
* anything, so we need to ASM patch instead.
Expand All @@ -29,22 +33,31 @@ void HookMain() {
char* movOffsetAddr = (char*)addr + 0x3;
void* movOffsetValue;
memcpy(&movOffsetValue, movOffsetAddr, 0x4);
printf("Found KAGE::EngineStartup hook address %p\n", addr);
ZHL::Log("Found KAGE::EngineStartup call address %p\n", addr);
ZHL::Log("Dumping ASM: ");
ZHL::DumpMemory(addr, 0x20, false, true);
ASMPatch patch;
ASMPatch::SavedRegisters registers(ASMPatch::SavedRegisters::GP_REGISTERS_STACKLESS, true);
patch.PreserveRegisters(registers);
patch.AddInternalCall(SanityCheckInitZHL);
patch.AddInternalCall(loaderFinish);
patch.RestoreRegisters(registers);
ByteBuffer buffer;
buffer.AddString("\x32\xd2\xb9");
buffer.AddPointer(movOffsetValue);
patch.AddBytes(buffer);
patch.AddRelativeJump((char*)addr + 0x7);
sASMPatcher.PatchAt(addr, &patch);
size_t patchLen = 0;
void* patchedAddr = sASMPatcher.PatchAt(addr, &patch, &patchLen);

ZHL::Log("Dumping ASM of the call to KAGE::Engine post patch: ");
ZHL::DumpMemory(addr, 0x20, false, true);
ZHL::Log("Dumping ASM of the patch: ");
ZHL::DumpMemory(patchedAddr, patchLen, false, true);
}

extern "C" {
__declspec(dllexport) int InitZHL(void (*loaderFinishPtr)())
__declspec(dllexport) int InitZHL(void (__stdcall*loaderFinishPtr)())
{
#ifdef ZHL_LOG_FILE
std::ofstream f(ZHL_LOG_FILE, std::ios_base::app);
Expand All @@ -58,6 +71,7 @@ extern "C" {
ExitProcess(1);
}
#endif
ZHL::ClearLogFile();
if (!FunctionDefinition::Init())
{
auto const& missing = Definition::GetMissing();
Expand Down
4 changes: 2 additions & 2 deletions loader/loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ DWORD RedirectLua(FILE* f, HMODULE* outLua) {

static HMODULE luaHandle = NULL;

void LoadMods() {
void __stdcall LoadMods() {
FILE* f = fopen("zhlLoader.log", "a");
Log(f, "INFO", "Loading mods...\n");

Expand Down Expand Up @@ -192,7 +192,7 @@ extern "C" {
Log(f, "INFO", "Loaded ZHL at %p\n", zhl);
Log(f, "INFO", "Search InitZHL in ZHL\n");

int (*initZhl)(void (*)()) = (int(*)(void(*)()))GetProcAddress(zhl, "InitZHL");
int (*initZhl)(void (__stdcall*)()) = (int(*)(void(__stdcall*)()))GetProcAddress(zhl, "InitZHL");
if (!initZhl) {
FreeLibrary(zhl);
Log(f, "ERROR", "InitZHL not found\n");
Expand Down
1 change: 0 additions & 1 deletion repentogon/dllmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ char REPENTOGON::moddedtitle[256] = "";
// This small function loads all the hooks and must be present in every mod
MOD_EXPORT int ModInit(int argc, char** argv)
{
ZHL::ClearLogFile();
ZHL::Logger logger(true);
logger.Log("REPENTOGON: ModInit\n");

Expand Down

0 comments on commit 902273e

Please sign in to comment.