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
946 stars 194 forks source link

Struct methods may be invoked incorrectly #321

Closed Flechaa closed 10 months ago

Flechaa commented 1 year ago

Take the following:

const double = Il2Cpp.corlib.class("System.Double").new();
double.field("m_value").value = 51.51100833075058;
console.log(double);

const int32 = Il2Cpp.corlib.class("System.Int32").new();
int32.field("m_value").value = 0;
console.log(int32);

Console:

2,65922814801271E-312
1362888960

Logging, for example int32.field("m_value").value, works as expected.

Replicating this issue: #17

const Vector2Class = Il2Cpp.domain.assembly("UnityEngine.CoreModule").image.class("UnityEngine.Vector2");
const vec = Vector2Class.new();
vec.method(".ctor").invoke(36, 4);

console.log("X: " + vec.field("x").value);
console.log("Y: " + vec.field("y").value);

Console:

X: 0
Y: 0

It's important to note that logging just the struct gives me the right values but accessing the fields does not. It also seems that the value applied is the incorrect one being shown and not the one in m_value.

vfsfitvnm commented 1 year ago

When printed, Il2Cpp.Objects call their ToString method. It looks like System.Double and friends do not log their value, but their hash code (int32.method("GetHashCode").invoke()).

Now, the second snippet logs the correct values for me:

X: 36
Y: 4

What's the unity version you are using?

Flechaa commented 1 year ago

When printed, Il2Cpp.Objects call their ToString method. It looks like System.Double and friends do not log their value, but their hash code (int32.method("GetHashCode").invoke()).

Now, the second snippet logs the correct values for me:

X: 36
Y: 4

What's the unity version you are using?

2021.3.15f1

vfsfitvnm commented 1 year ago

If on Android, what's the package id?

Flechaa commented 1 year ago

If on Android, what's the package id?

com.nianticlabs.pokemongo

vfsfitvnm commented 1 year ago

I could reproduce. It looks like this line https://github.com/vfsfitvnm/frida-il2cpp-bridge/blob/41af796c2c8537fa4c3e8b66e242f9429b717bb0/src/il2cpp/structs/method.ts#L309 should be changed to:

return target.invokeRaw.bind(target, instance.handle.add(instance.class.isValueType ? Il2Cpp.Object.headerSize : 0));

I'm not sure whether this is specific to a set of Unity versions (I couldn't reproduce on 2020.3.17f1).

vfsfitvnm commented 1 year ago

Alright, it looks like they changed something starting from Unity 2021.x.x now we just have to find the version where the change has first appeared. Test snippet:

Il2Cpp.perform(() => {
    const MonoRuntimeEventHandle = Il2Cpp.corlib.class("Mono.RuntimeEventHandle");
    const instance = MonoRuntimeEventHandle.alloc();
    instance.method(".ctor").invoke(ptr(0xdeadbeef));

    if (instance.handle.readPointer().equals(ptr(0xdeadbeef))) {
        console.log(Il2Cpp.unityVersion, "is affected!");
    } else {
        console.log(Il2Cpp.unityVersion, "is not affected");
    }
});
vfsfitvnm commented 1 year ago

Alright, it looks like the change first appeared in 2021.2.0f1

vfsfitvnm commented 1 year ago

Fixed in v0.8.4. Thank you for reporting :smile:

thinhbuzz commented 1 year ago

@vfsfitvnm https://github.com/vfsfitvnm/frida-il2cpp-bridge/commit/95eb02ef7edf019466676ac5439b77cc9c5b514b application information is the same as the Fleecha provided above. This commit causes a crash with the message:

Error: access violation accessing 0x5a4


// Assembly-CSharp
class Niantic.Holoholo.Items.StarPiece : Niantic.Holoholo.Items.ItemBuffBase
{
    ♥VZONZZ[XXXO♥ ♥XOVOYSZOXTS♥; // 0x90
    ♥ZZ[VYXMVQS[♥ ♥Q]QPYQPPNNX♥; // 0x98
    System.Int64 ♥RTOOOV]Y]MN♥(); // 0x023685f8
    Niantic.Promises.IPromise Activate(); // 0x02368620
    System.Int64 ♥YORUZMRVOWW♥(); // 0x02368944
    ♥]QSO]PZMOVT♥ get_ItemId(); // 0x0236896c
    ♥]QSO]PZMOVT♥ ♥M[XMQYNUXXX♥(); // 0x02368974
    ♥]QSO]PZMOVT♥ ♥TUQMOPZWXXT♥(); // 0x0236897c
    System.Int64 ♥M]Q[RRRP]]]♥(); // 0x02368984
    System.Int64 get_BuffDurationMs(); // 0x023689ac
    System.Void .ctor(); // 0x023689d4
    System.Int64 ♥ZUNZZ]VTYSW♥(); // 0x023689dc
    System.Int64 ♥VNUTYMMYUYQ♥(); // 0x02368a04
    System.Int64 ♥VVPO[[Y[VSN♥(); // 0x02368a2c
}
// Assembly-CSharp
enum ♥]QSO]PZMOVT♥ : System.Enum
{
    System.Int32 value__; // 0x10
    static ♥]QSO]PZMOVT♥ ITEM_UNKNOWN = 0;
    static ♥]QSO]PZMOVT♥ ITEM_POKE_BALL = 1;
    static ♥]QSO]PZMOVT♥ ITEM_GREAT_BALL = 2;
    static ♥]QSO]PZMOVT♥ ITEM_ULTRA_BALL = 3;
    static ♥]QSO]PZMOVT♥ ITEM_MASTER_BALL = 4;
    static ♥]QSO]PZMOVT♥ ITEM_PREMIER_BALL = 5;
    static ♥]QSO]PZMOVT♥ ITEM_BEAST_BALL = 6;
    static ♥]QSO]PZMOVT♥ ITEM_POTION = 101;
    static ♥]QSO]PZMOVT♥ ITEM_SUPER_POTION = 102;
    static ♥]QSO]PZMOVT♥ ITEM_HYPER_POTION = 103;
    static ♥]QSO]PZMOVT♥ ITEM_MAX_POTION = 104;
    static ♥]QSO]PZMOVT♥ ITEM_REVIVE = 201;
    static ♥]QSO]PZMOVT♥ ITEM_MAX_REVIVE = 202;
    static ♥]QSO]PZMOVT♥ ITEM_LUCKY_EGG = 301;
    static ♥]QSO]PZMOVT♥ ITEM_INCENSE_ORDINARY = 401;
    static ♥]QSO]PZMOVT♥ ITEM_INCENSE_SPICY = 402;
    static ♥]QSO]PZMOVT♥ ITEM_INCENSE_COOL = 403;
    static ♥]QSO]PZMOVT♥ ITEM_INCENSE_FLORAL = 404;
    static ♥]QSO]PZMOVT♥ ITEM_INCENSE_BELUGA_BOX = 405;
    static ♥]QSO]PZMOVT♥ ITEM_INCENSE_DAILY_ADVENTURE = 406;
    static ♥]QSO]PZMOVT♥ ITEM_INCENSE_SPARKLY = 407;
    static ♥]QSO]PZMOVT♥ ITEM_TROY_DISK = 501;
    static ♥]QSO]PZMOVT♥ ITEM_TROY_DISK_GLACIAL = 502;
    static ♥]QSO]PZMOVT♥ ITEM_TROY_DISK_MOSSY = 503;
    static ♥]QSO]PZMOVT♥ ITEM_TROY_DISK_MAGNETIC = 504;
    static ♥]QSO]PZMOVT♥ ITEM_TROY_DISK_RAINY = 505;
    static ♥]QSO]PZMOVT♥ ITEM_TROY_DISK_SPARKLY = 506;
    static ♥]QSO]PZMOVT♥ ITEM_X_ATTACK = 602;
    static ♥]QSO]PZMOVT♥ ITEM_X_DEFENSE = 603;
    static ♥]QSO]PZMOVT♥ ITEM_X_MIRACLE = 604;
    static ♥]QSO]PZMOVT♥ ITEM_RAZZ_BERRY = 701;
    static ♥]QSO]PZMOVT♥ ITEM_BLUK_BERRY = 702;
    static ♥]QSO]PZMOVT♥ ITEM_NANAB_BERRY = 703;
    static ♥]QSO]PZMOVT♥ ITEM_WEPAR_BERRY = 704;
    static ♥]QSO]PZMOVT♥ ITEM_PINAP_BERRY = 705;
    static ♥]QSO]PZMOVT♥ ITEM_GOLDEN_RAZZ_BERRY = 706;
    static ♥]QSO]PZMOVT♥ ITEM_GOLDEN_NANAB_BERRY = 707;
    static ♥]QSO]PZMOVT♥ ITEM_GOLDEN_PINAP_BERRY = 708;
    static ♥]QSO]PZMOVT♥ ITEM_POFFIN = 709;
    static ♥]QSO]PZMOVT♥ ITEM_SPECIAL_CAMERA = 801;
    static ♥]QSO]PZMOVT♥ ITEM_STICKER_INVENTORY = 802;
    static ♥]QSO]PZMOVT♥ ITEM_POSTCARD_INVENTORY = 803;
    static ♥]QSO]PZMOVT♥ ITEM_BREAKFAST = 651;
    static ♥]QSO]PZMOVT♥ ITEM_INCUBATOR_BASIC_UNLIMITED = 901;
    static ♥]QSO]PZMOVT♥ ITEM_INCUBATOR_BASIC = 902;
    static ♥]QSO]PZMOVT♥ ITEM_INCUBATOR_SUPER = 903;
    static ♥]QSO]PZMOVT♥ ITEM_POKEMON_STORAGE_UPGRADE = 1001;
    static ♥]QSO]PZMOVT♥ ITEM_ITEM_STORAGE_UPGRADE = 1002;
    static ♥]QSO]PZMOVT♥ ITEM_POSTCARD_STORAGE_UPGRADE = 1003;
    static ♥]QSO]PZMOVT♥ ITEM_SUN_STONE = 1101;
    static ♥]QSO]PZMOVT♥ ITEM_KINGS_ROCK = 1102;
    static ♥]QSO]PZMOVT♥ ITEM_METAL_COAT = 1103;
    static ♥]QSO]PZMOVT♥ ITEM_DRAGON_SCALE = 1104;
    static ♥]QSO]PZMOVT♥ ITEM_UP_GRADE = 1105;
    static ♥]QSO]PZMOVT♥ ITEM_GEN4_EVOLUTION_STONE = 1106;
    static ♥]QSO]PZMOVT♥ ITEM_GEN5_EVOLUTION_STONE = 1107;
    static ♥]QSO]PZMOVT♥ ITEM_OTHER_EVOLUTION_STONE_A = 1150;
    static ♥]QSO]PZMOVT♥ ITEM_BEANS = 650;
    static ♥]QSO]PZMOVT♥ ITEM_MOVE_REROLL_FAST_ATTACK = 1201;
    static ♥]QSO]PZMOVT♥ ITEM_MOVE_REROLL_SPECIAL_ATTACK = 1202;
    static ♥]QSO]PZMOVT♥ ITEM_MOVE_REROLL_ELITE_FAST_ATTACK = 1203;
    static ♥]QSO]PZMOVT♥ ITEM_MOVE_REROLL_ELITE_SPECIAL_ATTACK = 1204;
    static ♥]QSO]PZMOVT♥ ITEM_MOVE_REROLL_OTHER_SPECIAL_ATTACK_A = 1250;
    static ♥]QSO]PZMOVT♥ ITEM_RARE_CANDY = 1301;
    static ♥]QSO]PZMOVT♥ ITEM_XL_RARE_CANDY = 1302;
    static ♥]QSO]PZMOVT♥ ITEM_FREE_RAID_TICKET = 1401;
    static ♥]QSO]PZMOVT♥ ITEM_PAID_RAID_TICKET = 1402;
    static ♥]QSO]PZMOVT♥ ITEM_LEGENDARY_RAID_TICKET = 1403;
    static ♥]QSO]PZMOVT♥ ITEM_STAR_PIECE = 1404;
    static ♥]QSO]PZMOVT♥ ITEM_FRIEND_GIFT_BOX = 1405;
    static ♥]QSO]PZMOVT♥ ITEM_TEAM_CHANGE = 1406;
    static ♥]QSO]PZMOVT♥ ITEM_REMOTE_RAID_TICKET = 1408;
    static ♥]QSO]PZMOVT♥ ITEM_S_RAID_TICKET = 1409;
    static ♥]QSO]PZMOVT♥ ITEM_LEADER_MAP_FRAGMENT = 1501;
    static ♥]QSO]PZMOVT♥ ITEM_LEADER_MAP = 1502;
    static ♥]QSO]PZMOVT♥ ITEM_GIOVANNI_MAP = 1503;
    static ♥]QSO]PZMOVT♥ ITEM_SHADOW_GEM_FRAGMENT = 1504;
    static ♥]QSO]PZMOVT♥ ITEM_SHADOW_GEM = 1505;
    static ♥]QSO]PZMOVT♥ ITEM_GLOBAL_EVENT_TICKET = 1600;
    static ♥]QSO]PZMOVT♥ ITEM_EVENT_TICKET_PINK = 1601;
    static ♥]QSO]PZMOVT♥ ITEM_EVENT_TICKET_GRAY = 1602;
    static ♥]QSO]PZMOVT♥ ITEM_GLOBAL_EVENT_TICKET_TO_GIFT = 1603;
    static ♥]QSO]PZMOVT♥ ITEM_EVENT_TICKET_PINK_TO_GIFT = 1604;
    static ♥]QSO]PZMOVT♥ ITEM_EVENT_TICKET_GRAY_TO_GIFT = 1605;
    static ♥]QSO]PZMOVT♥ ITEM_BATTLE_PASS_TICKET = 1606;
    static ♥]QSO]PZMOVT♥ ITEM_EVERGREEN_TICKET = 1607;
    static ♥]QSO]PZMOVT♥ ITEM_EVERGREEN_TICKET_TO_GIFT = 1608;
    static ♥]QSO]PZMOVT♥ ITEM_DEPRECATED_1 = 1609;

}
#
vfsfitvnm commented 1 year ago

@thinhbuzz What's the line that causes the error?

thinhbuzz commented 1 year ago

@vfsfitvnm sorry for the lack of information, the error was encountered when calling function get_ItemId, it also happens with any function that returns an enum


starPiece.method<Il2Cpp.Object>('get_ItemId').invoke()
thinhbuzz commented 1 year ago

i think we need to exclude enum case, i am not sure but i have success with it.

if (instance.class.isValueType && !instance.class.isEnum && !Il2Cpp.unityVersionIsBelow202120) {
   instanceHandle = instanceHandle.add(Il2Cpp.Object.headerSize);
}
vfsfitvnm commented 1 year ago

Yeah, thanks, it looks like so. We really need tests...

thinhbuzz commented 1 year ago

We will be here to help you test as many cases as possible. Thanks for this great project and thank you so much for the quick response

vfsfitvnm commented 10 months ago

~~Ok, it wasn't really a problem of method invocations, but it was about calculating the handle (a NativePointer) to read field values. Only boxed structs seems to be affected, and this extra scenario seemed to only occur in Unity > 2021.2.0f1, but it was observed in 5.3.5f1 as well. I don't know if I missed something, however I just implemented a future proof :tm: solution so that it should work under any circumstances~~

nope, the problem was really about method invocations

vfsfitvnm commented 10 months ago

(Thanks @Flechaa for reporting)