mirror of
https://github.com/Artikash/Textractor.git
synced 2024-12-23 08:54:12 +08:00
dont remove mono if flooding, instead use config file for which hook to insert
This commit is contained in:
parent
565f99cced
commit
c8853a1af8
@ -58,7 +58,6 @@ void TextThread::Push(BYTE* data, int length)
|
||||
if (std::all_of(buffer.begin(), buffer.end(), [&](wchar_t ch) { return repeatingChars.find(ch) != repeatingChars.end(); })) buffer.clear();
|
||||
if (RemoveRepetition(buffer)) // sentence repetition detected, which means the entire sentence has already been received
|
||||
{
|
||||
if (hp.type & BLOCK_FLOOD) Host::RemoveHook(tp.processId, tp.addr);
|
||||
repeatingChars = std::unordered_set(buffer.begin(), buffer.end());
|
||||
AddSentence(std::move(buffer));
|
||||
buffer.clear();
|
||||
@ -88,7 +87,6 @@ void TextThread::Flush()
|
||||
sentence.erase(std::remove(sentence.begin(), sentence.end(), L'\0'));
|
||||
if (Output(*this, sentence)) storage->append(sentence);
|
||||
}
|
||||
if (hp.type & BLOCK_FLOOD && totalSize > PIPE_BUFFER_SIZE) Host::RemoveHook(tp.processId, tp.addr);
|
||||
|
||||
std::scoped_lock lock(bufferMutex);
|
||||
if (buffer.empty()) return;
|
||||
|
@ -4,7 +4,7 @@
|
||||
// 8/23/2013 jichi
|
||||
// Branch: ITH/common.h, rev 128
|
||||
|
||||
enum { STRING = 12, MESSAGE_SIZE = 500, PIPE_BUFFER_SIZE = 10000, SHIFT_JIS = 932, MAX_MODULE_SIZE = 120, PATTERN_SIZE = 30, HOOK_NAME_SIZE = 30, FIXED_SPLIT_VALUE = 0x10001 };
|
||||
enum { STRING = 12, MESSAGE_SIZE = 500, PIPE_BUFFER_SIZE = 10000, SHIFT_JIS = 932, MAX_MODULE_SIZE = 120, PATTERN_SIZE = 30, HOOK_NAME_SIZE = 60, FIXED_SPLIT_VALUE = 0x10001 };
|
||||
enum WildcardByte { XX = 0x11 };
|
||||
|
||||
enum HostCommandType { HOST_COMMAND_NEW_HOOK, HOST_COMMAND_REMOVE_HOOK, HOST_COMMAND_FIND_HOOK, HOST_COMMAND_MODIFY_HOOK, HOST_COMMAND_HIJACK_PROCESS, HOST_COMMAND_DETACH };
|
||||
@ -27,8 +27,7 @@ enum HookParamType : unsigned
|
||||
FIXING_SPLIT = 0x800,
|
||||
DIRECT_READ = 0x1000, // /R read code instead of classic /H hook code
|
||||
FULL_STRING = 0x2000,
|
||||
BLOCK_FLOOD = 0x4000, // remove this hook if flooding text causing perf issues
|
||||
HEX_DUMP = 0x8000,
|
||||
HOOK_ENGINE = 0x10000,
|
||||
HOOK_ADDITIONAL = 0x20000,
|
||||
HEX_DUMP = 0x4000,
|
||||
HOOK_ENGINE = 0x8000,
|
||||
HOOK_ADDITIONAL = 0x10000,
|
||||
};
|
||||
|
@ -16717,6 +16717,7 @@ void InsertMonoHook(HMODULE h)
|
||||
if (!getDomain || !getName || !getJitInfo) goto failed;
|
||||
static auto domain = getDomain();
|
||||
if (!domain) goto failed;
|
||||
ConsoleOutput("Textractor: Mono Dynamic ENTER (hook = %s)", loadedConfig ? loadedConfig : "brute force");
|
||||
const BYTE prolog[] = { 0x55, 0x8b, 0xec };
|
||||
for (auto addr : Util::SearchMemory(prolog, sizeof(prolog), PAGE_EXECUTE_READWRITE))
|
||||
{
|
||||
@ -16726,24 +16727,29 @@ void InsertMonoHook(HMODULE h)
|
||||
{
|
||||
if (getJitInfo(domain, addr))
|
||||
if (char* name = getName(addr))
|
||||
if (strstr(name, "string:") && !strstr(name, "string:mem"))
|
||||
if ((!loadedConfig && strstr(name, "string:") && !strstr(name, "string:mem")) || (loadedConfig && strstr(name, loadedConfig)))
|
||||
{
|
||||
HookParam hp = {};
|
||||
hp.address = addr;
|
||||
hp.type = USING_UNICODE | FULL_STRING | BLOCK_FLOOD;
|
||||
hp.type = USING_UNICODE | FULL_STRING;
|
||||
hp.offset = 4;
|
||||
char nameForUser[HOOK_NAME_SIZE] = {};
|
||||
strncpy_s(nameForUser, name + 1, HOOK_NAME_SIZE - 1);
|
||||
if (char* end = strstr(nameForUser, " + 0x0")) *end = 0;
|
||||
hp.text_fun = [](DWORD esp_base, HookParam*, BYTE, DWORD* data, DWORD* split, DWORD* len)
|
||||
{
|
||||
MonoString* string = (MonoString*)argof(1, esp_base);
|
||||
*data = (DWORD)string->chars;
|
||||
*len = string->length * 2;
|
||||
};
|
||||
NewHook(hp, name);
|
||||
NewHook(hp, nameForUser);
|
||||
}
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {}
|
||||
}(addr);
|
||||
}
|
||||
if (!loadedConfig) ConsoleOutput("Textractor: Mono Dynamic used brute force: if performance issues arise, please create a TextractorConfig.txt file"
|
||||
"next to the main executable and put the name of a working hook inside it");
|
||||
return true;
|
||||
failed:
|
||||
ConsoleOutput("Textractor: Mono Dynamic failed");
|
||||
|
@ -15,6 +15,7 @@ namespace Engine {
|
||||
// Global variables
|
||||
extern wchar_t *processName, // cached
|
||||
processPath[MAX_PATH]; // cached
|
||||
inline const char *requestedEngine = nullptr, *loadedConfig = nullptr;
|
||||
|
||||
// Artikash 6/17/2019 TODO: These have the wrong values on x64
|
||||
/** jichi 12/24/2014
|
||||
|
@ -12,6 +12,8 @@ namespace Engine
|
||||
WCHAR* processName, // cached
|
||||
processPath[MAX_PATH]; // cached
|
||||
|
||||
char configFileData[1000];
|
||||
|
||||
bool UnsafeDetermineEngineType();
|
||||
|
||||
// jichi 10/21/2014: Return whether found the game engine
|
||||
@ -41,6 +43,19 @@ namespace Engine
|
||||
{
|
||||
GetModuleFileNameW(nullptr, processPath, MAX_PATH);
|
||||
processName = wcsrchr(processPath, L'\\') + 1;
|
||||
wchar_t configFilename[MAX_PATH + sizeof(L"TextractorConfig.txt")];
|
||||
wcsncpy_s(configFilename, processPath, MAX_PATH - 1);
|
||||
wcscpy_s(wcsrchr(configFilename, L'\\') + 1, sizeof(L"TextractorConfig.txt"), L"TextractorConfig.txt");
|
||||
if (AutoHandle<> configFile = CreateFileW(configFilename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL))
|
||||
{
|
||||
if (ReadFile(configFile, configFileData, sizeof(configFileData) - 1, DUMMY, nullptr)) ConsoleOutput("Textractor: game configuration loaded");
|
||||
if (strncmp(configFileData, "Engine:", 7) == 0)
|
||||
{
|
||||
if (loadedConfig = strchr(configFileData, '\n')) *(char*)loadedConfig++ = 0;
|
||||
ConsoleOutput("Textractor: Engine = %s", requestedEngine = configFileData + 7);
|
||||
}
|
||||
else loadedConfig = configFileData;
|
||||
}
|
||||
|
||||
processStartAddress = processStopAddress = (uintptr_t)GetModuleHandleW(nullptr);
|
||||
MEMORY_BASIC_INFORMATION info;
|
||||
|
@ -80,6 +80,7 @@ namespace Engine
|
||||
if (!getDomain || !getName || !getJitInfo) goto failed;
|
||||
static auto domain = getDomain();
|
||||
if (!domain) goto failed;
|
||||
ConsoleOutput("Textractor: Mono Dynamic ENTER (hook = %s)", loadedConfig ? loadedConfig : "brute force");
|
||||
const BYTE prolog1[] = { 0x55, 0x48, 0x8b, 0xec };
|
||||
const BYTE prolog2[] = { 0x48, 0x83, 0xec };
|
||||
for (auto [prolog, size] : Array<const BYTE*, size_t>{ { prolog1, sizeof(prolog1) }, { prolog2, sizeof(prolog2) } })
|
||||
@ -91,13 +92,17 @@ namespace Engine
|
||||
{
|
||||
if (getJitInfo(domain, addr))
|
||||
if (char* name = getName(addr))
|
||||
if (strstr(name, "string:") && strstr(name, "+ 0x0") && !strstr(name, "string:mem"))
|
||||
if ((!loadedConfig && strstr(name, "string:") && strstr(name, "+ 0x0") && !strstr(name, "string:mem")) ||
|
||||
loadedConfig && strstr(name, loadedConfig) && strstr(name, "+ 0x0"))
|
||||
{
|
||||
HookParam hp = {};
|
||||
hp.address = addr;
|
||||
hp.type = USING_STRING | USING_UNICODE | BLOCK_FLOOD | FULL_STRING;
|
||||
hp.type = USING_STRING | USING_UNICODE | FULL_STRING;
|
||||
hp.offset = -0x20; // rcx
|
||||
hp.padding = 20;
|
||||
char nameForUser[HOOK_NAME_SIZE] = {};
|
||||
strncpy_s(nameForUser, name + 1, HOOK_NAME_SIZE - 1);
|
||||
if (char* end = strstr(nameForUser, " + 0x0")) *end = 0;
|
||||
hp.length_fun = [](uintptr_t, uintptr_t data)
|
||||
{
|
||||
/* Artikash 6/18/2019:
|
||||
@ -106,12 +111,14 @@ namespace Engine
|
||||
int len = *(int*)(data - 4);
|
||||
return len > 0 && len < PIPE_BUFFER_SIZE ? len * 2 : 0;
|
||||
};
|
||||
NewHook(hp, name);
|
||||
NewHook(hp, nameForUser);
|
||||
}
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER) {}
|
||||
}(addr);
|
||||
}
|
||||
if (!loadedConfig) ConsoleOutput("Textractor: Mono Dynamic used brute force: if performance issues arise, please create a TextractorConfig.txt file"
|
||||
"next to the main executable and put the name of a working hook inside it");
|
||||
return true;
|
||||
failed:
|
||||
ConsoleOutput("Textractor: Mono Dynamic failed");
|
||||
|
Loading…
x
Reference in New Issue
Block a user