fix crash strlen null in dumpDiagnostics safe minimal
Some checks failed
Build DevourUnlocker / windows-cross (push) Failing after 8s
Build DevourUnlocker / linux (push) Failing after 7s
Build DevourUnlocker / standalone (push) Successful in 5s

This commit is contained in:
MiTHRAL 2026-08-24 00:45:53 -04:00
parent 626c78c266
commit bffc822614
2 changed files with 23 additions and 8 deletions

View file

@ -198,15 +198,24 @@ ResolvedMethod Il2CppResolver::waitForPurchasedPet() { return resolve("SurvivalL
void Il2CppResolver::dumpDiagnostics(){ void Il2CppResolver::dumpDiagnostics(){
#ifdef _WIN32 #ifdef _WIN32
// Also log via OutputDebugString for Wine debug
OutputDebugStringA("[Diag] dumpDiagnostics enter\n"); OutputDebugStringA("[Diag] dumpDiagnostics enter\n");
try{ try{
char exe[MAX_PATH]; GetModuleFileNameA(nullptr, exe, MAX_PATH); char exe[MAX_PATH]; GetModuleFileNameA(nullptr, exe, MAX_PATH);
char* slash = strrchr(exe, '\\'); if(!slash) slash = strrchr(exe, '/'); char* slash = strrchr(exe, '\\'); if(!slash) slash = strrchr(exe, '/');
std::string logPath = slash ? std::string(exe, slash - exe) + "\\DevourUnlocker.log" : "DevourUnlocker.log"; std::string logPath = slash ? std::string(exe, slash - exe) + "\\DevourUnlocker.log" : "DevourUnlocker.log";
std::ofstream f(logPath, std::ios::app); std::ofstream f(logPath, std::ios::app);
f << "[Diag] dumpDiagnostics ENTER\n"; f.flush(); f << "[Diag] dumpDiagnostics ENTER (safe mode - minimal)\n"; f.flush();
auto il2cpp_domain_get = reinterpret_cast<void*(*)()>(getProc("il2cpp_domain_get")); auto il2cpp_domain_get = reinterpret_cast<void*(*)()>(getProc("il2cpp_domain_get"));
if(!il2cpp_domain_get){ f << "[Diag] no domain_get\n"; return; }
void* domain = il2cpp_domain_get();
if(!domain){ f << "[Diag] domain null (IL2CPP not ready - retry later)\n"; return; }
// Minimal safe dump - do not enumerate all classes (caused strlen(null) crash)
f << "[Diag] domain=" << domain << " - skipping full enumeration to avoid crash\n";
f << "[Diag] If hooks not found, IL2CPP may not be ready until lobby - retry thread will handle\n";
f << "[Diag] dump done (safe)\n";
return;
// DISABLED heavy enumeration that caused crash (strlen null at 0x8eb3)
#if 0
auto domain_get_assemblies = reinterpret_cast<const void**(*)(void*, size_t*)>(getProc("il2cpp_domain_get_assemblies")); auto domain_get_assemblies = reinterpret_cast<const void**(*)(void*, size_t*)>(getProc("il2cpp_domain_get_assemblies"));
auto assembly_get_image = reinterpret_cast<void*(*)(void*)>(getProc("il2cpp_assembly_get_image")); auto assembly_get_image = reinterpret_cast<void*(*)(void*)>(getProc("il2cpp_assembly_get_image"));
auto image_get_class_count = reinterpret_cast<int(*)(void*)>(getProc("il2cpp_image_get_class_count")); auto image_get_class_count = reinterpret_cast<int(*)(void*)>(getProc("il2cpp_image_get_class_count"));
@ -219,9 +228,9 @@ void Il2CppResolver::dumpDiagnostics(){
if(!il2cpp_domain_get || !domain_get_assemblies || !assembly_get_image || !image_get_class_count || !image_get_class) { if(!il2cpp_domain_get || !domain_get_assemblies || !assembly_get_image || !image_get_class_count || !image_get_class) {
f << "[Diag] missing IL2CPP exports for dump\n"; return; f << "[Diag] missing IL2CPP exports for dump\n"; return;
} }
void* domain = il2cpp_domain_get(); void* domain2 = il2cpp_domain_get();
if(!domain){ f << "[Diag] domain null\n"; return; } if(!domain2){ f << "[Diag] domain null\n"; return; }
size_t nAssemblies=0; const void** assemblies = domain_get_assemblies(domain, &nAssemblies); size_t nAssemblies=0; const void** assemblies = domain_get_assemblies(domain2, &nAssemblies);
f << "[Diag] assemblies=" << nAssemblies << "\n"; f << "[Diag] assemblies=" << nAssemblies << "\n";
for(size_t ai=0; ai<nAssemblies && ai<32; ++ai){ for(size_t ai=0; ai<nAssemblies && ai<32; ++ai){
void* image = assembly_get_image((void*)assemblies[ai]); void* image = assembly_get_image((void*)assemblies[ai]);
@ -256,7 +265,10 @@ void Il2CppResolver::dumpDiagnostics(){
void* ptr = *reinterpret_cast<void**>(reinterpret_cast<uint8_t*>(m) + 0x18); void* ptr = *reinterpret_cast<void**>(reinterpret_cast<uint8_t*>(m) + 0x18);
f << " ptr=" << ptr; f << " ptr=" << ptr;
auto method_get_name2 = reinterpret_cast<const char*(*)(void*)>(getProc("il2cpp_method_get_name")); auto method_get_name2 = reinterpret_cast<const char*(*)(void*)>(getProc("il2cpp_method_get_name"));
if(method_get_name2) f << " name=" << method_get_name2(m); if(method_get_name2){
const char* mn2 = method_get_name2(m);
f << " name=" << (mn2 ? mn2 : "<null>");
}
} }
f << "\n"; f << "\n";
} }
@ -289,6 +301,7 @@ void Il2CppResolver::dumpDiagnostics(){
} }
} }
f << "[Diag] dump done\n"; f << "[Diag] dump done\n";
#endif // 0
}catch(...){} }catch(...){}
#endif #endif
} }

View file

@ -9,10 +9,12 @@ static void logVer(const char* m){
std::string p = s? std::string(exe,s-exe)+"\\DevourUnlocker.log":"DevourUnlocker.log"; std::string p = s? std::string(exe,s-exe)+"\\DevourUnlocker.log":"DevourUnlocker.log";
std::ofstream f(p,std::ios::app); f<<m<<std::endl; std::ofstream f(p,std::ios::app); f<<m<<std::endl;
} }
static bool g_hooked = false;
static DWORD WINAPI HookThreadVer(LPVOID){ static DWORD WINAPI HookThreadVer(LPVOID){
if(__atomic_exchange_n(&g_hooked, true, __ATOMIC_SEQ_CST)) return 0;
logVer("[DevourUnlocker version.dll] HookThread start (always-on full unlock)"); logVer("[DevourUnlocker version.dll] HookThread start (always-on full unlock)");
for(int i=0;i<200;i++){ if(GetModuleHandleA("GameAssembly.dll")) break; Sleep(100); } for(int i=0;i<200;i++){ if(GetModuleHandleA("GameAssembly.dll")) break; Sleep(100); }
Sleep(2000); Sleep(3000);
bool ok = devour::installPatches(); bool ok = devour::installPatches();
logVer(ok ? "[DevourUnlocker version.dll] patches installed — all categories unlocked" : "[DevourUnlocker version.dll] patches not yet, retrying via installPatches retry thread"); logVer(ok ? "[DevourUnlocker version.dll] patches installed — all categories unlocked" : "[DevourUnlocker version.dll] patches not yet, retrying via installPatches retry thread");
return 0; return 0;
@ -21,7 +23,7 @@ BOOL APIENTRY DllMain(HMODULE hMod, DWORD reason, LPVOID) {
if (reason == DLL_PROCESS_ATTACH) { if (reason == DLL_PROCESS_ATTACH) {
DisableThreadLibraryCalls(hMod); DisableThreadLibraryCalls(hMod);
logVer("[DevourUnlocker version.dll] DllMain attach (always-on)"); logVer("[DevourUnlocker version.dll] DllMain attach (always-on)");
CreateThread(nullptr,0,HookThreadVer,nullptr,0,nullptr); if(!g_hooked) CreateThread(nullptr,0,HookThreadVer,nullptr,0,nullptr);
} }
return TRUE; return TRUE;
} }