vfsfitvnm / frida-il2cpp-bridge

A Frida module to dump, trace or hijack any Il2Cpp application at runtime, without needing the global-metadata.dat file.
https://github.com/vfsfitvnm/frida-il2cpp-bridge/wiki
MIT License
1.06k stars 204 forks source link

Question: Return object #435

Open choldi opened 1 year ago

choldi commented 1 year ago

I have this classes:

// Assembly-CSharp
class Game.Core.DatabaseSystem.DataSheet.DataRecord : System.Object, Game.Core.DatabaseSystem.IRecord
{
    System.String <ID>k__BackingField; // 0x10
    System.String <Name>k__BackingField; // 0x18
    System.Int32 <Value>k__BackingField; // 0x48
    System.String <Item1>k__BackingField; // 0x50
    System.Collections.Generic.List<System.String> <Equipments>k__BackingField; // 0x68
    System.String get_ID(); // 0x01750d08
    System.Void set_ID(System.String value); // 0x01750d10
    System.String get_Name(); // 0x01750d18
    System.Void set_Name(System.String value); // 0x01750d20
    System.Collections.Generic.List<System.String> get_Equipments(); // 0x01750db8
    System.Void set_Equipments(System.Collections.Generic.List<System.String> value); // 0x01750dc0
    System.Void .ctor(); // 0x01750c18
}

// Assembly-CSharp
class Game.Core.DatabaseSystem.DataSheet : Date.Core.DatabaseSystem.Sheet<Game.Core.DatabaseSystem.DataSheet.DataRecord>
{

    System.Void .ctor(); // 0x017508c4
    System.Void .ctor(System.Collections.Generic.List<System.String> lines); // 0x0174fcbc
    System.Void Load(System.Collections.Generic.List<System.String> strLines); // 0x0175090c
    Game.Core.DatabaseSystem.DataSheet.DataRecord GetData(); // 0x01750ca0
}

And I want to overrride the GetData method. I've tried this, but gives me error.

import "frida-il2cpp-bridge";

Il2Cpp.perform(() => {

    console.log(Il2Cpp.unityVersion);
    const SystemInt32 = Il2Cpp.corlib.class("System.Int32");
    const SystemString = Il2Cpp.corlib.class("System.String").type;
    Il2Cpp.trace()
        .assemblies(Il2Cpp.domain.assembly("Assembly-CSharp"))
        .and()
        .attach();

    const mscorlib = Il2Cpp.domain.tryAssembly("Assembly-CSharp")?.image
    if (mscorlib) {
        const PackRecord = mscorlib.class("Gaqme.Core.DatabaseSystem.HeroSheet");
        // @ts-ignore
        PackRecord.method("GetData").implementation = function():Il2Cpp.Object {
            const ret:Il2Cpp.Object=this.method("GetData").invoke<Il2Cpp.Object>();
            console.log("Data:", ret.ID, ret.Name);
           return ret;
        }
    };
})

How can I translate the c# class Game.Core.DatabaseSystem.DataSheet.DataRecord to TS and receive this data and return this data?

movedaccount-droid commented 1 year ago

Gaqme.Core.DatabaseSystem.HeroSheet -> Game.Core.DatabaseSystem.HeroSheet use ret.field("ID").value to get values from object fields

choldi commented 1 year ago

const PackRecord = mscorlib.class("Gaqme.Core.DatabaseSystem.HeroSheet"); // @ts-ignore PackRecord.method("GetData").implementation = function():Il2Cpp.Object { const ret:Il2Cpp.Object=this.method("GetData").invoke(); console.log("Data:", ret.ID, ret.Name); return ret;

Thanks @ralcore but I get these compile error:

0:34:32 - File change detected. Starting incremental compilation...
agent/index.ts(18,19): error TS2322: Type 'ReturnType' is not assignable to type 'Object'.
  Type 'number' is not assignable to type 'Object'.
agent/index.ts(18,73): error TS2558: Expected 0 type arguments, but got 1.

0:34:32 - Found 2 errors. Watching for file changes.

Line 18 is the call to the original method. This happened also before correct the object name :

const ret:Il2Cpp.Object=this.method("GetData").invoke<Il2Cpp.Object>();

movedaccount-droid commented 1 year ago

missed that, object generic type is applied to method not invoke - this.method("GetData").invoke(); -> this.method("GetData").invoke();

choldi commented 1 year ago

Thanks again @ralcore Compile right now but the funcion seems not to be called. Perhaps the implementation it is not been called because is a new implementation.

The original GetData() returns Game.Core.DatabaseSystem.DataSheet.DataRecord instance The GetData() in my implementation returns a generic Il2Cpp.Object

Could I implement with onEnter and OnLeave? How can I rewrite?

Still a long way ahead to learn for me...

namtacs commented 2 months ago

this Il2Cpp.Object would contain Game.Core.DatabaseSystem.DataSheet.DataRecord as the library does not generate bindings and every object is Il2Cpp.Object