New hook for ConCommandBase::IsFlagSet(...)

Updated signatures
Code cleanup and improvements
Fixd some bugs and crashes
This commit is contained in:
Amos 2021-04-25 14:36:55 -07:00
parent c53ba3f31e
commit c8a682ddaa
11 changed files with 180 additions and 107 deletions

View File

@ -1,8 +1,8 @@
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <Windows.h>
#include <Windows.h>
#include <detours.h> #include <detours.h>
#include "hooks.h" #include "hooks.h"
@ -23,13 +23,14 @@ void SetupConsole()
// Set the window title // Set the window title
FILE* sBuildTxt; FILE* sBuildTxt;
CHAR sBuildBuf[1024]; CHAR sBuildBuf[1024] = { 0 };
#pragma warning(suppress : 4996) fopen_s(&sBuildTxt, "build.txt", "r");
sBuildTxt = fopen("build.txt", "r");
if (sBuildTxt) if (sBuildTxt)
{ {
while (fgets(sBuildBuf, sizeof(sBuildBuf), sBuildTxt) != NULL) while (fgets(sBuildBuf, sizeof(sBuildBuf), sBuildTxt) != NULL)
{
fclose(sBuildTxt); fclose(sBuildTxt);
}
} }
SetConsoleTitle(sBuildBuf); SetConsoleTitle(sBuildBuf);
@ -39,25 +40,59 @@ void SetupConsole()
freopen_s(&fDummy, "CONOUT$", "w", stdout); freopen_s(&fDummy, "CONOUT$", "w", stdout);
freopen_s(&fDummy, "CONOUT$", "w", stderr); freopen_s(&fDummy, "CONOUT$", "w", stderr);
// Create a worker thread to process console commands. // Create a worker thread to process console commands
DWORD threadId;
DWORD __stdcall ProcessConsoleWorker(LPVOID); DWORD __stdcall ProcessConsoleWorker(LPVOID);
HANDLE hThread = CreateThread(NULL, NULL, ProcessConsoleWorker, NULL, NULL, NULL); HANDLE hThread = CreateThread(NULL, 0, ProcessConsoleWorker, NULL, 0, &threadId);
CloseHandle(hThread);
if (hThread)
{
printf("THREAD ID: %ld\n\n", threadId);
CloseHandle(hThread);
}
} }
bool Hook_Cvar_IsFlagSet(int ** cvar, int flag) static bool b_DebugConsole = true;
bool Hook_ConVar_IsFlagSet(int** cvar, int flag)
{ {
int real_flags = *(*(cvar + (72/(sizeof(void*)))) + (56/sizeof(int))); int real_flags = *(*(cvar + (72 / (sizeof(void*)))) + (56 / sizeof(int)));
if (!b_DebugConsole)
{
printf("----------------------------------------------\n");
printf(" Flaged: %08X\n", real_flags);
}
printf("----------------------------------------------\n"); // Mask off FCVAR_CHEATS and FCVAR_DEVELOPMENTONLY
printf("Real flags: %08X\n", real_flags);
// Mask off FCVAR_CHEATS and FCVAR_DEVELOPMENTONLY
real_flags &= 0xFFFFBFFD; real_flags &= 0xFFFFBFFD;
if (!b_DebugConsole)
{
printf(" Masked: %08X\n", real_flags);
printf(" Verify: %08X\n", flag);
}
if (flag & 0x80000)
{
return true;
}
printf(" Masked: %08X\n", real_flags); return (real_flags & flag) != 0;
printf(" Checking: %08X\n", flag); }
bool Hook_ConCommand_IsFlagSet(int* cmd, int flag)
{
int real_flags = *((cmd + (56 / sizeof(int))));
if (!b_DebugConsole)
{
printf("----------------------------------------------\n");
printf(" Flaged: %08X\n", real_flags);
}
// Mask off FCVAR_CHEATS and FCVAR_DEVELOPMENTONLY
real_flags &= 0xFFFFBFFD;
if (!b_DebugConsole)
{
printf(" Masked: %08X\n", real_flags);
printf(" Verify: %08X\n", flag);
}
if (flag & 0x80000) if (flag & 0x80000)
{ {
return true; return true;
@ -86,12 +121,21 @@ DWORD __stdcall ProcessConsoleWorker(LPVOID)
ToggleDevCommands(); ToggleDevCommands();
continue; continue;
} }
if (sCommand == "toggle net") if (sCommand == "toggle net")
{ {
ToggleNetHooks(); ToggleNetHooks();
continue; continue;
} }
if (sCommand == "pattern test")
{
PrintHAddress();
continue;
}
if (sCommand == "console test")
{
b_DebugConsole = !b_DebugConsole;
continue;
}
// Execute the command in the r5 SQVM // Execute the command in the r5 SQVM
CommandExecute(NULL, sCommand.c_str()); CommandExecute(NULL, sCommand.c_str());

View File

@ -6,11 +6,6 @@
#include "utilities.h" #include "utilities.h"
#include "hooks.h" #include "hooks.h"
__declspec(dllexport) void DummyExport()
{
// Required for detours.
}
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// Main // Main
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
@ -19,7 +14,10 @@ void InitializeR5Dev()
{ {
SetupConsole(); SetupConsole();
InstallHooks(); InstallHooks();
printf("R5 Dev -- Initialized...\n"); printf("+-----------------------------------------------------------------------------+\n");
printf("| R5 DEV -- INITIALIZED ------------------------------------------------- |\n");
printf("+-----------------------------------------------------------------------------+\n");
printf("\n");
} }
void TerminateR5Dev() void TerminateR5Dev()

View File

@ -7,59 +7,37 @@
#include "utilities.h" #include "utilities.h"
#include "hooks.h" #include "hooks.h"
#include "patterns.h" #include "patterns.h"
#include "structs.h"
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
// Engine Hooks // Engine Hooks
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
struct __declspec(align(8)) netpacket_t
{
DWORD family_maybe;
sockaddr_in sin;
WORD sin_port;
BYTE gap16;
BYTE byte17;
DWORD source;
double received;
unsigned __int8* data;
QWORD label;
BYTE byte38;
QWORD qword40;
QWORD qword48;
BYTE gap50[8];
QWORD qword58;
QWORD qword60;
QWORD qword68;
int less_than_12;
DWORD wiresize;
BYTE gap78[8];
QWORD qword80;
};
bool Hook_NET_ReceiveDatagram(int sock, void* inpacket, bool raw) bool Hook_NET_ReceiveDatagram(int sock, void* inpacket, bool raw)
{ {
bool result = NET_ReceiveDatagram(sock, inpacket, raw); bool result = NET_ReceiveDatagram(sock, inpacket, raw);
if (result) if (result)
{ {
netpacket_t* pkt = (netpacket_t *)inpacket; int i = NULL;
netpacket_t* pkt = (netpacket_t*)inpacket;
// TODO: print the rest of the data.. // Log received packet data
printf("Got packet! Len %u\n -- ", pkt->wiresize); HexDump("", "", "", 0, &pkt->data[i], pkt->wiresize);
for (int i = 0; i < 16 && i < pkt->wiresize; i++)
{
printf("%02X ", pkt->data[i]);
}
printf("\n");
} }
return result; return result;
} }
unsigned int Hook_NET_SendDatagram(SOCKET s, const char* ptxt, int len, void* netchan_maybe, bool raw) unsigned int Hook_NET_SendDatagram(SOCKET s, const char* buf, int len, int flags)
{ {
// TODO print ptxt[...] up to len bytes unsigned int result = NET_SendDatagram(s, buf, len, flags);
printf("Sending packet! %u bytes @ %p\n", len, ptxt); if (result)
return NET_SendDatagram(s, ptxt, len, netchan_maybe, raw); {
// Log transmitted packet data
HexDump("", "", "", 0, buf, len);
}
return result;
} }
void* Hook_SQVM_Print(void* sqvm, char* fmt, ...) void* Hook_SQVM_Print(void* sqvm, char* fmt, ...)
@ -73,7 +51,7 @@ void* Hook_SQVM_Print(void* sqvm, char* fmt, ...)
bool Hook_SQVM_LoadScript(void* sqvm, const char* script_path, const char* script_name, int flag) bool Hook_SQVM_LoadScript(void* sqvm, const char* script_path, const char* script_name, int flag)
{ {
char filepath[MAX_PATH] = {0}; char filepath[MAX_PATH] = { 0 };
sprintf_s(filepath, MAX_PATH, "platform\\%s", script_path); sprintf_s(filepath, MAX_PATH, "platform\\%s", script_path);
// Flip forward slashes in filepath to windows-style backslash // Flip forward slashes in filepath to windows-style backslash
@ -126,6 +104,10 @@ void RemoveHooks()
// Unhook Functions // Unhook Functions
DetourDetach((LPVOID*)&SQVM_Print, &Hook_SQVM_Print); DetourDetach((LPVOID*)&SQVM_Print, &Hook_SQVM_Print);
DetourDetach((LPVOID*)&SQVM_LoadScript, &Hook_SQVM_LoadScript); DetourDetach((LPVOID*)&SQVM_LoadScript, &Hook_SQVM_LoadScript);
DetourDetach((LPVOID*)&ConVar_IsFlagSet, &Hook_ConVar_IsFlagSet);
DetourDetach((LPVOID*)&ConCommand_IsFlagSet, &Hook_ConCommand_IsFlagSet);
DetourDetach((LPVOID*)&NET_SendDatagram, &Hook_NET_SendDatagram);
DetourDetach((LPVOID*)&NET_ReceiveDatagram, &Hook_NET_ReceiveDatagram);
// Commit the transaction // Commit the transaction
DetourTransactionCommit(); DetourTransactionCommit();
@ -133,18 +115,20 @@ void RemoveHooks()
void ToggleDevCommands() void ToggleDevCommands()
{ {
bool g_dev = false; static bool g_dev = false;
DetourTransactionBegin(); DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread()); DetourUpdateThread(GetCurrentThread());
if (!g_dev) if (!g_dev)
{ {
DetourAttach((PVOID*)&Cvar_IsFlagSet, &Hook_Cvar_IsFlagSet); DetourAttach((LPVOID*)&ConVar_IsFlagSet, &Hook_ConVar_IsFlagSet);
DetourAttach((LPVOID*)&ConCommand_IsFlagSet, &Hook_ConCommand_IsFlagSet);
} }
else else
{ {
DetourDetach((PVOID*)&Cvar_IsFlagSet, &Hook_Cvar_IsFlagSet); DetourDetach((LPVOID*)&ConVar_IsFlagSet, &Hook_ConVar_IsFlagSet);
DetourDetach((LPVOID*)&ConCommand_IsFlagSet, &Hook_ConCommand_IsFlagSet);
} }
if (DetourTransactionCommit() != NO_ERROR) if (DetourTransactionCommit() != NO_ERROR)
@ -152,25 +136,25 @@ void ToggleDevCommands()
TerminateProcess(GetCurrentProcess(), 0xBAD0C0DE); TerminateProcess(GetCurrentProcess(), 0xBAD0C0DE);
} }
g_dev = ~g_dev; g_dev = !g_dev;
} }
void ToggleNetHooks() void ToggleNetHooks()
{ {
bool g_net = false; static bool g_net = false;
DetourTransactionBegin(); DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread()); DetourUpdateThread(GetCurrentThread());
if (!g_net) if (!g_net)
{ {
DetourAttach((PVOID*)&NET_SendDatagram, &Hook_NET_SendDatagram); DetourAttach((LPVOID*)&NET_SendDatagram, &Hook_NET_SendDatagram);
DetourAttach((PVOID*)&NET_ReceiveDatagram, &Hook_NET_ReceiveDatagram); DetourAttach((LPVOID*)&NET_ReceiveDatagram, &Hook_NET_ReceiveDatagram);
} }
else else
{ {
DetourDetach((PVOID*)&NET_SendDatagram, &Hook_NET_SendDatagram); DetourDetach((LPVOID*)&NET_SendDatagram, &Hook_NET_SendDatagram);
DetourDetach((PVOID*)&NET_ReceiveDatagram, &Hook_NET_ReceiveDatagram); DetourDetach((LPVOID*)&NET_ReceiveDatagram, &Hook_NET_ReceiveDatagram);
} }
if (DetourTransactionCommit() != NO_ERROR) if (DetourTransactionCommit() != NO_ERROR)
@ -178,5 +162,5 @@ void ToggleNetHooks()
TerminateProcess(GetCurrentProcess(), 0xBAD0C0DE); TerminateProcess(GetCurrentProcess(), 0xBAD0C0DE);
} }
g_net = ~g_net; g_net = !g_net;
} }

View File

@ -5,4 +5,5 @@ void RemoveHooks();
void ToggleDevCommands(); void ToggleDevCommands();
void ToggleNetHooks(); void ToggleNetHooks();
bool Hook_Cvar_IsFlagSet(int** cvar, int flag); bool Hook_ConVar_IsFlagSet(int** cvar, int flag);
bool Hook_ConCommand_IsFlagSet(int* cmd, int flag);

View File

@ -6,34 +6,40 @@ namespace
{ {
SigScan fScanner; SigScan fScanner;
LONGLONG hGameConsole = fScanner.FindPattern("r5apex.exe", "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x48\x8D\x0D\x27\x61\xa5\x1e\x41\x8B\xD8", "xxxx?xxxxxxxx????xxx"); LONGLONG p_GameConsole = fScanner.FindPattern("r5apex.exe", "\x48\x89\x5C\x24\x08\x57\x48\x83\xEC\x20\x48\x8D\x0D\x27\x61\xa5\x1e\x41\x8B\xD8", "xxxx?xxxxxxxx????xxx");
void (*CommandExecute)(void* self, const char* cmd) = (void (*)(void*, const char*))hGameConsole; void (*CommandExecute)(void* self, const char* cmd) = (void (*)(void*, const char*))p_GameConsole;
LONGLONG hGameConsoleFlag = fScanner.FindPattern("r5apex.exe", "\x48\x8B\x41\x48\x85\x50\x38", "xxxxxxx"); LONGLONG p_ConVarFlag = fScanner.FindPattern("r5apex.exe", "\x48\x8B\x41\x48\x85\x50\x38", "xxxxxxx");
bool (*Cvar_IsFlagSet)(int** cvar, int flag) = (bool (*)(int**, int))hGameConsoleFlag; bool (*ConVar_IsFlagSet)(int** cvar, int flag) = (bool (*)(int**, int))p_ConVarFlag;
LONGLONG hSquirrelVMPrint = fScanner.FindPattern("r5apex.exe", "\x48\x8B\xC4\x48\x89\x50\x10\x4C\x89\x40\x18\x4C\x89\x48\x20\x53\x56\x57\x48\x81\xEC\x30\x08\x00\x00\x48\x8B\xDA\x48\x8D\x70\x18\x48\x8B\xF9\xE8\x00\x00\x00\xff\x48\x89\x74\x24\x28\x48\x8d\x54\x24\x30\x33", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx???xxxxxxxxxxxx"); LONGLONG p_ConCommandFlag = fScanner.FindPattern("r5apex.exe", "\x85\x51\x38\x0f\x95\xc0\xc3", "xxxxxxx");
void* SQVM_Print = (void*)hSquirrelVMPrint; bool (*ConCommand_IsFlagSet)(int* cmd, int flag) = (bool (*)(int*, int))p_ConCommandFlag;
LONGLONG hSquirrelVMScript = fScanner.FindPattern("r5apex.exe", "\x48\x89\x5C\x24\x10\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x48\x89\x4C\x24\x08\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\x6C", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); // Uncomment for S0 and S1 LONGLONG p_SquirrelVMPrint = fScanner.FindPattern("r5apex.exe", "\x48\x8B\xC4\x48\x89\x50\x10\x4C\x89\x40\x18\x4C\x89\x48\x20\x53\x56\x57\x48\x81\xEC\x30\x08\x00\x00\x48\x8B\xDA\x48\x8D\x70\x18\x48\x8B\xF9\xE8\x00\x00\x00\xff\x48\x89\x74\x24\x28\x48\x8d\x54\x24\x30\x33", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx???xxxxxxxxxxxx");
//LONGLONG hSquirrelVMScript = fScanner.FindPattern("r5apex.exe", "\x48\x8B\xC4\x48\x89\x48\x08\x55\x41\x56\x48\x8D\x68", "xxxxxxxxxxxxx"); // Uncomment for anything S2 and above (current S8) void* SQVM_Print = (void*)p_SquirrelVMPrint;
bool (*SQVM_LoadScript)(void* sqvm, const char* script_path, const char* script_name, int flag) = (bool (*)(void*, const char*, const char*, int))hSquirrelVMScript;
LONGLONG hNetRXDatagram = fScanner.FindPattern("r5apex.exe", "\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xAC\x24\x50\xeb", "xxxxxxxxxxxxxxxxxxxxxxxxx"); //LONGLONG p_SquirrelVMScript = fScanner.FindPattern("r5apex.exe", "\x48\x89\x5C\x24\x10\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x48\x89\x4C\x24\x08\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\x6C", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"); // Uncomment for S0 and S1
bool (*NET_ReceiveDatagram)(int, void*, bool) = (bool (*)(int, void*, bool))hNetRXDatagram; LONGLONG p_SquirrelVMScript = fScanner.FindPattern("r5apex.exe", "\x48\x8B\xC4\x48\x89\x48\x08\x55\x41\x56\x48\x8D\x68", "xxxxxxxxxxxxx"); // Uncomment for anything S2 and above (current S8)
bool (*SQVM_LoadScript)(void* sqvm, const char* script_path, const char* script_name, int flag) = (bool (*)(void*, const char*, const char*, int))p_SquirrelVMScript;
LONGLONG hNetTXDatagram = fScanner.FindPattern("r5apex.exe", "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xEC\x20\x48\x8B\xF9\x41\xb8\x2d", "xxxxxxxxxxxxxxxxxxxxxxxxxx"); LONGLONG p_NetRXDatagram = fScanner.FindPattern("r5apex.exe", "\x48\x89\x74\x24\x18\x48\x89\x7C\x24\x20\x55\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xAC\x24\x50\xeb", "xxxxxxxxxxxxxxxxxxxxxxxxx");
unsigned int (*NET_SendDatagram)(SOCKET s, const char* ptxt, int len, void* netchan_maybe, bool raw) = (unsigned int (*)(SOCKET, const char*, int, void*, bool))hNetTXDatagram; bool (*NET_ReceiveDatagram)(int, void*, bool) = (bool (*)(int, void*, bool))p_NetRXDatagram;
LONGLONG p_NetTXDatagram = fScanner.FindPattern("r5apex.exe", "\x48\x89\x5c\x24\x08\x48\x89\x6c\x24\x10\x48\x89\x74\x24\x18\x57\x41\x56\x41\x57\x48\x81\xec\x00\x05\x00\x00", "xxxxxxxxxxxxxxxxxxxxxxx?xxx");
unsigned int (*NET_SendDatagram)(SOCKET s, const char* buf, int len, int flags) = (unsigned int (*)(SOCKET, const char*, int, int))p_NetTXDatagram;
void PrintHAddress() // Test the sigscan results void PrintHAddress() // Test the sigscan results
{ {
printf("%lld\n", hGameConsole); printf("\n");
printf("%lld\n", hGameConsoleFlag); printf("0x%llx = GameConsole\n", p_GameConsole);
printf("%lld\n", hSquirrelVMPrint); printf("0x%llx = GameConsoleFlag\n", p_ConCommandFlag);
printf("%lld\n", hSquirrelVMScript); printf("0x%llx = GameConsoleFlag\n", p_ConVarFlag);
printf("%lld\n", hNetRXDatagram); printf("0x%llx = SquirrelVMPrint\n", p_SquirrelVMPrint);
printf("%lld\n", hNetTXDatagram); printf("0x%llx = SquirrelVMScript\n", p_SquirrelVMScript);
printf("0x%llx = NetRXDatagram\n", p_NetRXDatagram);
printf("0x%llx = NetTXDatagram\n", p_NetTXDatagram);
printf("\n");
// TODO implement error handling when sigscan fails/result is 0 // TODO implement error handling when sigscan fails or result is 0
} }
} }

View File

@ -3,3 +3,8 @@
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files // Windows Header Files
#include <windows.h> #include <windows.h>
__declspec(dllexport) void DummyExport()
{
// Required for detours.
}

View File

@ -176,6 +176,7 @@
<ClInclude Include="patterns.h" /> <ClInclude Include="patterns.h" />
<ClInclude Include="r5dev.h" /> <ClInclude Include="r5dev.h" />
<ClInclude Include="sigscan.h" /> <ClInclude Include="sigscan.h" />
<ClInclude Include="structs.h" />
<ClInclude Include="utilities.h" /> <ClInclude Include="utilities.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View File

@ -44,10 +44,13 @@
<ClInclude Include="sigscan.h"> <ClInclude Include="sigscan.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="structs.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="r5dev.def"> <None Include="r5dev.def">
<Filter>Header Files</Filter> <Filter>Resource Files</Filter>
</None> </None>
</ItemGroup> </ItemGroup>
</Project> </Project>

28
r5dev/structs.h Normal file
View File

@ -0,0 +1,28 @@
#pragma once
// Define structures/types
typedef unsigned __int64 QWORD;
struct __declspec(align(8)) netpacket_t
{
DWORD family_maybe;
sockaddr_in sin;
WORD sin_port;
BYTE gap16;
BYTE byte17;
DWORD source;
double received;
unsigned __int8* data;
QWORD label;
BYTE byte38;
QWORD qword40;
QWORD qword48;
BYTE gap50[8];
QWORD qword58;
QWORD qword60;
QWORD qword68;
int less_than_12;
DWORD wiresize;
BYTE gap78[8];
QWORD qword80;
};

View File

@ -1,10 +1,19 @@
#pragma once #pragma once
#include <Windows.h>
#include <stdio.h> #include <stdio.h>
#include <string> #include <string>
#include "hooks.h"
namespace namespace
{ {
BOOL FileExists(LPCTSTR szPath)
{
DWORD dwAttrib = GetFileAttributes(szPath);
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
static void DbgPrint(LPCSTR Format, ...) static void DbgPrint(LPCSTR Format, ...)
{ {
CHAR Buffer[512] = { 0 }; CHAR Buffer[512] = { 0 };
@ -21,17 +30,7 @@ namespace
OutputDebugString(Buffer); OutputDebugString(Buffer);
} }
typedef unsigned __int64 QWORD; static void HexDump(const char* header, const char* file, const char* mode, int func, const void* data, int size)
BOOL FileExists(LPCTSTR szPath)
{
DWORD dwAttrib = GetFileAttributes(szPath);
return (dwAttrib != INVALID_FILE_ATTRIBUTES &&
!(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}
static void HexDump(char* data, int len)
{ {
// todo.. // todo..
} }

View File

@ -8,7 +8,9 @@ void PrintLastError()
//Get the error message, if any. //Get the error message, if any.
DWORD errorMessageID = ::GetLastError(); DWORD errorMessageID = ::GetLastError();
if (errorMessageID == 0) if (errorMessageID == 0)
{
return; return;
}
LPSTR messageBuffer = nullptr; LPSTR messageBuffer = nullptr;
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
@ -21,12 +23,12 @@ void PrintLastError()
bool LaunchR5Apex() bool LaunchR5Apex()
{ {
FILE* sLaunchParams; FILE* sLaunchParams;
CHAR sArgumentBuffer[1024]; CHAR sArgumentBuffer[1024] = { 0 };
CHAR sCommandDirectory[MAX_PATH]; CHAR sCommandDirectory[MAX_PATH];
LPSTR sCommandLine = sCommandDirectory; LPSTR sCommandLine = sCommandDirectory;
#pragma warning(suppress : 4996) // '+exec autoexec -dev -fnf -noplatform'
sLaunchParams = fopen("launchparams.txt", "r"); // "+exec autoexec -dev -fnf -noplatform" fopen_s(&sLaunchParams, "launchparams.txt", "r");
BOOL result; BOOL result;
@ -44,7 +46,9 @@ bool LaunchR5Apex()
if (sLaunchParams) if (sLaunchParams)
{ {
while (fgets(sArgumentBuffer, sizeof(sArgumentBuffer), sLaunchParams) != NULL) while (fgets(sArgumentBuffer, sizeof(sArgumentBuffer), sLaunchParams) != NULL)
{
fclose(sLaunchParams); fclose(sLaunchParams);
}
} }
// Format the file paths for the game exe and dll. // Format the file paths for the game exe and dll.