2019-06-07 11:53:37 +08:00
|
|
|
#include "match.h"
|
|
|
|
#include "engine.h"
|
2018-08-23 23:53:23 +08:00
|
|
|
#include "main.h"
|
2020-03-05 16:51:36 +08:00
|
|
|
#include "defs.h"
|
2019-06-07 11:53:37 +08:00
|
|
|
#include "native/pchooks.h"
|
2016-01-05 23:01:17 +08:00
|
|
|
|
2019-02-28 00:33:17 +08:00
|
|
|
extern const char* HIJACK_ERROR;
|
|
|
|
|
2019-06-07 11:53:37 +08:00
|
|
|
uintptr_t processStartAddress, processStopAddress;
|
2016-01-05 23:01:17 +08:00
|
|
|
|
2019-06-07 11:53:37 +08:00
|
|
|
namespace Engine
|
2016-01-05 23:01:17 +08:00
|
|
|
{
|
2019-06-07 11:53:37 +08:00
|
|
|
WCHAR* processName, // cached
|
|
|
|
processPath[MAX_PATH]; // cached
|
2016-01-05 23:01:17 +08:00
|
|
|
|
2020-08-12 15:41:13 +08:00
|
|
|
char configFileData[1000]{};
|
2020-02-27 19:26:01 +08:00
|
|
|
|
2019-06-07 11:53:37 +08:00
|
|
|
bool UnsafeDetermineEngineType();
|
2016-01-05 23:01:17 +08:00
|
|
|
|
2019-06-07 11:53:37 +08:00
|
|
|
// jichi 10/21/2014: Return whether found the game engine
|
|
|
|
bool DetermineEngineType()
|
|
|
|
{
|
|
|
|
// jichi 9/27/2013: disable game engine for debugging use
|
|
|
|
bool found = false;
|
2018-09-04 06:43:43 +08:00
|
|
|
#ifndef ITH_DISABLE_ENGINE
|
2019-06-07 11:53:37 +08:00
|
|
|
__try { found = UnsafeDetermineEngineType(); }
|
|
|
|
__except (EXCEPTION_EXECUTE_HANDLER) { ConsoleOutput(HIJACK_ERROR); }
|
2018-09-04 06:43:43 +08:00
|
|
|
#endif // ITH_DISABLE_ENGINE
|
2019-06-07 11:53:37 +08:00
|
|
|
if (!found) { // jichi 10/2/2013: Only enable it if no game engine is detected
|
|
|
|
PcHooks::hookOtherPcFunctions();
|
|
|
|
} //else
|
|
|
|
// ConsoleOutput("vnreng: found game engine, IGNORE non gui hooks");
|
|
|
|
return found;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Hijack()
|
|
|
|
{
|
2021-01-15 21:07:23 +08:00
|
|
|
static auto _ = ([]
|
2019-06-07 11:53:37 +08:00
|
|
|
{
|
2019-06-17 03:28:59 +08:00
|
|
|
GetModuleFileNameW(nullptr, processPath, MAX_PATH);
|
|
|
|
processName = wcsrchr(processPath, L'\\') + 1;
|
2020-03-05 16:51:36 +08:00
|
|
|
wchar_t configFilename[MAX_PATH + std::size(GAME_CONFIG_FILE)];
|
2020-02-27 19:26:01 +08:00
|
|
|
wcsncpy_s(configFilename, processPath, MAX_PATH - 1);
|
2020-03-05 16:51:36 +08:00
|
|
|
wcscpy_s(wcsrchr(configFilename, L'\\') + 1, std::size(GAME_CONFIG_FILE), GAME_CONFIG_FILE);
|
2020-02-27 19:26:01 +08:00
|
|
|
if (AutoHandle<> configFile = CreateFileW(configFilename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL))
|
|
|
|
{
|
2020-08-12 15:41:13 +08:00
|
|
|
ReadFile(configFile, configFileData, sizeof(configFileData) - 1, DUMMY, nullptr);
|
2020-02-27 19:26:01 +08:00
|
|
|
if (strncmp(configFileData, "Engine:", 7) == 0)
|
|
|
|
{
|
|
|
|
if (loadedConfig = strchr(configFileData, '\n')) *(char*)loadedConfig++ = 0;
|
|
|
|
ConsoleOutput("Textractor: Engine = %s", requestedEngine = configFileData + 7);
|
|
|
|
}
|
|
|
|
else loadedConfig = configFileData;
|
2020-08-12 15:41:13 +08:00
|
|
|
if ((loadedConfig && !*loadedConfig) || strstr(configFileData, "https://")) loadedConfig = nullptr;
|
|
|
|
else ConsoleOutput("Textractor: game configuration loaded");
|
2020-02-27 19:26:01 +08:00
|
|
|
}
|
2019-06-17 03:28:59 +08:00
|
|
|
|
|
|
|
processStartAddress = processStopAddress = (uintptr_t)GetModuleHandleW(nullptr);
|
|
|
|
MEMORY_BASIC_INFORMATION info;
|
|
|
|
do
|
|
|
|
{
|
|
|
|
VirtualQuery((void*)processStopAddress, &info, sizeof(info));
|
|
|
|
processStopAddress = (uintptr_t)info.BaseAddress + info.RegionSize;
|
|
|
|
} while (info.Protect > PAGE_NOACCESS);
|
|
|
|
processStopAddress -= info.RegionSize;
|
|
|
|
spDefault.minAddress = processStartAddress;
|
|
|
|
spDefault.maxAddress = processStopAddress;
|
|
|
|
ConsoleOutput("Textractor: hijacking process located from 0x%p to 0x%p", processStartAddress, processStopAddress);
|
|
|
|
|
|
|
|
DetermineEngineType();
|
2021-03-08 23:41:34 +08:00
|
|
|
if (processStartAddress + 0x40000 > processStopAddress) ConsoleOutput("Textractor: WARNING injected process is very small, possibly a dummy!");
|
2021-01-15 21:07:23 +08:00
|
|
|
}(), 0);
|
2019-06-07 11:53:37 +08:00
|
|
|
}
|
2020-03-18 03:53:46 +08:00
|
|
|
|
|
|
|
bool ShouldMonoHook(const char* name)
|
|
|
|
{
|
|
|
|
if (!loadedConfig) return strstr(name, "string:") && !strstr(name, "string:mem");
|
|
|
|
for (const char* hook = loadedConfig; hook; hook = strchr(hook + 1, '\t'))
|
|
|
|
for (auto start = name; *start; ++start)
|
|
|
|
for (int i = 0; ; ++i)
|
|
|
|
if (start[i] != hook[i + 1]) break;
|
|
|
|
else if (!hook[i + 2] || hook[i + 2] == '\t') return true;
|
|
|
|
return false;
|
|
|
|
}
|
2016-01-05 23:01:17 +08:00
|
|
|
}
|