LunaHook-mirror/LunaHook/engines/mono/impl_il2cpp.cpp

183 lines
5.3 KiB
C++
Raw Normal View History

2024-10-26 02:23:45 +08:00
#include "def_il2cpp.hpp"
namespace
{
Il2CppClass *get_il2cppclass1(const char *assemblyName, const char *namespaze,
const char *klassName, bool strict)
2024-05-09 07:23:06 +08:00
{
2024-10-26 02:23:45 +08:00
auto il2cpp_domain = (SafeFptr(il2cpp_domain_get))();
if (!il2cpp_domain)
return NULL;
void *assembly = 0;
do
{
2024-05-14 13:07:12 +08:00
assembly = (SafeFptr(il2cpp_domain_assembly_open))(il2cpp_domain, assemblyName);
2024-10-26 02:23:45 +08:00
if (!assembly)
break;
2024-05-14 13:07:12 +08:00
auto image = (SafeFptr(il2cpp_assembly_get_image))(assembly);
2024-10-26 02:23:45 +08:00
if (!image)
break;
2024-05-14 13:07:12 +08:00
auto klass = (SafeFptr(il2cpp_class_from_name))(image, namespaze, klassName);
2024-10-26 02:23:45 +08:00
if (klass)
return klass;
} while (0);
if (strict)
return NULL;
2024-05-14 13:07:12 +08:00
int _ = 0;
size_t sz = 0;
auto assemblies = (SafeFptr(il2cpp_domain_get_assemblies))(il2cpp_domain, &sz);
2024-10-26 02:23:45 +08:00
if (assemblies)
for (auto i = 0; i < sz; i++, assemblies++)
{
auto image = (SafeFptr(il2cpp_assembly_get_image))(*assemblies);
if (!image)
continue;
auto cls = (SafeFptr(il2cpp_class_from_name))(image, namespaze, klassName);
if (cls)
return cls;
}
2024-05-09 07:23:06 +08:00
return NULL;
}
2024-10-26 02:23:45 +08:00
void foreach_func(Il2CppClass *klass, void *userData)
{
auto st = (std::vector<Il2CppClass *> *)userData;
2024-05-09 14:22:19 +08:00
st->push_back(klass);
2024-05-09 07:23:06 +08:00
}
2024-10-26 02:23:45 +08:00
std::vector<Il2CppClass *> get_il2cppclass2(const char *namespaze,
const char *klassName)
2024-05-09 07:23:06 +08:00
{
2024-10-26 02:23:45 +08:00
std::vector<Il2CppClass *> maybes;
std::vector<Il2CppClass *> klasses;
(SafeFptr(il2cpp_class_for_each))(foreach_func, &klasses);
for (auto klass : klasses)
{
2024-05-14 13:07:12 +08:00
auto classname = (SafeFptr(il2cpp_class_get_name))(klass);
2024-10-26 02:23:45 +08:00
if (!classname)
continue;
if (strcmp(classname, klassName) != 0)
continue;
2024-05-09 14:22:19 +08:00
maybes.push_back(klass);
2024-10-26 02:23:45 +08:00
auto namespacename = (SafeFptr(il2cpp_class_get_namespace))(klass);
if (!namespacename)
continue;
if (strlen(namespaze) && (strcmp(namespacename, namespaze) == 0))
{
2024-05-14 13:07:12 +08:00
return {klass};
2024-05-09 14:22:19 +08:00
}
}
return maybes;
}
2024-10-26 02:23:45 +08:00
struct AutoThread
{
void *thread = NULL;
AutoThread()
{
auto il2cpp_domain = (SafeFptr(il2cpp_domain_get))();
if (!il2cpp_domain)
return;
thread = (SafeFptr(il2cpp_thread_attach))(il2cpp_domain);
2024-05-09 14:22:19 +08:00
}
2024-10-26 02:23:45 +08:00
~AutoThread()
{
if (!thread)
return;
2024-05-14 13:07:12 +08:00
(SafeFptr(il2cpp_thread_detach))(thread);
2024-05-09 14:22:19 +08:00
}
};
2024-10-26 02:23:45 +08:00
void tryprintimage(Il2CppClass *klass)
{
auto image = (SafeFptr(il2cpp_class_get_image))(klass);
if (!image)
return;
auto imagen = (SafeFptr(il2cpp_image_get_name))(image);
auto names = (SafeFptr(il2cpp_class_get_namespace))(klass);
if (imagen && names)
ConsoleOutput("%s:%s", imagen, names);
2024-05-09 21:31:38 +08:00
}
2024-10-26 02:23:45 +08:00
uintptr_t getmethodofklass(Il2CppClass *klass, const char *name, int argsCount)
{
if (!klass)
return NULL;
2024-05-14 13:07:12 +08:00
auto ret = (SafeFptr(il2cpp_class_get_method_from_name))(klass, name, argsCount);
2024-10-26 02:23:45 +08:00
if (!ret)
return NULL;
2024-05-09 21:31:38 +08:00
tryprintimage(klass);
2024-05-09 14:22:19 +08:00
return ret->methodPointer;
2024-05-09 07:23:06 +08:00
}
2024-05-14 20:37:48 +08:00
}
void il2cppfunctions::init(HMODULE game_module)
{
RESOLVE_IMPORT(il2cpp_string_new_utf16);
RESOLVE_IMPORT(il2cpp_string_chars);
RESOLVE_IMPORT(il2cpp_string_length);
RESOLVE_IMPORT(il2cpp_image_get_name);
RESOLVE_IMPORT(il2cpp_class_get_image);
RESOLVE_IMPORT(il2cpp_string_new_utf16);
RESOLVE_IMPORT(il2cpp_string_new);
RESOLVE_IMPORT(il2cpp_domain_get);
RESOLVE_IMPORT(il2cpp_domain_assembly_open);
RESOLVE_IMPORT(il2cpp_assembly_get_image);
RESOLVE_IMPORT(il2cpp_class_from_name);
RESOLVE_IMPORT(il2cpp_class_get_methods);
RESOLVE_IMPORT(il2cpp_class_get_method_from_name);
RESOLVE_IMPORT(il2cpp_method_get_param);
RESOLVE_IMPORT(il2cpp_object_new);
RESOLVE_IMPORT(il2cpp_resolve_icall);
RESOLVE_IMPORT(il2cpp_array_new);
RESOLVE_IMPORT(il2cpp_thread_attach);
RESOLVE_IMPORT(il2cpp_thread_detach);
RESOLVE_IMPORT(il2cpp_class_get_field_from_name);
RESOLVE_IMPORT(il2cpp_class_is_assignable_from);
RESOLVE_IMPORT(il2cpp_class_for_each);
RESOLVE_IMPORT(il2cpp_class_get_nested_types);
RESOLVE_IMPORT(il2cpp_class_get_type);
RESOLVE_IMPORT(il2cpp_type_get_object);
RESOLVE_IMPORT(il2cpp_gchandle_new);
RESOLVE_IMPORT(il2cpp_gchandle_free);
RESOLVE_IMPORT(il2cpp_gchandle_get_target);
RESOLVE_IMPORT(il2cpp_class_from_type);
RESOLVE_IMPORT(il2cpp_runtime_class_init);
RESOLVE_IMPORT(il2cpp_runtime_invoke);
RESOLVE_IMPORT(il2cpp_class_get_name);
RESOLVE_IMPORT(il2cpp_class_get_namespace);
RESOLVE_IMPORT(il2cpp_domain_get_assemblies);
}
2024-10-26 02:23:45 +08:00
uintptr_t il2cppfunctions::get_method_pointer(const char *assemblyName, const char *namespaze,
const char *klassName, const char *name, int argsCount, bool strict)
2024-05-14 20:37:48 +08:00
{
2024-10-26 02:23:45 +08:00
auto thread = AutoThread();
if (!thread.thread)
return NULL;
2024-05-09 14:22:19 +08:00
2024-10-26 02:23:45 +08:00
auto klass = get_il2cppclass1(assemblyName, namespaze, klassName, strict); // 正向查询assemblyName可以为空
if (klass)
return getmethodofklass(klass, name, argsCount);
if (strict)
return NULL;
auto klasses = get_il2cppclass2(namespaze, klassName); // 反向查询namespace可以为空
for (auto klass : klasses)
{
auto method = getmethodofklass(klass, name, argsCount);
if (method)
return method;
2024-05-09 07:23:06 +08:00
}
2024-05-14 20:37:48 +08:00
return NULL;
}
2024-10-26 02:23:45 +08:00
std::optional<std::wstring_view> il2cppfunctions::get_string(void *ptr)
{
auto str = reinterpret_cast<Il2CppString *>(ptr);
if (!str)
return {};
auto wc = (SafeFptr(il2cpp_string_chars))(str);
auto len = (SafeFptr(il2cpp_string_length))(str);
if (!(wc && len))
return {};
return std::wstring_view(wc, len);
2024-05-09 07:23:06 +08:00
}
2024-10-26 02:23:45 +08:00
void *il2cppfunctions::create_string(std::wstring_view ws)
{
return (SafeFptr(il2cpp_string_new_utf16))(ws.data(), ws.length());
2024-05-14 20:37:48 +08:00
}