r5sdk/r5dev/console.cpp
Kawe Mazidjatari 4439f513d0 Implement signature based hooking and small code cleanup
Better signatures have to be created in the future to support roughly all retail r5apex modules. Maybe also load a file from the disk containing offsets for instant hooking before falling back to sigscan
2021-04-16 14:12:39 +02:00

112 lines
2.4 KiB
C++

#include <string>
#include <iostream>
#include <sstream>
#include <Windows.h>
#include <detours.h>
#include "patterns.h"
DWORD __stdcall ProcessConsoleWorker(LPVOID);
FILE* sBuildTxt;
CHAR sBuildStr[1024];
void SetupConsole()
{
// Create the console window
if (AllocConsole() == FALSE)
{
OutputDebugStr("Failed to create console window!\n");
return;
}
// Set the window title
#pragma warning(suppress : 4996)
sBuildTxt = fopen("build.txt", "r");
if (sBuildTxt)
{
while (fgets(sBuildStr, sizeof(sBuildStr), sBuildTxt) != NULL)
fclose(sBuildTxt);
}
SetConsoleTitle(sBuildStr);
// Open input/output streams
FILE* fDummy;
freopen_s(&fDummy, "CONIN$", "r", stdin);
freopen_s(&fDummy, "CONOUT$", "w", stdout);
freopen_s(&fDummy, "CONOUT$", "w", stderr);
// Create a worker thread to process console commands.
HANDLE hThread = CreateThread(NULL, NULL, ProcessConsoleWorker, NULL, NULL, NULL);
CloseHandle(hThread);
}
bool Hook_Cvar_IsFlagSet(int ** cvar, int flag);
bool Hook_Cvar_IsFlagSet(int ** cvar, int flag)
{
int real_flags = *(*(cvar + (72/(sizeof(void*)))) + (56/sizeof(int)));
#ifdef _DEBUG
printf("----------------------------------------------\n");
printf("Real flags: %08X\n", real_flags);
#endif
// mask off FCVAR_CHEATS and FCVAR_DEVELOPMENTONLY
real_flags &= 0xFFFFBFFD;
#ifdef _DEBUG
printf(" masked: %08X\n", real_flags);
printf(" checking: %08X\n", flag);
#endif
if (flag & 0x80000)
{
return true;
}
return (real_flags & flag) != 0;
}
bool g_dev = false;
void ToggleDevCommands()
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
if (!g_dev)
DetourAttach((PVOID*)&Cvar_IsFlagSet, &Hook_Cvar_IsFlagSet);
else
DetourDetach((PVOID*)&Cvar_IsFlagSet, &Hook_Cvar_IsFlagSet);
if (DetourTransactionCommit() != NO_ERROR)
TerminateProcess(GetCurrentProcess(), 0xBAD0C0DE);
g_dev = ~g_dev;
}
DWORD __stdcall ProcessConsoleWorker(LPVOID)
{
// Loop forever.
while (true)
{
std::string sCommand;
// get the user input on the debug console
printf(">");
std::getline(std::cin, sCommand);
if (sCommand == "toggle dev")
{
ToggleDevCommands();
continue;
}
// execute the command in the r5 SQVM
CommandExecute(NULL, sCommand.c_str());
sCommand.clear();
// Sleep and loop.
Sleep(50);
}
return 0;
}