#pragma once #include "../deps/UnityResolve/UnityResolve.hpp" #include "Log.h" #include namespace Il2cppUtils { using namespace GakumasLocal; struct Il2CppClassHead { // The following fields are always valid for a Il2CppClass structure const void* image; void* gc_desc; const char* name; const char* namespaze; }; struct MethodInfo { uintptr_t methodPointer; uintptr_t invoker_method; const char* name; uintptr_t klass; //const Il2CppType* return_type; //const ParameterInfo* parameters; const void* return_type; const void* parameters; uintptr_t methodDefinition; uintptr_t genericContainer; uint32_t token; uint16_t flags; uint16_t iflags; uint16_t slot; uint8_t parameters_count; uint8_t is_generic : 1; uint8_t is_inflated : 1; uint8_t wrapper_type : 1; uint8_t is_marshaled_from_native : 1; }; struct Resolution_t { int width; int height; int herz; }; UnityResolve::Class* GetClass(const std::string& assemblyName, const std::string& nameSpaceName, const std::string& className) { const auto assembly = UnityResolve::Get(assemblyName); if (!assembly) { Log::ErrorFmt("GetMethodPointer error: assembly %s not found.", assemblyName.c_str()); return nullptr; } const auto pClass = assembly->Get(className, nameSpaceName); if (!pClass) { Log::ErrorFmt("GetMethodPointer error: Class %s::%s not found.", nameSpaceName.c_str(), className.c_str()); return nullptr; } return pClass; } /* UnityResolve::Method* GetMethodIl2cpp(const char* assemblyName, const char* nameSpaceName, const char* className, const char* methodName, const int argsCount) { auto domain = UnityResolve::Invoke("il2cpp_domain_get"); UnityResolve::Invoke("il2cpp_thread_attach", domain); auto image = UnityResolve::Invoke("il2cpp_assembly_get_image", domain); if (!image) { Log::ErrorFmt("GetMethodIl2cpp error: assembly %s not found.", assemblyName); return nullptr; } Log::Debug("GetMethodIl2cpp 1"); auto klass = UnityResolve::Invoke("il2cpp_class_from_name", image, nameSpaceName, className); if (!klass) { Log::ErrorFmt("GetMethodIl2cpp error: Class %s::%s not found.", nameSpaceName, className); return nullptr; } Log::Debug("GetMethodIl2cpp 2"); auto ret = UnityResolve::Invoke("il2cpp_class_get_method_from_name", klass, methodName, argsCount); if (!ret) { Log::ErrorFmt("GetMethodIl2cpp error: method %s::%s.%s not found.", nameSpaceName, className, methodName); return nullptr; } return ret; }*/ UnityResolve::Method* GetMethod(const std::string& assemblyName, const std::string& nameSpaceName, const std::string& className, const std::string& methodName, const std::vector& args = {}) { const auto assembly = UnityResolve::Get(assemblyName); if (!assembly) { Log::ErrorFmt("GetMethod error: assembly %s not found.", assemblyName.c_str()); return nullptr; } const auto pClass = assembly->Get(className, nameSpaceName); if (!pClass) { Log::ErrorFmt("GetMethod error: Class %s::%s not found.", nameSpaceName.c_str(), className.c_str()); return nullptr; } auto method = pClass->Get(methodName, args); if (!method) { /* method = GetMethodIl2cpp(assemblyName.c_str(), nameSpaceName.c_str(), className.c_str(), methodName.c_str(), args.size() == 0 ? -1 : args.size()); if (!method) { Log::ErrorFmt("GetMethod error: method %s::%s.%s not found.", nameSpaceName.c_str(), className.c_str(), methodName.c_str()); return nullptr; }*/ Log::ErrorFmt("GetMethod error: method %s::%s.%s not found.", nameSpaceName.c_str(), className.c_str(), methodName.c_str()); return nullptr; } return method; } void* GetMethodPointer(const std::string& assemblyName, const std::string& nameSpaceName, const std::string& className, const std::string& methodName, const std::vector& args = {}) { auto method = GetMethod(assemblyName, nameSpaceName, className, methodName, args); if (method) { return method->function; } return nullptr; } void* il2cpp_resolve_icall(const char* s) { return UnityResolve::Invoke("il2cpp_resolve_icall", s); } Il2CppClassHead* get_class_from_instance(const void* instance) { return static_cast(*static_cast(std::assume_aligned(instance))); } MethodInfo* il2cpp_class_get_method_from_name(void* klass, const char* name, int argsCount) { return UnityResolve::Invoke("il2cpp_class_get_method_from_name", klass, name, argsCount); } void* find_nested_class(void* klass, std::predicate auto&& predicate) { void* iter{}; while (const auto curNestedClass = UnityResolve::Invoke("il2cpp_class_get_nested_types", klass, &iter)) { if (static_cast(predicate)(curNestedClass)) { return curNestedClass; } } return nullptr; } void* find_nested_class_from_name(void* klass, const char* name) { return find_nested_class(klass, [name = std::string_view(name)](void* nestedClass) { return static_cast(nestedClass)->name == name; }); } template auto ClassGetFieldValue(void* obj, UnityResolve::Field* field) -> RType { return *reinterpret_cast(reinterpret_cast(obj) + field->offset); } template auto ClassSetFieldValue(void* obj, UnityResolve::Field* field, RType value) -> void { return *reinterpret_cast(reinterpret_cast(obj) + field->offset) = value; } }