Update monocommon.hpp

This commit is contained in:
恍兮惚兮 2024-08-10 00:59:45 +08:00
parent 9cbc2e0260
commit ddb14b42ce

View File

@ -1,166 +1,197 @@
#include"def_mono.hpp" #include "def_mono.hpp"
#include"def_il2cpp.hpp" #include "def_il2cpp.hpp"
#include"monostringapis.h" #include "monostringapis.h"
namespace { namespace
void mscorlib_system_string_InternalSubString_hook_fun(hook_stack* stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t*len)
{
uintptr_t offset=stack->ARG1;
uintptr_t startIndex=stack->ARG2;
uintptr_t length=stack->ARG3;
MonoString* string = (MonoString*)offset;
if(string==0)return;
*data = (uintptr_t)(startIndex+string->chars);
if(wcslen((wchar_t*)*data)<length)return;
*len = length * 2;
}
/** jichi 12/26/2014 Mono
* Sample game: [141226] <EFBFBD><EFBFBD>
*/
void SpecialHookMonoString(hook_stack* stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t*len)
{ {
commonsolvemonostring(stack->ARG1,data,len);
#ifndef _WIN64 void mscorlib_system_string_InternalSubString_hook_fun(hook_stack *stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
auto s = stack->ecx; {
for (int i = 0; i < 0x10; i++) // traverse pointers until a non-readable address is met uintptr_t offset = stack->ARG1;
if (s && !::IsBadReadPtr((LPCVOID)s, sizeof(DWORD))) uintptr_t startIndex = stack->ARG2;
s = *(DWORD *)s; uintptr_t length = stack->ARG3;
else
break; MonoString *string = (MonoString *)offset;
if (!s) if (string == 0)
s = hp->address; return;
if (hp->type & USING_SPLIT) *split = s; *data = (uintptr_t)(startIndex + string->chars);
#endif if (wcslen((wchar_t *)*data) < length)
return;
*len = length * 2;
}
/** jichi 12/26/2014 Mono
* Sample game: [141226] <EFBFBD><EFBFBD>
*/
void SpecialHookMonoString(hook_stack *stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t *len)
{
commonsolvemonostring(stack->ARG1, data, len);
#ifndef _WIN64
auto s = stack->ecx;
for (int i = 0; i < 0x10; i++) // traverse pointers until a non-readable address is met
if (s && !::IsBadReadPtr((LPCVOID)s, sizeof(DWORD)))
s = *(DWORD *)s;
else
break;
if (!s)
s = hp->address;
if (hp->type & USING_SPLIT)
*split = s;
#endif
}
} }
namespace
} {
namespace { bool monodllhook(HMODULE module)
bool monodllhook(HMODULE module) { {
HookParam hp; HookParam hp;
const MonoFunction funcs[] = { MONO_FUNCTIONS_INITIALIZER }; const MonoFunction funcs[] = {MONO_FUNCTIONS_INITIALIZER};
for (auto func : funcs) { for (auto func : funcs)
if (FARPROC addr = GetProcAddress(module, func.functionName)) { {
hp.address =(uintptr_t) addr; if (FARPROC addr = GetProcAddress(module, func.functionName))
hp.type =USING_STRING| func.hookType; {
hp.filter_fun =all_ascii_Filter; hp.address = (uintptr_t)addr;
hp.offset = func.textIndex * 4; hp.type = USING_STRING | func.hookType;
hp.length_offset = func.lengthIndex * 4; hp.filter_fun = all_ascii_Filter;
hp.text_fun = (decltype(hp.text_fun))func.text_fun; hp.offset = func.textIndex * 4;
ConsoleOutput("Mono: INSERT"); hp.length_offset = func.lengthIndex * 4;
NewHook(hp, func.functionName); hp.text_fun = (decltype(hp.text_fun))func.text_fun;
ConsoleOutput("Mono: INSERT");
NewHook(hp, func.functionName);
} }
} }
return true; return true;
} }
} }
namespace monocommon{ namespace monocommon
{
bool monodllhook(HMODULE module) {
bool monodllhook(HMODULE module)
{
HookParam hp; HookParam hp;
const MonoFunction funcs[] = { MONO_FUNCTIONS_INITIALIZER }; const MonoFunction funcs[] = {MONO_FUNCTIONS_INITIALIZER};
for (auto func : funcs) { for (auto func : funcs)
if (FARPROC addr = GetProcAddress(module, func.functionName)) { {
hp.address =(uintptr_t) addr; if (FARPROC addr = GetProcAddress(module, func.functionName))
hp.type =USING_STRING| func.hookType; {
hp.filter_fun =all_ascii_Filter; hp.address = (uintptr_t)addr;
hp.offset = func.textIndex * 4; hp.type = USING_STRING | func.hookType;
hp.length_offset = func.lengthIndex * 4; hp.filter_fun = all_ascii_Filter;
hp.text_fun = (decltype(hp.text_fun))func.text_fun; hp.offset = func.textIndex * 4;
NewHook(hp, func.functionName); hp.length_offset = func.lengthIndex * 4;
hp.text_fun = (decltype(hp.text_fun))func.text_fun;
NewHook(hp, func.functionName);
} }
} }
return true; return true;
} }
struct functioninfo{ struct functioninfo
const char* assemblyName;const char* namespaze; {
const char* klassName; const char* name;int argsCount; const char *assemblyName;
int argidx;void* text_fun=nullptr;bool Embed=false;bool isstring=true; const char *namespaze;
std::string hookname(){ const char *klassName;
const char *name;
int argsCount;
int argidx;
void *text_fun = nullptr;
bool Embed = false;
bool isstring = true;
std::string hookname()
{
char tmp[1024]; char tmp[1024];
sprintf(tmp,"%s:%s",klassName,name); sprintf(tmp, "%s:%s", klassName, name);
return tmp; return tmp;
} }
std::string info(){ std::string info()
{
char tmp[1024]; char tmp[1024];
sprintf(tmp,"%s:%s:%s:%s:%d",assemblyName,namespaze,klassName,name,argsCount); sprintf(tmp, "%s:%s:%s:%s:%d", assemblyName, namespaze, klassName, name, argsCount);
return tmp; return tmp;
} }
}; };
bool NewHook_check(uintptr_t addr,functioninfo&hook){ bool NewHook_check(uintptr_t addr, functioninfo &hook)
{
HookParam hp; HookParam hp;
hp.address = addr; hp.address = addr;
hp.argidx=hook.argidx; hp.argidx = hook.argidx;
hp.text_fun =(decltype(hp.text_fun))hook.text_fun; hp.text_fun = (decltype(hp.text_fun))hook.text_fun;
if(hook.isstring){ if (hook.isstring)
hp.type = USING_STRING | CODEC_UTF16|FULL_STRING; {
if(!hp.text_fun)hp.type|=SPECIAL_JIT_STRING; hp.type = USING_STRING | CODEC_UTF16 | FULL_STRING;
if(hook.Embed) if (!hp.text_fun)
hp.type|=EMBED_ABLE|EMBED_BEFORE_SIMPLE; hp.type |= SPECIAL_JIT_STRING;
if (hook.Embed)
hp.type |= EMBED_ABLE | EMBED_BEFORE_SIMPLE;
} }
else{ else
hp.type = USING_CHAR | CODEC_UTF16; {
hp.type = USING_CHAR | CODEC_UTF16;
} }
hp.jittype=JITTYPE::UNITY; hp.jittype = JITTYPE::UNITY;
strcpy(hp.unityfunctioninfo,hook.info().c_str()); strcpy(hp.unityfunctioninfo, hook.info().c_str());
auto succ=NewHook(hp,hook.hookname().c_str()); auto succ = NewHook(hp, hook.hookname().c_str());
#ifdef _WIN64 #ifdef _WIN64
if(!succ){ if (!succ)
hp.type|=BREAK_POINT; {
succ|=NewHook(hp,hook.hookname().c_str()); hp.type |= BREAK_POINT;
succ |= NewHook(hp, hook.hookname().c_str());
} }
#endif #endif
return succ; return succ;
} }
std::vector<functioninfo>commonhooks{ std::vector<functioninfo> commonhooks{
{"mscorlib","System","String","ToCharArray",0,1}, {"mscorlib", "System", "String", "ToCharArray", 0, 1},
{"mscorlib","System","String","Replace",2,1}, {"mscorlib", "System", "String", "Replace", 2, 1},
{"mscorlib","System","String","ToString",0,1}, //{"mscorlib","System","String","ToString",0,1}, //删除。虽然可能会误伤,但这个乱码太多了,而且不知道原因。
{"mscorlib","System","String","IndexOf",1,1}, {"mscorlib", "System", "String", "IndexOf", 1, 1},
{"mscorlib","System","String","Substring",2,1}, {"mscorlib", "System", "String", "Substring", 2, 1},
{"mscorlib","System","String","op_Inequality",2,1}, {"mscorlib", "System", "String", "op_Inequality", 2, 1},
{"mscorlib","System","String","InternalSubString",2,1,mscorlib_system_string_InternalSubString_hook_fun}, {"mscorlib", "System", "String", "InternalSubString", 2, 1, mscorlib_system_string_InternalSubString_hook_fun},
{"Unity.TextMeshPro","TMPro","TMP_Text","set_text",1,2,nullptr,true}, {"Unity.TextMeshPro", "TMPro", "TMP_Text", "set_text", 1, 2, nullptr, true},
{"Unity.TextMeshPro","TMPro","TextMeshPro","set_text",1,2,nullptr,true}, {"Unity.TextMeshPro", "TMPro", "TextMeshPro", "set_text", 1, 2, nullptr, true},
{"UnityEngine.UI","UnityEngine.UI","Text","set_text",1,2,nullptr,true}, {"UnityEngine.UI", "UnityEngine.UI", "Text", "set_text", 1, 2, nullptr, true},
{"UnityEngine.UIElementsModule","UnityEngine.UIElements","TextElement","set_text",1,2,nullptr,true}, {"UnityEngine.UIElementsModule", "UnityEngine.UIElements", "TextElement", "set_text", 1, 2, nullptr, true},
{"UnityEngine.UIElementsModule","UnityEngine.UIElements","TextField","set_value",1,2,nullptr,true}, {"UnityEngine.UIElementsModule", "UnityEngine.UIElements", "TextField", "set_value", 1, 2, nullptr, true},
{"UnityEngine.TextRenderingModule","UnityEngine","GUIText","set_text",1,2,nullptr,true}, {"UnityEngine.TextRenderingModule", "UnityEngine", "GUIText", "set_text", 1, 2, nullptr, true},
{"UnityEngine.TextRenderingModule","UnityEngine","TextMesh","set_text",1,2,nullptr,true}, {"UnityEngine.TextRenderingModule", "UnityEngine", "TextMesh", "set_text", 1, 2, nullptr, true},
{"UGUI","","UILabel","set_text",1,2,nullptr,true}, {"UGUI", "", "UILabel", "set_text", 1, 2, nullptr, true},
}; };
std::vector<functioninfo>extrahooks{ std::vector<functioninfo> extrahooks{
//https://vndb.org/r37234 && https://vndb.org/r37235 // https://vndb.org/r37234 && https://vndb.org/r37235
//Higurashi When They Cry Hou - Ch.2 Watanagashi && Higurashi When They Cry Hou - Ch.3 Tatarigoroshi // Higurashi When They Cry Hou - Ch.2 Watanagashi && Higurashi When They Cry Hou - Ch.3 Tatarigoroshi
{"Assembly-CSharp","Assets.Scripts.Core.TextWindow","TextController","SetText",4,3,nullptr,true}, {"Assembly-CSharp", "Assets.Scripts.Core.TextWindow", "TextController", "SetText", 4, 3, nullptr, true},
//逆転裁判123 成歩堂セレクション // 逆転裁判123 成歩堂セレクション
{"Assembly-CSharp","","MessageText","Append",1,2,nullptr,false,false}, {"Assembly-CSharp", "", "MessageText", "Append", 1, 2, nullptr, false, false},
}; };
bool hook_mono_il2cpp(){ bool hook_mono_il2cpp()
for (const wchar_t* monoName : { L"mono.dll", L"mono-2.0-bdwgc.dll",L"GameAssembly.dll" }) {
if (HMODULE module = GetModuleHandleW(monoName)) { for (const wchar_t *monoName : {L"mono.dll", L"mono-2.0-bdwgc.dll", L"GameAssembly.dll"})
//bool b2=monodllhook(module); if (HMODULE module = GetModuleHandleW(monoName))
{
// bool b2=monodllhook(module);
il2cppfunctions::init(module); il2cppfunctions::init(module);
monofunctions::init(module); monofunctions::init(module);
bool succ=false; bool succ = false;
for(auto hook:commonhooks){ for (auto hook : commonhooks)
auto addr=tryfindmonoil2cpp(hook.assemblyName,hook.namespaze,hook.klassName,hook.name,hook.argsCount); {
if(!addr)continue; auto addr = tryfindmonoil2cpp(hook.assemblyName, hook.namespaze, hook.klassName, hook.name, hook.argsCount);
succ|=NewHook_check(addr,hook); if (!addr)
continue;
succ |= NewHook_check(addr, hook);
} }
for(auto hook:extrahooks){ for (auto hook : extrahooks)
auto addr=tryfindmonoil2cpp(hook.assemblyName,hook.namespaze,hook.klassName,hook.name,hook.argsCount,true); {
if(!addr)continue; auto addr = tryfindmonoil2cpp(hook.assemblyName, hook.namespaze, hook.klassName, hook.name, hook.argsCount, true);
succ|=NewHook_check(addr,hook); if (!addr)
continue;
succ |= NewHook_check(addr, hook);
} }
if(succ)return true; if (succ)
return true;
} }
return false; return false;
} }