googoleapp 发表于 2022-3-10 15:29

一套强劲的 Il2cpp Hook 框架 思考

https://www.52pojie.cn/thread-978958-1-1.html

看了此贴突有感而发懒得打字了麻烦直接贴代码

1.unity.cpp
extern void unity_il2cpp_entry(hook* ptr_hook, void *handle);
extern void unity_mono_entry(hook* ptr_hook, void *handle);

/* unity hook 入口函数
*/
void unity_entry(hook* ptr_hook, void *handle)
{
    LOGD("[+] [%s] handle [%p]", __FUNCTION__, handle);

    do {
      if (MS_FindSymbol(handle, "il2cpp_init"))
      {
            unity_il2cpp_entry(ptr_hook, handle);
            break;
      }
      if (MS_FindSymbol(handle, "mono_init"))
      {
            unity_mono_entry(ptr_hook, handle);
            break;
      }
    } while (0);

    LOGD("[+] [%s] unity 注入成功 .", __FUNCTION__);
}

2.li2cpp.h
#include <vector>
#include "vm/il2cpp_array.h"
#include "vm/il2cpp_string.h"

//Il2CppDomain* il2cpp_domain_get()
typedef void *(*il2cpp_domain_get_t)();

//const Il2CppAssembly* il2cpp_domain_assembly_open(Il2CppDomain *domain, const char *name)
typedef void *(*il2cpp_domain_assembly_open_t)(void *domain, const char *name);

//const Il2CppImage* il2cpp_assembly_get_image(const Il2CppAssembly *assembly)
typedef void *(*il2cpp_assembly_get_image_t)(const void *assembly);

//Il2CppClass* il2cpp_class_from_name(const Il2CppImage* image, const char* namespaze, const char *name)
typedef void *(*il2cpp_class_from_name_t)(const void *image, const char *namespaze, const char *name);

//const MethodInfo* il2cpp_class_get_method_from_name(Il2CppClass *klass, const char* name, int argsCount)
typedef void *(*il2cpp_class_get_method_from_name_t)(void *klass, const char *name, int argsCount);

extern il2cpp_domain_get_t il2cpp_domain_get;
extern il2cpp_domain_assembly_open_t il2cpp_domain_assembly_open;
extern il2cpp_assembly_get_image_t il2cpp_assembly_get_image;
extern il2cpp_class_from_name_t il2cpp_class_from_name;
extern il2cpp_class_get_method_from_name_t il2cpp_class_get_method_from_name;

/* name: 模块名称
* return: Il2CppImage*
*/
void *il2cpp_get_image(const char *name);

/* image: Il2CppImage*
* namespaze: 名字空间
* name: 类名
* return: Il2CppClass*
*/
void *il2cpp_get_class(const void *image, const char *namespaze, const char *name);

/* klass: Il2CppClass*
* name: 方法名称
* argsCount: 参数个数
* return: MethodInfo*
*/
size_t *il2cpp_get_method(void *klass, const char *name, int argsCount);

3.li2cpp.cpp
extern void unity_il2cpp_luaframework_entry(hook* ptr_hook, void *handle);

il2cpp_domain_get_t il2cpp_domain_get = nullptr;
il2cpp_domain_assembly_open_t il2cpp_domain_assembly_open = nullptr;
il2cpp_assembly_get_image_t il2cpp_assembly_get_image = nullptr;
il2cpp_class_from_name_t il2cpp_class_from_name = nullptr;
il2cpp_class_get_method_from_name_t il2cpp_class_get_method_from_name = nullptr;

void *il2cpp_get_image(const char *name)
{
    void *image = nullptr;
    void *assembly = nullptr;
    void *domain = nullptr;

    do
    {
      if (!(domain = il2cpp_domain_get()))
            break;
      if (!(assembly = il2cpp_domain_assembly_open(domain, name)))
            break;
      if (!(image = il2cpp_assembly_get_image(assembly)))
            break;
    } while (0);

    LOGD("[?] [%s] image[%p]", __FUNCTION__, image);

    return image;
}

void *il2cpp_get_class(const void *image, const char *namespaze, const char *name)
{
    void *clazz = nullptr;
    do
    {
      if (!image)
            break;
      if (!(clazz = il2cpp_class_from_name(image, namespaze, name)))
            break;
    } while (0);

    LOGD("[?] [%s] clazz[%p] namespaze[%s] name[%s]", __FUNCTION__, clazz, namespaze, name);

    return clazz;
}

size_t *il2cpp_get_method(void *klass, const char *name, int argsCount)
{
    size_t *method = nullptr;
    do
    {
      if (!klass)
            break;
      if (!(method = (size_t *)il2cpp_class_get_method_from_name(klass, name, argsCount)))
            break;
    } while (0);

    LOGD("[?] [%s] method[%p] name[%s] argsCount[%d]", __FUNCTION__, method, name, argsCount);

    return method ? (size_t *)(*method) : method;
}

void unity_il2cpp_entry(hook* ptr_hook, void *handle)
{
    size_t find = 0;
    il2cpp_domain_get = (il2cpp_domain_get_t)MS_FindSymbol(handle, "il2cpp_domain_get");
    il2cpp_domain_assembly_open = (il2cpp_domain_assembly_open_t)MS_FindSymbol(handle, "il2cpp_domain_assembly_open");
    il2cpp_assembly_get_image = (il2cpp_assembly_get_image_t)MS_FindSymbol(handle, "il2cpp_assembly_get_image");
    il2cpp_class_from_name = (il2cpp_class_from_name_t)MS_FindSymbol(handle, "il2cpp_class_from_name");
    il2cpp_class_get_method_from_name = (il2cpp_class_get_method_from_name_t)MS_FindSymbol(handle, "il2cpp_class_get_method_from_name");

    LOGD("[+] [%s] il2cpp_domain_get[%p]", __FUNCTION__, il2cpp_domain_get);
    LOGD("[+] [%s] il2cpp_domain_assembly_open[%p]", __FUNCTION__, il2cpp_domain_assembly_open);
    LOGD("[+] [%s] il2cpp_assembly_get_image[%p]", __FUNCTION__, il2cpp_assembly_get_image);
    LOGD("[+] [%s] il2cpp_class_from_name[%p]", __FUNCTION__, il2cpp_class_from_name);
    LOGD("[+] [%s] il2cpp_class_get_method_from_name[%p]", __FUNCTION__, il2cpp_class_get_method_from_name);

    if (il2cpp_domain_get
      && il2cpp_domain_assembly_open
      && il2cpp_assembly_get_image
      && il2cpp_class_from_name
      && il2cpp_class_get_method_from_name)
    {
      find++;
    }

    if (find)
    {
      unity_il2cpp_luaframework_entry(ptr_hook, handle);
    }
}

4.luaframework.cpp
HOOK_DEF(void *, LuaFramework_MessageBox__Show, System_String_o* title, System_String_o* content, void* completed, System_String_o* ok, System_String_o* no, const void* method)
{
    LOGD("[+] [%s] content[%s]", __FUNCTION__, String::GetChar(content));
    String::Set(content, "我是蛤蟆怪aaa");
    return old_LuaFramework_MessageBox__Show(title, content, completed, ok, no, method);
}

void unity_il2cpp_luaframework_entry(hook* ptr_hook, void *handle)
{
    void *image = il2cpp_get_image("LuaFramework.Runtime");
    void *clazz = il2cpp_get_class(image, "LuaFramework", "MessageBox");
    void *method = il2cpp_get_method(clazz, "Show", 5);
    if (method)
    {
      MS_Function(method, LuaFramework_MessageBox__Show);
    }
}

5.总结
前文章既然都是通过符号查找的 il2cpp_class_from_name 那么何必计算偏移量呢 image用api查找出来就行了
没有image的话要等他加载才能获取hook时机 -> 这样主动获取image随时都具有hook时机了
当然抹除符号之后这个依旧行不通

success666 发表于 2022-3-14 14:54

小白表示看不懂啊:'(weeqw
页: [1]
查看完整版本: 一套强劲的 Il2cpp Hook 框架 思考