Skip to content

Commit

Permalink
Create crash dump exception handler
Browse files Browse the repository at this point in the history
  • Loading branch information
Sirius902 committed Feb 20, 2022
1 parent 56930e8 commit b6efd22
Showing 1 changed file with 172 additions and 154 deletions.
326 changes: 172 additions & 154 deletions LuaBackendDLL/main_dll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
#include <windows.h>
#include <shlobj.h>

#define MiniDumpWriteDump MiniDumpWriteDump_Original
#include <minidumpapiset.h>
#undef MiniDumpWriteDump

#include <MemoryLib.h>
#include <LuaBackend.h>
#include <mIni/ini.h>
Expand All @@ -30,15 +34,7 @@ const std::unordered_map<std::string_view, GameInfo> gameInfos{

namespace fs = std::filesystem;

using MiniDumpWriteDumpProc = BOOL(WINAPI*)(
HANDLE hProcess,
DWORD ProcessId,
HANDLE hFile,
DWORD DumpType,
PVOID ExceptionParam,
PVOID UserStreamParam,
PVOID CallbackParam
);
using MiniDumpWriteDumpProc = decltype(&MiniDumpWriteDump_Original);

using GameFrameProc = std::uint64_t(__cdecl*)(void* rcx);

Expand All @@ -51,119 +47,119 @@ std::optional<GameInfo> gameInfo{};

extern "C"
{
using namespace std;
using namespace mINI;

bool _funcOneState = true;
bool _funcTwoState = true;
bool _funcThreeState = true;

string _scrPath;

bool _showConsole = false;
bool _requestedReset = false;
LuaBackend* _backend = nullptr;

chrono::high_resolution_clock::time_point _sClock;
chrono::high_resolution_clock::time_point _msClock;

void EnterWait()
{
string _output;
getline(std::cin, _output);
return;
}

void ResetLUA()
{
printf("\n");
ConsoleLib::MessageOutput("Reloading...\n\n", 0);
_backend = new LuaBackend(_scrPath.c_str(), MemoryLib::ExecAddress + MemoryLib::BaseAddress);

if (_backend->loadedScripts.size() == 0)
ConsoleLib::MessageOutput("No scripts found! Reload halted!\n\n", 3);

ConsoleLib::MessageOutput("Executing initialization event handlers...\n\n", 0);

for (auto _script : _backend->loadedScripts)
if (_script->initFunction)
{
auto _result = _script->initFunction();

if (!_result.valid())
{
sol::error _err = _result;
ConsoleLib::MessageOutput(_err.what(), 3);
printf("\n\n");
}
}

ConsoleLib::MessageOutput("Reload complete!\n\n", 1);

_msClock = chrono::high_resolution_clock::now();
_sClock = chrono::high_resolution_clock::now();

_requestedReset = false;
}

int __declspec(dllexport) EntryLUA(int ProcessID, HANDLE ProcessH, uint64_t TargetAddress, const char* ScriptPath)
{
ShowWindow(GetConsoleWindow(), SW_HIDE);

cout << "======================================" << "\n";
cout << "======= LuaBackendHook | v1.2.1 ======" << "\n";
cout << "====== Copyright 2021 - TopazTK ======" << "\n";
cout << "======================================" << "\n";
cout << "=== Compatible with LuaEngine v5.0 ===" << "\n";
cout << "========== Embedded Version ==========" << "\n";
cout << "======================================" << "\n\n";

ConsoleLib::MessageOutput("Initializing LuaEngine v5.0...\n\n", 0);
_scrPath = string(ScriptPath);

MemoryLib::ExternProcess(ProcessID, ProcessH, TargetAddress);

_backend = new LuaBackend(ScriptPath, MemoryLib::ExecAddress + TargetAddress);
_backend->frameLimit = 16;

if (_backend->loadedScripts.size() == 0)
{
ConsoleLib::MessageOutput("No scripts were found! Initialization halted!\n\n", 3);
return -1;
}
ConsoleLib::MessageOutput("Executing initialization event handlers...\n\n", 0);

for (auto _script : _backend->loadedScripts)
if (_script->initFunction)
{
auto _result = _script->initFunction();

if (!_result.valid())
{
sol::error _err = _result;
ConsoleLib::MessageOutput(_err.what(), 3);
printf("\n\n");
}
}

ConsoleLib::MessageOutput("Initialization complete!\n", 1);
ConsoleLib::MessageOutput("Press 'F1' to reload all scripts, press 'F2' to toggle the console, press 'F3' to set execution frequency.\n\n", 0);

_msClock = chrono::high_resolution_clock::now();
_sClock = chrono::high_resolution_clock::now();

return 0;
}

void __declspec(dllexport) ExecuteLUA()
{
if (_requestedReset == false)
{
auto _currTime = chrono::high_resolution_clock::now();
auto _msTime = std::chrono::duration_cast<std::chrono::milliseconds>(_currTime - _msClock).count();
auto _sTime = std::chrono::duration_cast<std::chrono::milliseconds>(_currTime - _sClock).count();
using namespace std;
using namespace mINI;

bool _funcOneState = true;
bool _funcTwoState = true;
bool _funcThreeState = true;

string _scrPath;

bool _showConsole = false;
bool _requestedReset = false;

LuaBackend* _backend = nullptr;

chrono::high_resolution_clock::time_point _sClock;
chrono::high_resolution_clock::time_point _msClock;

void EnterWait()
{
string _output;
getline(std::cin, _output);
return;
}

void ResetLUA()
{
printf("\n");
ConsoleLib::MessageOutput("Reloading...\n\n", 0);
_backend = new LuaBackend(_scrPath.c_str(), MemoryLib::ExecAddress + MemoryLib::BaseAddress);

if (_backend->loadedScripts.size() == 0)
ConsoleLib::MessageOutput("No scripts found! Reload halted!\n\n", 3);

ConsoleLib::MessageOutput("Executing initialization event handlers...\n\n", 0);

for (auto _script : _backend->loadedScripts)
if (_script->initFunction)
{
auto _result = _script->initFunction();

if (!_result.valid())
{
sol::error _err = _result;
ConsoleLib::MessageOutput(_err.what(), 3);
printf("\n\n");
}
}

ConsoleLib::MessageOutput("Reload complete!\n\n", 1);

_msClock = chrono::high_resolution_clock::now();
_sClock = chrono::high_resolution_clock::now();

_requestedReset = false;
}

int __declspec(dllexport) EntryLUA(int ProcessID, HANDLE ProcessH, uint64_t TargetAddress, const char* ScriptPath)
{
ShowWindow(GetConsoleWindow(), SW_HIDE);

cout << "======================================" << "\n";
cout << "======= LuaBackendHook | v1.2.1 ======" << "\n";
cout << "====== Copyright 2021 - TopazTK ======" << "\n";
cout << "======================================" << "\n";
cout << "=== Compatible with LuaEngine v5.0 ===" << "\n";
cout << "========== Embedded Version ==========" << "\n";
cout << "======================================" << "\n\n";

ConsoleLib::MessageOutput("Initializing LuaEngine v5.0...\n\n", 0);
_scrPath = string(ScriptPath);

MemoryLib::ExternProcess(ProcessID, ProcessH, TargetAddress);

_backend = new LuaBackend(ScriptPath, MemoryLib::ExecAddress + TargetAddress);
_backend->frameLimit = 16;

if (_backend->loadedScripts.size() == 0)
{
ConsoleLib::MessageOutput("No scripts were found! Initialization halted!\n\n", 3);
return -1;
}

ConsoleLib::MessageOutput("Executing initialization event handlers...\n\n", 0);

for (auto _script : _backend->loadedScripts)
if (_script->initFunction)
{
auto _result = _script->initFunction();

if (!_result.valid())
{
sol::error _err = _result;
ConsoleLib::MessageOutput(_err.what(), 3);
printf("\n\n");
}
}

ConsoleLib::MessageOutput("Initialization complete!\n", 1);
ConsoleLib::MessageOutput("Press 'F1' to reload all scripts, press 'F2' to toggle the console, press 'F3' to set execution frequency.\n\n", 0);

_msClock = chrono::high_resolution_clock::now();
_sClock = chrono::high_resolution_clock::now();

return 0;
}

void __declspec(dllexport) ExecuteLUA()
{
if (_requestedReset == false)
{
auto _currTime = chrono::high_resolution_clock::now();
auto _msTime = std::chrono::duration_cast<std::chrono::milliseconds>(_currTime - _msClock).count();
auto _sTime = std::chrono::duration_cast<std::chrono::milliseconds>(_currTime - _sClock).count();

if (GetKeyState(VK_F3) & 0x8000 && _funcThreeState)
{
Expand Down Expand Up @@ -235,33 +231,33 @@ extern "C"

_msClock = chrono::high_resolution_clock::now();

if (_sTime > 250)
{
_funcOneState = true;
_funcTwoState = true;
_funcThreeState = true;
_sClock = chrono::high_resolution_clock::now();
}
}

else
ResetLUA();
}

bool __declspec(dllexport) CheckLUA()
{
auto _int = MemoryLib::ReadInt(0);

if (_int == 0)
return false;

return true;
}

int __declspec(dllexport) VersionLUA()
{
return 128;
}
if (_sTime > 250)
{
_funcOneState = true;
_funcTwoState = true;
_funcThreeState = true;
_sClock = chrono::high_resolution_clock::now();
}
}

else
ResetLUA();
}

bool __declspec(dllexport) CheckLUA()
{
auto _int = MemoryLib::ReadInt(0);

if (_int == 0)
return false;

return true;
}

int __declspec(dllexport) VersionLUA()
{
return 128;
}
}

std::optional<std::uintptr_t> followPointerChain(std::uintptr_t start, const std::vector<std::uintptr_t>& offsets) {
Expand All @@ -285,9 +281,31 @@ std::uint64_t __cdecl frameHook(void* rcx) {
return frameProc(rcx);
}

LONG WINAPI crashHandler(PEXCEPTION_POINTERS exceptionPointers) {
HANDLE file = CreateFileA("CrashDump.dmp", GENERIC_READ | GENERIC_WRITE, 0,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

if (file != NULL) {
MINIDUMP_EXCEPTION_INFORMATION mdei;

mdei.ThreadId = GetCurrentThreadId();
mdei.ExceptionPointers = exceptionPointers;
mdei.ClientPointers = TRUE;

(*writeDumpProc)( GetCurrentProcess(), GetCurrentProcessId(),
file, MiniDumpNormal, (exceptionPointers != 0) ? &mdei : 0, 0, 0 );

CloseHandle(file);
}

return EXCEPTION_EXECUTE_HANDLER;
}

bool hookGame(std::uint64_t moduleAddress) {
static_assert(sizeof(std::uint64_t) == sizeof(std::uintptr_t));

SetUnhandledExceptionFilter(crashHandler);

const std::vector<std::uintptr_t> frameProcOffsets{ 0x3E8, 0x0, 0x20 };
const std::vector<std::uintptr_t> graphicsProcOffsets{ 0x2D8 };

Expand Down Expand Up @@ -345,7 +363,7 @@ DWORD WINAPI entry(LPVOID lpParameter) {
std::this_thread::sleep_for(std::chrono::milliseconds(16));
}
} else {
std::cout << "Failed to initialize internal LuaBackend!" << std::endl;
std::cout << "Failed to initialize internal LuaBackend!" << std::endl;
}
}

Expand Down Expand Up @@ -384,10 +402,10 @@ extern "C" __declspec(dllexport) BOOL WINAPI MiniDumpWriteDump(
HANDLE hProcess,
DWORD ProcessId,
HANDLE hFile,
DWORD DumpType,
PVOID ExceptionParam,
PVOID UserStreamParam,
PVOID CallbackParam
MINIDUMP_TYPE DumpType,
PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
PMINIDUMP_CALLBACK_INFORMATION CallbackParam
) {
return writeDumpProc(hProcess, ProcessId, hFile, DumpType, ExceptionParam, UserStreamParam, CallbackParam);
}

0 comments on commit b6efd22

Please sign in to comment.