一些使用 - 350030173/frida-il2cpp-bridge GitHub Wiki

主动调用非静态方法:

import "frida-il2cpp-bridge";

async function main()
{
    await Il2Cpp.initialize();

    //Il2Cpp.dump("/sdcard/dump.cs");
    const AssemblyCSharp = Il2Cpp.Domain.reference.assemblies["Assembly-CSharp"].image;
    const GameUICtrl = AssemblyCSharp.classes["GameUICtrl"];
    var GameLosePanelCtrl = AssemblyCSharp.classes["GameLosePanelCtrl"];
    GameUICtrl.methods["onClickTipBtn"].intercept({
        onEnter(instance, parameters)
        {
            //先查找要主动调用的方法所属的类的实例,如果调用的是静态方法,则不需要找实例
            Il2Cpp.GC.choose(GameLosePanelCtrl).forEach(instance =>
            {
                if (instance.class.type.name == "GameLosePanelCtrl")
                {
                    console.log("fund GameLosePanelCtrl instance . . .");
                    //主动调用
                    instance.methods["onShowAnswer"].invoke();
                }
            });
        },
        onLeave(returnValue)
        {
        }
    });
}

main().catch(error => console.log(error.stack));

trace类下所有的函数,并过滤打印非常频繁的函数

//0.5.1版本
export function traceClass(klass: Il2Cpp.Class, excludes: string[] = []): void {
    const methods = [];
    for (const method of Object.values(klass.methods)) {
        if (excludes.includes(method.name)) {
            continue;
        }

        methods.push(method);
    }
 
    Il2Cpp.Tracer.fullWithValuesTrace(...methods);
}

//调用
traceClass(SomeIl2CppClass, ['FixedUpdate', 'Update']);

或者

const CoreModule = Il2Cpp.Domain.reference.assemblies["UnityEngine.CoreModule"].image;
const Application = CoreModule.classes["UnityEngine.Application"];

const tracees = { ...Application.methods };//得到类下所有的函数
delete tracees.get_isPlaying;//删除某个函数

Il2Cpp.Tracer.fullWithValuesTrace(...Object.values(tracees));

根据参数不同,替换值 案例:论如何建立一个修仙门派国际服

import "frida-il2cpp-bridge";

Il2Cpp.perform(() =>
{
    const AssemblyCSharp = Il2Cpp.Domain.assemblies["Assembly-CSharp"].image;
    const mydicfloat = AssemblyCSharp.classes["mydicfloat"];
    mydicfloat.methods["set_Item"].implementation = function (str, mydouble): void
    {
        //str.content用于获取字符串,才能和别的字符串对比
        //如果只是str,也是能打印出字符串,但是无法进行对比
        if (str.content == "money" || str.content == "rock0")
        {
            console.log(str.content);
            console.log(mydouble);
            
            //主动调用,并设置不同的值
            this.methods.set_Item.invoke(str, 666666);
        } else
        {
            //调用原来的函数,不做修改
            this.methods.set_Item.invoke(str, mydouble);
        }
    };
});

报错问题: 找不到名称 "console"。是否需要更改目标库? 请尝试将 lib 编译器选项更改为包含 "dom"。ts(2584) 在tsconfig.json中

{
  "compilerOptions": {
    "target": "es2020",
    "lib": [
      "es2020",//===============有个逗号
      "dom"//===============添加这个
    ],
    "allowJs": true,
    "noEmit": true,
    "strict": true,
    "esModuleInterop": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "skipLibCheck": true,
    "allowSyntheticDefaultImports": true
  }
}

返回值加以利用

    GameObject.methods["get_transform"].implementation = function ()
    {

        const origina = new Il2Cpp.Object(this.handle);
        console.log("当前类:" + origina);
        const ori = origina.class.name;
        console.log("当前类类名:" + ori);


        //public sealed class RectTransform : Transform
        //public Transform get_transform(); //0x5C91D8
        // get_transform 所有的类的实现类, get_transform 返回值是 Transform ,class RectTransform 继承于 Transform
        const transform = this.methods.get_transform.invoke();
        console.log("get_transform所属的类的子类:" + String(transform));


        const testObject = transform as Il2Cpp.Object;
        const childClass = testObject.class.name;
        console.log("get_transform所属的类的子类 类名:" + childClass);

        return transform;
    };

方法参数是对象,设置对象中的局部变量,方式1: //frida-il2cpp-bridge代码,版本是0.5.1 //测试用例:莱娜世界_v2.2(31) //国家领导人:战略决策者_v0.1.9(9)

import "frida-il2cpp-bridge";
Il2Cpp.perform(() =>
{
    //获取 Inventory 类
    const Inventory = Il2Cpp.Domain.assemblies["Assembly-CSharp"].image.classes["Inventory"];

    //获取 CataloguesData.ItemData 类
    const ItemData = Il2Cpp.Domain.assemblies["Assembly-CSharp"].image.classes["CataloguesData.ItemData"];

    //hook住 Inventory 类下的 OnBuyitem 方法 ,有一个参数:itemData
    Inventory.methods["OnBuyitem"].implementation = function (itemData)
    {
        //从内存中搜索到 CataloguesData.ItemData 类实例
        Il2Cpp.GC.choose(ItemData).forEach(instance => 
        {
            //根据实例对象,设置price值为负数
            instance.fields.price.value = -1000;
        });

        //主动调用 Inventory 类的 OnBuyitem 方法
        const result = this.methods.OnBuyitem.invoke(itemData);
        return result;
    };
});

方法参数是对象,设置对象中的局部变量,方式2:

import "frida-il2cpp-bridge";

//hook  憎恨之心:亡者归来_v1.0.0(100)
Il2Cpp.perform(() =>
{
    const AssemblyCSharp = Il2Cpp.Domain.assemblies["Assembly-CSharp"].image
    AssemblyCSharp.classes["SA2.MonsterBaseController"].methods["OnDamage"].implementation = function (Affect_Damage)
    {
        //根据参数获取参数对象
        const Affect_Damage2 = Affect_Damage as Il2Cpp.Object;
        
        //获取对象类的成员变量值
        const monsterphysicalDamage = Affect_Damage2.fields["physicalDamage"].value
        console.log("=====monsterphysicalDamage:" + monsterphysicalDamage);
        
        //修改成员变量值
        Affect_Damage2.fields["physicalDamage"].value = 100000
        
        //主动调用被hook的方法
        const ret = this.methods.OnDamage.invoke(Affect_Damage)
        return ret;
    };
});

方法参数是对象,调用方法: 免广告

import "frida-il2cpp-bridge";

//案例:火箭飞拳_v2.2.1(32)
Il2Cpp.perform(() =>
{
    const AssemblyCSharp = Il2Cpp.Domain.assemblies["Assembly-CSharp"].image
    AssemblyCSharp.classes["AppLovinManager"].methods["ShowRewardAd"].implementation = function (AdsType, callback)
    {
        //获取对象
        const my_call_back = callback as Il2Cpp.Object
        
        //使用对象直接调用方法
        my_call_back.methods["Invoke"].invoke(1)
    };
});

查找某个gameobject(点击后)

import "frida-il2cpp-bridge";

Il2Cpp.perform(() =>
{
    const CoreModule = Il2Cpp.Domain.assemblies["UnityEngine.CoreModule"].image;
    const GameObject = CoreModule.classes["UnityEngine.GameObject"];
    GameObject.methods["get_transform"].implementation = function ()
    {
        var transform = this.methods.get_transform.invoke();
        //console.log("=======" + String(transform))//显示gameobject名
        if (String(transform) == "MenuButton (UnityEngine.RectTransform)")
        {
            console.log("=======" + String(transform))
            //this.methods.SetActive.invoke(false);//隐藏指定gameobject
        }
        return transform;
    };
});

主动调用设置某个控件隐藏 //案例:我眼神贼好_v1.9.5(90)_(com.find.hidden.object.difference.clue))

function myfun()
{
    Il2Cpp.perform(() =>
    {
        const GameObject = Il2Cpp.Domain.assembly("UnityEngine.CoreModule").image.class("UnityEngine.GameObject");
        var Find = GameObject.method("Find");//Find是静态的函数,public static GameObject Find(string name); 
        //商店按钮
        var StoreBtn = Find.invoke(Il2Cpp.String.from("StoreBtn")) as unknown as Il2Cpp.Class;

        if (JSON.stringify(StoreBtn) != "\{\"handle\":\"0x0\"\}")
        {
            console.log("--StoreBtn" + JSON.stringify(StoreBtn));
            StoreBtn.method("SetActive").invoke(false);
            //clearInterval(myid);
        }

        //声音按钮
        var Sound = Find.invoke(Il2Cpp.String.from("Sound")) as unknown as Il2Cpp.Class;
        if (JSON.stringify(Sound) != "\{\"handle\":\"0x0\"\}")
        {
            console.log("---Sound-----:" + String(Sound));
            Sound.method("SetActive").invoke(false);
        }
    });
}
//获取可以通过hook 载入场景的时候再启动hook
var myid = setInterval(myfun, 100)//一直调用,可能会效率,没找到更的方法

获取成员变量值:

import "frida-il2cpp-bridge";

Il2Cpp.perform(() =>
{
    const AssemblyCSharp = Il2Cpp.Domain.assemblies["Assembly-CSharp"]
    const AppLovinManager = AssemblyCSharp.image.classes["WeaponBehavior"];

    const myfields = { ...AppLovinManager.fields };

    //静态成员变量
    for (var i in myfields)
    {
        if (myfields[i].isStatic)
        {
            console.log("\n" + myfields[i].name + "; // " + myfields[i].offset, "\x1b[32m" + myfields[i].value + "\x1B[0m")
        }
    }

    //动态成员变量
    Il2Cpp.GC.choose(AppLovinManager).forEach((instance: Il2Cpp.Object) => 
    {
        var dynamicFields = instance.fields
        for (var i in dynamicFields)
        {
            console.log("\n" + dynamicFields[i], "\x1b[33m" + dynamicFields[i].value + "\x1B[0m")
        }
    });

});

如果被hook的函数无法hook,说明游戏本身可能有问题 可以在被hook的方法中添加:

https://github.com/vfsfitvnm/frida-il2cpp-bridge/issues/198

Il2Cpp.installExceptionListener("all");