2024-05-09 07:23:06 +08:00
|
|
|
|
|
|
|
|
|
il2cpp_string_new_utf16_t il2cpp_string_new_utf16;
|
|
|
|
|
il2cpp_string_new_t il2cpp_string_new;
|
|
|
|
|
il2cpp_domain_get_t il2cpp_domain_get;
|
|
|
|
|
il2cpp_domain_assembly_open_t il2cpp_domain_assembly_open;
|
|
|
|
|
il2cpp_assembly_get_image_t il2cpp_assembly_get_image;
|
|
|
|
|
il2cpp_class_from_name_t il2cpp_class_from_name;
|
|
|
|
|
il2cpp_class_get_methods_t il2cpp_class_get_methods;
|
|
|
|
|
il2cpp_class_get_method_from_name_t il2cpp_class_get_method_from_name;
|
|
|
|
|
il2cpp_method_get_param_t il2cpp_method_get_param;
|
|
|
|
|
il2cpp_object_new_t il2cpp_object_new;
|
|
|
|
|
il2cpp_resolve_icall_t il2cpp_resolve_icall;
|
|
|
|
|
il2cpp_array_new_t il2cpp_array_new;
|
|
|
|
|
il2cpp_thread_attach_t il2cpp_thread_attach;
|
|
|
|
|
il2cpp_thread_detach_t il2cpp_thread_detach;
|
|
|
|
|
il2cpp_class_get_field_from_name_t il2cpp_class_get_field_from_name;
|
|
|
|
|
il2cpp_class_is_assignable_from_t il2cpp_class_is_assignable_from;
|
|
|
|
|
il2cpp_class_for_each_t il2cpp_class_for_each;
|
|
|
|
|
il2cpp_class_get_nested_types_t il2cpp_class_get_nested_types;
|
|
|
|
|
il2cpp_class_get_type_t il2cpp_class_get_type;
|
|
|
|
|
il2cpp_type_get_object_t il2cpp_type_get_object;
|
|
|
|
|
il2cpp_gchandle_new_t il2cpp_gchandle_new;
|
|
|
|
|
il2cpp_gchandle_free_t il2cpp_gchandle_free;
|
|
|
|
|
il2cpp_gchandle_get_target_t il2cpp_gchandle_get_target;
|
|
|
|
|
il2cpp_class_from_type_t il2cpp_class_from_type;
|
|
|
|
|
il2cpp_runtime_class_init_t il2cpp_runtime_class_init;
|
|
|
|
|
il2cpp_runtime_invoke_t il2cpp_runtime_invoke;
|
|
|
|
|
il2cpp_class_get_name_t il2cpp_class_get_name;
|
|
|
|
|
il2cpp_class_get_namespace_t il2cpp_class_get_namespace;
|
|
|
|
|
il2cpp_domain_get_assemblies_t il2cpp_domain_get_assemblies;
|
2024-05-09 14:22:19 +08:00
|
|
|
|
|
2024-05-09 07:23:06 +08:00
|
|
|
|
|
|
|
|
|
namespace il2cpp_symbols
|
|
|
|
|
{
|
|
|
|
|
#define RESOLVE_IMPORT(name) name = reinterpret_cast<name##_t>(GetProcAddress(game_module, #name))
|
|
|
|
|
|
|
|
|
|
void init(HMODULE game_module)
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
Il2CppClass* get_il2cppclass1(const char* assemblyName, const char* namespaze,
|
|
|
|
|
const char* klassName)
|
|
|
|
|
{
|
2024-05-09 14:22:19 +08:00
|
|
|
|
if(!(il2cpp_assembly_get_image&&il2cpp_class_from_name))return NULL;
|
2024-05-09 07:23:06 +08:00
|
|
|
|
void* assembly=0;
|
|
|
|
|
if(il2cpp_domain_assembly_open){
|
|
|
|
|
do{
|
|
|
|
|
assembly = il2cpp_domain_assembly_open(il2cpp_domain, assemblyName);
|
|
|
|
|
if(!assembly)break;
|
|
|
|
|
auto image = il2cpp_assembly_get_image(assembly);
|
|
|
|
|
if(!image)break;
|
|
|
|
|
auto klass = il2cpp_class_from_name(image, namespaze, klassName);
|
|
|
|
|
if(klass)return klass;
|
|
|
|
|
}while(0);
|
|
|
|
|
}
|
|
|
|
|
if(il2cpp_domain_get_assemblies&&il2cpp_assembly_get_image)
|
|
|
|
|
{
|
|
|
|
|
int _ = 0;
|
|
|
|
|
size_t sz = 0;
|
|
|
|
|
auto assemblies = il2cpp_domain_get_assemblies(il2cpp_domain, &sz);
|
|
|
|
|
for (auto i = 0; i < sz; i++, assemblies++) {
|
|
|
|
|
auto image = il2cpp_assembly_get_image(*assemblies);
|
|
|
|
|
auto cls = il2cpp_class_from_name(image, namespaze, klassName);
|
|
|
|
|
if(cls)return cls;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
void foreach_func(Il2CppClass* klass, void* userData){
|
2024-05-09 14:22:19 +08:00
|
|
|
|
auto st=(std::vector<Il2CppClass*>*)userData;
|
|
|
|
|
st->push_back(klass);
|
|
|
|
|
|
2024-05-09 07:23:06 +08:00
|
|
|
|
}
|
2024-05-09 14:22:19 +08:00
|
|
|
|
std::vector<Il2CppClass*> get_il2cppclass2(const char* namespaze,
|
2024-05-09 07:23:06 +08:00
|
|
|
|
const char* klassName)
|
|
|
|
|
{
|
2024-05-09 14:22:19 +08:00
|
|
|
|
if(!(il2cpp_class_for_each&&il2cpp_class_get_name))return {};
|
|
|
|
|
std::vector<Il2CppClass*>maybes;
|
|
|
|
|
std::vector<Il2CppClass*>klasses;
|
|
|
|
|
il2cpp_class_for_each(foreach_func,&klasses);
|
2024-05-09 07:23:06 +08:00
|
|
|
|
|
2024-05-09 14:22:19 +08:00
|
|
|
|
for(auto klass:klasses){
|
|
|
|
|
auto classname = il2cpp_class_get_name(klass);
|
|
|
|
|
if(strcmp(classname,klassName)!=0)continue;
|
|
|
|
|
maybes.push_back(klass);
|
|
|
|
|
if(il2cpp_class_get_namespace){
|
|
|
|
|
auto namespacename=il2cpp_class_get_namespace(klass);
|
|
|
|
|
if(strcmp(namespacename,namespaze)==0){
|
|
|
|
|
return {klass};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return maybes;
|
|
|
|
|
}
|
|
|
|
|
struct AuthThread{
|
|
|
|
|
void*thread=NULL;
|
|
|
|
|
AuthThread(){
|
|
|
|
|
if(!(il2cpp_thread_attach&&il2cpp_domain_get))return;
|
|
|
|
|
auto il2cpp_domain=il2cpp_domain_get();
|
|
|
|
|
if (!il2cpp_domain) return;
|
|
|
|
|
thread= il2cpp_thread_attach(il2cpp_domain);
|
|
|
|
|
}
|
|
|
|
|
~AuthThread(){
|
|
|
|
|
if(!thread)return;
|
|
|
|
|
if(!il2cpp_thread_detach)return;
|
|
|
|
|
il2cpp_thread_detach(thread);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
uintptr_t getmethodofklass(Il2CppClass* klass,const char* name, int argsCount){
|
|
|
|
|
if(!(il2cpp_class_get_method_from_name))return NULL;
|
|
|
|
|
if(!klass)return NULL;
|
|
|
|
|
auto ret = il2cpp_class_get_method_from_name(klass, name, argsCount);
|
|
|
|
|
if(!ret)return NULL;
|
|
|
|
|
return ret->methodPointer;
|
2024-05-09 07:23:06 +08:00
|
|
|
|
}
|
|
|
|
|
uintptr_t get_method_pointer(const char* assemblyName, const char* namespaze,
|
|
|
|
|
const char* klassName, const char* name, int argsCount)
|
|
|
|
|
{
|
2024-05-09 14:22:19 +08:00
|
|
|
|
auto thread=AuthThread();
|
|
|
|
|
if(!thread.thread)return NULL;
|
|
|
|
|
|
|
|
|
|
auto klass=get_il2cppclass1(assemblyName,namespaze,klassName);//正向查询,assemblyName可以为空
|
|
|
|
|
if(klass)
|
|
|
|
|
return getmethodofklass(klass,name,argsCount);
|
|
|
|
|
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
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|