forked from Public-Mirror/Textractor
Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
22946df452 | |||
3b22857d12 |
@ -8,26 +8,9 @@ macro(msvc_registry_search)
|
||||
string(REPLACE "/Tools" ";" QT_ROOT "${QT_ROOT}")
|
||||
list(GET QT_ROOT 0 QT_ROOT)
|
||||
endif()
|
||||
file(GLOB QT_VERSIONS "${QT_ROOT}/5.13*")
|
||||
list(SORT QT_VERSIONS)
|
||||
|
||||
# assume the latest version will be last alphabetically
|
||||
list(REVERSE QT_VERSIONS)
|
||||
|
||||
list(GET QT_VERSIONS 0 QT_VERSION)
|
||||
|
||||
# fix any double slashes which seem to be common
|
||||
string(REPLACE "//" "/" QT_VERSION "${QT_VERSION}")
|
||||
|
||||
if(MSVC_VERSION GREATER_EQUAL 1920)
|
||||
set(QT_VERSION 5.13.2)
|
||||
set(QT_MSVC 2019)
|
||||
elseif(MSVC_VERSION GREATER_EQUAL 1910)
|
||||
set(QT_MSVC 2017)
|
||||
elseif(MSVC_VERSION GREATER_EQUAL 1900)
|
||||
set(QT_MSVC 2015)
|
||||
else()
|
||||
message(WARNING "Unsupported MSVC toolchain version")
|
||||
endif()
|
||||
|
||||
if(QT_MSVC)
|
||||
if(CMAKE_CL_64)
|
||||
@ -35,17 +18,7 @@ macro(msvc_registry_search)
|
||||
else()
|
||||
set(QT_SUFFIX "")
|
||||
endif()
|
||||
|
||||
# MSVC 2015+ is only backwards compatible
|
||||
if(EXISTS "${QT_VERSION}/msvc${QT_MSVC}${QT_SUFFIX}")
|
||||
set(Qt5_DIR "${QT_VERSION}/msvc${QT_MSVC}${QT_SUFFIX}/lib/cmake/Qt5")
|
||||
elseif(QT_MSVC GREATER_EQUAL 2019 AND EXISTS "${QT_VERSION}/msvc2017${QT_SUFFIX}")
|
||||
set(Qt5_DIR "${QT_VERSION}/msvc2017${QT_SUFFIX}/lib/cmake/Qt5")
|
||||
elseif(QT_MSVC GREATER_EQUAL 2017 AND EXISTS "${QT_VERSION}/msvc2015${QT_SUFFIX}")
|
||||
set(Qt5_DIR "${QT_VERSION}/msvc2015${QT_SUFFIX}/lib/cmake/Qt5")
|
||||
else()
|
||||
message(WARNING "Required QT5 toolchain is not installed")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
@ -55,6 +28,11 @@ macro(find_qt5)
|
||||
#set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
#add_definitions(-DQT_DEPRECATED_WARNINGS -DQT_DISABLE_DEPRECATED_BEFORE=0x060000)
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
set(Qt5_DIR "C:/Qt/Qt5.13.2/5.13.2/msvc2017_64/lib/cmake/Qt5")
|
||||
else()
|
||||
set(Qt5_DIR "C:/Qt/Qt5.13.2/5.13.2/msvc2017/lib/cmake/Qt5")
|
||||
endif()
|
||||
find_package(Qt5 COMPONENTS ${ARGN})
|
||||
|
||||
if(Qt5_FOUND)
|
||||
|
@ -9,43 +9,52 @@ const char* TRANSLATION_PROVIDER = "DeepL Translate";
|
||||
const char* GET_API_KEY_FROM = "https://www.deepl.com/pro.html#developer";
|
||||
extern const QStringList languagesTo
|
||||
{
|
||||
"Arabic",
|
||||
"Bulgarian",
|
||||
"Chinese (Simplified)",
|
||||
"Czech",
|
||||
"Danish",
|
||||
"Dutch",
|
||||
"English (American)",
|
||||
"German",
|
||||
"Greek",
|
||||
"English (backward compatibility)",
|
||||
"English (British)",
|
||||
"English (American)",
|
||||
"Spanish",
|
||||
"Estonian",
|
||||
"Finnish",
|
||||
"French",
|
||||
"German",
|
||||
"Greek",
|
||||
"Hungarian",
|
||||
"Indonesian",
|
||||
"Italian",
|
||||
"Japanese",
|
||||
"Latvian",
|
||||
"Korean",
|
||||
"Lithuanian",
|
||||
"Latvian",
|
||||
"Norwegian Bokmål",
|
||||
"Dutch",
|
||||
"Polish",
|
||||
"Portuguese (Brazil)",
|
||||
"Portuguese (Portugal)",
|
||||
"Portuguese (backward compatibility)",
|
||||
"Portuguese (Brazilian)",
|
||||
"Portuguese (all Portuguese variants excluding Brazilian Portuguese)",
|
||||
"Romanian",
|
||||
"Russian",
|
||||
"Slovak",
|
||||
"Slovenian",
|
||||
"Spanish",
|
||||
"Swedish",
|
||||
"Turkish"
|
||||
"Turkish",
|
||||
"Ukrainian",
|
||||
"Chinese (backward compatibility)",
|
||||
"Chinese (simplified)",
|
||||
"Chinese (traditional)"
|
||||
},
|
||||
languagesFrom
|
||||
{
|
||||
"Arabic",
|
||||
"Bulgarian",
|
||||
"Chinese",
|
||||
"Chinese (all Chinese variants)",
|
||||
"Czech",
|
||||
"Danish",
|
||||
"Dutch",
|
||||
"English",
|
||||
"English (all English variants)",
|
||||
"Estonian",
|
||||
"Finnish",
|
||||
"French",
|
||||
@ -55,52 +64,64 @@ languagesFrom
|
||||
"Indonesian",
|
||||
"Italian",
|
||||
"Japanese",
|
||||
"Korean",
|
||||
"Latvian",
|
||||
"Lithuanian",
|
||||
"Norwegian Bokmål",
|
||||
"Polish",
|
||||
"Portuguese",
|
||||
"Portuguese (all Portuguese variants)",
|
||||
"Romanian",
|
||||
"Russian",
|
||||
"Slovak",
|
||||
"Slovenian",
|
||||
"Spanish",
|
||||
"Swedish",
|
||||
"Turkish"
|
||||
"Turkish",
|
||||
"Ukrainian"
|
||||
};
|
||||
extern const std::unordered_map<std::wstring, std::wstring> codes
|
||||
{
|
||||
{ { L"Arabic" }, { L"AR" } },
|
||||
{ { L"Bulgarian" }, { L"BG" } },
|
||||
{ { L"Chinese" }, { L"ZH" } },
|
||||
{ { L"Chinese (Simplified)" }, { L"ZH" } },
|
||||
{ { L"Czech" }, { L"CS" } },
|
||||
{ { L"Danish" }, { L"DA" } },
|
||||
{ { L"Dutch" }, { L"NL" } },
|
||||
{ { L"English" }, { L"EN" } },
|
||||
{ { L"English (American)" }, { L"EN-US" } },
|
||||
{ { L"German" }, { L"DE" } },
|
||||
{ { L"Greek" }, { L"EL" } },
|
||||
{ { L"English (all English variants)" }, { L"EN" } },
|
||||
{ { L"English (backward compatibility)" }, { L"EN" } },
|
||||
{ { L"English (British)" }, { L"EN-GB" } },
|
||||
{ { L"English (American)" }, { L"EN-US" } },
|
||||
{ { L"Spanish" }, { L"ES" } },
|
||||
{ { L"Estonian" }, { L"ET" } },
|
||||
{ { L"Finnish" }, { L"FI" } },
|
||||
{ { L"French" }, { L"FR" } },
|
||||
{ { L"German" }, { L"DE" } },
|
||||
{ { L"Greek" }, { L"EL" } },
|
||||
{ { L"Hungarian" }, { L"HU" } },
|
||||
{ { L"Indonesian" }, { L"ID" } },
|
||||
{ { L"Italian" }, { L"IT" } },
|
||||
{ { L"Japanese" }, { L"JA" } },
|
||||
{ { L"Latvian" }, { L"LV" } },
|
||||
{ { L"Korean" }, { L"KO" } },
|
||||
{ { L"Lithuanian" }, { L"LT" } },
|
||||
{ { L"Latvian" }, { L"LV" } },
|
||||
{ { L"Norwegian Bokmål" }, { L"NB" } },
|
||||
{ { L"Dutch" }, { L"NL" } },
|
||||
{ { L"Polish" }, { L"PL" } },
|
||||
{ { L"Portuguese" }, { L"PT" } },
|
||||
{ { L"Portuguese (Brazil)" }, { L"PT-BR" } },
|
||||
{ { L"Portuguese (Portugal)" }, { L"PT-PT" } },
|
||||
{ { L"Portuguese (all Portuguese variants)" }, { L"PT" } },
|
||||
{ { L"Portuguese (backward compatibility)" }, { L"PT" } },
|
||||
{ { L"Portuguese (Brazilian)" }, { L"PT-BR" } },
|
||||
{ { L"Portuguese (all Portuguese variants excluding Brazilian Portuguese)" }, { L"PT-PT" } },
|
||||
{ { L"Romanian" }, { L"RO" } },
|
||||
{ { L"Russian" }, { L"RU" } },
|
||||
{ { L"Slovak" }, { L"SK" } },
|
||||
{ { L"Slovenian" }, { L"SL" } },
|
||||
{ { L"Spanish" }, { L"ES" } },
|
||||
{ { L"Swedish" }, { L"SV" } },
|
||||
{ { L"Turkish" }, { L"TR" } },
|
||||
{ { L"Ukrainian" }, { L"UK" } },
|
||||
{ { L"Chinese (all Chinese variants)" }, { L"ZH" } },
|
||||
{ { L"Chinese (backward compatibility)" }, { L"ZH" } },
|
||||
{ { L"Chinese (simplified)" }, { L"ZH-HANS" } },
|
||||
{ { L"Chinese (traditional)" }, { L"ZH-HANT" } },
|
||||
{ { L"?" }, { L"auto" } }
|
||||
|
||||
};
|
||||
|
||||
bool translateSelectedOnly = true, useRateLimiter = true, rateLimitSelected = true, useCache = true, useFilter = true;
|
||||
|
@ -27,6 +27,7 @@
|
||||
//#include <boost/foreach.hpp>
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
// jichi 375/2014: Add offset of pusha/pushad
|
||||
// http://faydoc.tripod.com/cpu/pushad.htm
|
||||
@ -6351,9 +6352,267 @@ static bool InsertYuris2Hook()
|
||||
NewHook(hp, "YU-RIS2");
|
||||
return true;
|
||||
}
|
||||
static bool Yuris3Filter(LPVOID data, DWORD* size, HookParam*, BYTE)
|
||||
{
|
||||
static wchar_t prev_text;
|
||||
wchar_t* pText = reinterpret_cast<wchar_t*>(data);
|
||||
|
||||
if (prev_text == *pText)
|
||||
{
|
||||
prev_text = '\0';
|
||||
return false;
|
||||
}
|
||||
prev_text = *pText;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool InsertYuris3Hook()
|
||||
{
|
||||
//by Blu3train
|
||||
HookParam hp = {};
|
||||
wcsncpy_s(hp.module, L"kernel32.dll", MAX_MODULE_SIZE - 1);
|
||||
strncpy_s(hp.function, "MultiByteToWideChar", MAX_MODULE_SIZE - 1);
|
||||
hp.address = 6;
|
||||
hp.offset = 0xC; //arg3
|
||||
hp.index = 0;
|
||||
hp.split = 0x1C;
|
||||
hp.split_index = 0;
|
||||
hp.filter_fun = Yuris3Filter;
|
||||
hp.type = USING_STRING | USING_SPLIT | MODULE_OFFSET | FUNCTION_OFFSET;
|
||||
hp.length_offset = 0x10 / (short)sizeof(void*); // arg4/arg_sz
|
||||
ConsoleOutput("vnreng: INSERT YU-RIS 3");
|
||||
NewHook(hp, "YU-RIS3");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InsertYuris4Hook()
|
||||
{
|
||||
//by Blu3train
|
||||
/*
|
||||
* Sample games:
|
||||
* https://vndb.org/v6540
|
||||
*/
|
||||
bool found = false;
|
||||
const BYTE pattern[] = {
|
||||
0x52, // 52 push edx
|
||||
0x68, 0x00, 0x42, 0x5C, 0x00, // 68 00425C00 push euphoria.exe+1C4200
|
||||
0xFF, 0x15, 0x90, 0x44, 0x7E, 0x00, // FF 15 90447E00 call dword ptr [euphoria.exe+3E4490]
|
||||
0x83, 0xC4, 0x0C, // 83 C4 0C add esp,0C
|
||||
0xEB, 0x5F, // EB 5F jmp euphoria.exe+4F4C5
|
||||
0xFF, 0x35, 0xA4, 0x19, 0x66, 0x00, // FF 35 A4196600 push [euphoria.exe+2619A4]
|
||||
0x52 // 52 push edx
|
||||
};
|
||||
enum { addr_offset = 12 }; // distance to the beginning of the function, which is 0x83, 0xC4, 0x0C (add esp,0C)
|
||||
|
||||
for (auto addr : Util::SearchMemory(pattern, sizeof(pattern), PAGE_EXECUTE, processStartAddress, processStopAddress))
|
||||
{
|
||||
HookParam hp = {};
|
||||
hp.address = addr + addr_offset;
|
||||
hp.offset = pusha_edx_off - 4;
|
||||
hp.type = USING_STRING;
|
||||
ConsoleOutput("Textractor: INSERT YU-RIS 4");
|
||||
NewHook(hp, "YU-RIS4");
|
||||
found = true;
|
||||
}
|
||||
if (!found) ConsoleOutput("Textractor:YU-RIS 4: pattern not found");
|
||||
return found;
|
||||
}
|
||||
|
||||
bool InsertYuris5Hook()
|
||||
{
|
||||
//by Blu3train
|
||||
/*
|
||||
* Sample games:
|
||||
* https://vndb.org/v4037
|
||||
*/
|
||||
const BYTE bytes[] = {
|
||||
0x33, 0xD2, // xor edx,edx
|
||||
0x88, 0x14, 0x0F, // mov [edi+ecx],dl
|
||||
0xA1, XX4, // mov eax,[exe+2DE630]
|
||||
0x8B, 0x78, 0x3C, // mov edi,[eax+3C]
|
||||
0x8B, 0x58, 0x5C, // mov ebx,[eax+5C]
|
||||
0x88, 0x14, 0x3B // mov [ebx+edi],dl
|
||||
};
|
||||
|
||||
enum { addr_offset = 0 }; // distance to the beginning of the function, which is 0x55 (push ebp)
|
||||
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
|
||||
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
|
||||
if (!addr)
|
||||
return false;
|
||||
|
||||
HookParam hp = {};
|
||||
hp.address = addr + addr_offset;
|
||||
hp.offset = pusha_ecx_off - 4;
|
||||
hp.type = USING_STRING | NO_CONTEXT;
|
||||
|
||||
ConsoleOutput("Textractor: INSERT YU-RIS 5");
|
||||
NewHook(hp, "YU-RIS5");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool Yuris6Filter(LPVOID data, DWORD* size, HookParam*, BYTE)
|
||||
{
|
||||
auto text = reinterpret_cast<LPSTR>(data);
|
||||
auto len = reinterpret_cast<size_t*>(size);
|
||||
static std::string prevText;
|
||||
|
||||
if (prevText.length() == *len && prevText.find(text, 0, *len) != std::string::npos) // Check if the string is present in the previous one
|
||||
return false;
|
||||
prevText.assign(text, *len);
|
||||
|
||||
// ruby <手水舎/ちょうずや>
|
||||
if (cpp_strnstr(text, "\x81\x83", *len)) { // \x81\x83 -> '<'
|
||||
StringFilterBetween(text, len, "\x81\x5E", 2, "\x81\x84", 2); // \x81\x5E -> '/' , \x81\x84 -> '>'
|
||||
StringFilter(text, len, "\x81\x83", 2); // \x81\x83 -> '<'
|
||||
}
|
||||
// ruby ≪美桜/姉さん≫
|
||||
else if (cpp_strnstr(text, "\x81\xE1", *len)) { // \x81\xE1 -> '≪'
|
||||
StringFilterBetween(text, len, "\x81\x5E", 2, "\x81\xE2", 2); // \x81\x5E -> '/' , \x81\xE2 -> '≫'
|
||||
StringFilter(text, len, "\x81\xE1", 2); // \x81\xE1 -> '≪'
|
||||
}
|
||||
|
||||
CharReplacer(text, len, '=', '-');
|
||||
StringCharReplacer(text, len, "\xEF\xF0", 2, ' ');
|
||||
StringFilter(text, len, "\xEF\xF2", 2);
|
||||
StringFilter(text, len, "\xEF\xF5", 2);
|
||||
StringFilter(text, len, "\x81\x98", 2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InsertYuris6Hook()
|
||||
{
|
||||
//by Blu3train
|
||||
/*
|
||||
* Sample games:
|
||||
* https://vndb.org/v40058
|
||||
* https://vndb.org/v42883
|
||||
* https://vndb.org/v44092
|
||||
* https://vndb.org/v21171
|
||||
* https://vndb.org/r46910
|
||||
*/
|
||||
const BYTE bytes[] = {
|
||||
0xE9, XX4, // jmp oshitona01.exe+1B629
|
||||
0xBF, XX4, // mov edi,oshitona01.exe+24EEA0
|
||||
0x8A, 0x17, // mov dl,[edi]
|
||||
0x47, // inc edi
|
||||
0x88, 0x16, // mov [esi],dl
|
||||
0x46, // inc esi
|
||||
0x84, 0xD2 // test dl,dl
|
||||
};
|
||||
|
||||
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
|
||||
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
|
||||
if (!addr)
|
||||
return false;
|
||||
|
||||
HookParam hp = {};
|
||||
hp.address = addr;
|
||||
hp.offset = pusha_eax_off - 4;
|
||||
hp.index = 0x38;
|
||||
hp.codepage = 65001;
|
||||
hp.filter_fun = Yuris6Filter;
|
||||
hp.type = USING_STRING | NO_CONTEXT | DATA_INDIRECT;
|
||||
|
||||
ConsoleOutput("Textractor: INSERT YU-RIS 6");
|
||||
NewHook(hp, "YU-RIS6");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InsertYuris7Hook()
|
||||
{
|
||||
//by Blu3train
|
||||
/*
|
||||
* Sample games:
|
||||
* https://vndb.org/v45381
|
||||
* https://vndb.org/v47458
|
||||
* https://vndb.org/v21144
|
||||
* https://vndb.org/v18681
|
||||
*/
|
||||
const BYTE bytes[] = {
|
||||
0x03, 0xC1, // add eax,ecx
|
||||
0x99, // cdq
|
||||
0xE9, XX4 // jmp nekonin_spin.exe+55753 << hook here
|
||||
};
|
||||
enum { addr_offset = sizeof(bytes) - 5 };
|
||||
|
||||
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
|
||||
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
|
||||
if (!addr)
|
||||
return false;
|
||||
|
||||
HookParam hp = {};
|
||||
hp.address = addr + addr_offset;
|
||||
hp.offset = pusha_eax_off - 4;
|
||||
hp.index = 0;
|
||||
hp.length_offset = 1; // only 1 character
|
||||
hp.text_fun = [](DWORD esp_base, HookParam*, BYTE, DWORD*, DWORD*, DWORD* len)
|
||||
{
|
||||
*len = (retof(esp_base) == 0) ? 2 : 0;
|
||||
};
|
||||
hp.type = BIG_ENDIAN;
|
||||
ConsoleOutput("vnreng: INSERT YU-RIS7");
|
||||
NewHook(hp, "YU-RIS7");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InsertYuris8Hook()
|
||||
{
|
||||
//by Blu3train
|
||||
/*
|
||||
* Sample games:
|
||||
* https://vndb.org/v47458
|
||||
* https://vndb.org/v45381
|
||||
*/
|
||||
const BYTE bytes[] = {
|
||||
0x57, // push edi << hook here
|
||||
0x56, // push esi
|
||||
0x55, // push ebp
|
||||
0x53, // push ebx
|
||||
0x83, 0xEC, 0x10, // sub esp,10
|
||||
0x8B, 0x5C, 0x24, 0x24, // mov ebx,[esp+24]
|
||||
0x8B, 0x15, XX4, // mov edx,[hajiron.exe+47243C]
|
||||
0x8B, 0x0C, 0x9A, // mov ecx,[edx+ebx*4]
|
||||
0xC6, 0x41, 0x01, 0x03, // mov byte ptr [ecx+01],03
|
||||
0x8B, 0xC3, // mov eax,ebx
|
||||
0xE8,XX4 // call hajiron.exe+54EA4
|
||||
};
|
||||
|
||||
ULONG range = min(processStopAddress - processStartAddress, MAX_REL_ADDR);
|
||||
ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStartAddress + range);
|
||||
if (!addr)
|
||||
return false;
|
||||
|
||||
HookParam hp = {};
|
||||
hp.address = addr;
|
||||
hp.offset = pusha_edx_off - 4;
|
||||
hp.index = 0;
|
||||
hp.text_fun = [](DWORD esp_base, HookParam*, BYTE, DWORD*, DWORD*, DWORD* len)
|
||||
{
|
||||
DWORD textLen = regof(eax, esp_base);
|
||||
if (textLen > 2)
|
||||
return;
|
||||
*len = (regof(edi, esp_base) >= 0xFA && regof(edi, esp_base) <= 0xFE || regof(edi, esp_base) >= 0x1A0 && regof(edi, esp_base) <= 0x1C2) ? textLen : 0;
|
||||
};
|
||||
hp.type = USING_STRING;
|
||||
ConsoleOutput("vnreng: INSERT YU-RIS8");
|
||||
NewHook(hp, "YU-RIS8");
|
||||
return true;
|
||||
}
|
||||
bool InsertYurisHook()
|
||||
{ return InsertYuris1Hook() || InsertYuris2Hook(); }
|
||||
{
|
||||
bool ok = InsertYuris1Hook();
|
||||
ok = InsertYuris2Hook() || ok;
|
||||
ok = InsertYuris3Hook() || ok;
|
||||
ok = InsertYuris4Hook() || ok;
|
||||
ok = InsertYuris5Hook() || ok;
|
||||
ok = InsertYuris6Hook() || ok;
|
||||
ok = InsertYuris7Hook() || ok;
|
||||
ok = InsertYuris8Hook() || ok;
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool InsertCotophaHook1()
|
||||
{
|
||||
@ -21026,6 +21285,84 @@ bool InsertTecmoPSPHook()
|
||||
}
|
||||
#endif // 0
|
||||
|
||||
|
||||
//for debug
|
||||
void StringBlockProcessor(char* str, size_t* size, size_t fixlength)
|
||||
{
|
||||
size_t original_len = *size;
|
||||
size_t new_len = 0;
|
||||
char* new_str = new char[original_len + 1];
|
||||
|
||||
size_t i = 0;
|
||||
while (i < original_len) {
|
||||
size_t block_end = i + fixlength;
|
||||
if (block_end > original_len) {
|
||||
block_end = original_len;
|
||||
}
|
||||
|
||||
size_t block_len = block_end - i;
|
||||
char* block = str + i;
|
||||
|
||||
for (size_t j = 0; j < block_len; ++j) {
|
||||
if (block[j] != 0) {
|
||||
new_str[new_len++] = block[j];
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
i = block_end;
|
||||
}
|
||||
|
||||
new_str[new_len] = '\0';
|
||||
|
||||
std::memcpy(str, new_str, new_len + 1);
|
||||
*size = new_len;
|
||||
delete[] new_str;
|
||||
}
|
||||
|
||||
bool DACFilter(LPVOID data, DWORD* size, HookParam*, BYTE)
|
||||
{
|
||||
auto text = reinterpret_cast<LPSTR>(data);
|
||||
auto len = reinterpret_cast<size_t*>(size);
|
||||
|
||||
StringBlockProcessor(text, len, 0x3f);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InsertDACHook()
|
||||
{
|
||||
const BYTE bytecodes[] = {
|
||||
0x0F, 0xBF, 0x56, 0x34, // movsx edx, word ptr ds:[esi+34]
|
||||
0x83, 0xC2, 0x05, // add edx, 5
|
||||
0x8B, 0x8E, 0x00, 0x01, 0x00, 0x00, // mov ecx, dword ptr ds:[esi+100]
|
||||
0x0F, 0xAF, 0xD3 // imul edx, ebx <--
|
||||
};
|
||||
|
||||
ULONG addr = MemDbg::findBytes(bytecodes, sizeof(bytecodes), processStartAddress, processStopAddress);
|
||||
if (addr == 0) {
|
||||
ConsoleOutput("vnreng:DAC: pattern not found");
|
||||
return false;
|
||||
}
|
||||
enum { addr_offset = 13 };
|
||||
|
||||
HookParam hp = {};
|
||||
hp.type = USING_STRING; //S
|
||||
hp.address = addr + addr_offset;
|
||||
hp.offset = pusha_ecx_off - 4; //-C
|
||||
hp.index = 0x00;
|
||||
hp.filter_fun = DACFilter;
|
||||
hp.length_fun = [](uintptr_t, uintptr_t data)
|
||||
{
|
||||
int len = 0x3f;
|
||||
return len * 4;
|
||||
};
|
||||
NewHook(hp, "DAC");
|
||||
ConsoleOutput("vnreng: INSERT DAC");
|
||||
return true;
|
||||
}
|
||||
|
||||
/** jichi 7/19/2014 PCSX2
|
||||
* Tested wit pcsx2-v1.2.1-328-gef0e3fe-windows-x86, built at http://buildbot.orphis.net/pcsx2
|
||||
*/
|
||||
@ -21261,7 +21598,6 @@ bool InsertTypeMoonPS2Hook()
|
||||
ConsoleOutput("vnreng: TypeMoon PS2: leave");
|
||||
return addr;
|
||||
}
|
||||
|
||||
/** 8/3/2014 jichi
|
||||
* Tested game: School Rumble ねる娘<EFBFBD>育つ
|
||||
*
|
||||
|
@ -96,6 +96,7 @@ bool InsertCandyHook(); // SystemC@CandySoft: *.fpk
|
||||
bool InsertCatSystemHook(); // CatSystem2: *.int
|
||||
bool InsertCMVSHook(); // CMVS: data/pack/*.cpz; do not support the latest cmvs32.exe and cmvs64.exe
|
||||
bool InsertCotophaHook(); // Cotopha: *.noa
|
||||
bool InsertDACHook(); // DAC
|
||||
bool InsertDebonosuHook(); // Debonosu: bmp.bak and dsetup.dll
|
||||
bool InsertEaglsHook(); // E.A.G.L.S: EAGLES.dll
|
||||
bool InsertEMEHook(); // EmonEngine: emecfg.ecf
|
||||
|
@ -54,6 +54,11 @@ bool DeterminePCEngine()
|
||||
return true;
|
||||
}
|
||||
|
||||
if (Util::CheckFile(L"script.dpk")) {
|
||||
InsertDACHook();
|
||||
return true;
|
||||
}
|
||||
|
||||
// jichi 5/14/2015: Skip hijacking BALDRSKY ZEROs
|
||||
//if (Util::CheckFile(L"bsz_Data\\Mono\\mono.dll") || Util::CheckFile(L"bsz2_Data\\Mono\\mono.dll")) {
|
||||
// ConsoleOutput("vnreng: IGNORE BALDRSKY ZEROs");
|
||||
|
Loading…
x
Reference in New Issue
Block a user