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.03k stars 202 forks source link

dlopen hook fails on Android 12 (gadget) #185

Closed falconman44 closed 1 year ago

falconman44 commented 2 years ago

I'm back with another fun debugging problem. This time it seems the library doesn't play well with Samsung Galaxy S22 ultra devices.

Just to make sure it's not a Frida issue I got a user to run the following in a Frida Gadget script

'use strict';

console.log("Waiting for Java..");

Java.perform(function () {
  var Log = Java.use("android.util.Log");
  Log.v("frida-lief", "Have fun!");
});

Which logs as expected. Good. So lets try the library now

'use strict';
import "frida-il2cpp-bridge";

console.log("Waiting for Java..");

Il2Cpp.perform(() => {
    Java.perform(function () {
        var Log = Java.use("android.util.Log");
        Log.v("frida-lief", "Have fun!");
    });
});

Crashes immediately after booting.

While I wait for them to come online and test a new version I created to try and narrow down exactly where the crash occurs, I figured I'd come here and see if you may have any insight on what we should try to narrow this down. The only big obvious difference I see right now is the Galaxy S22 runs the Armv9 architecture while most newer devices are on Armv8.

EDIT: The crash doesn't happen if initialize() is commented out EDIT2: Reverted the fix done in #95 and it still didn't open so it's unrelated EDIT 3: commenting out https://github.com/vfsfitvnm/frida-il2cpp-bridge/blob/b49a0c642d4d741551f700bd55f644d9883e015c/src/il2cpp/base.ts#L148 stops the crash

vfsfitvnm commented 2 years ago

Well, I guess the problem still resides in the dlopen interceptor mechanism (here).

First things first, did you try with the latest frida and frida-il2cpp-bridge? Also, did you try the things I said in the #95? (this one in particular)

falconman44 commented 2 years ago

I combined all 3 of those previous suggestions and it spit out this.

05-14 13:38:34.813 13030 13079 V frida-lief: android_dlopen_ext loading /data/user_de/0/com.google.android.gms/app_chimera/m/00000028/oat/arm64/dl-AdsFdrDynamite.integ_221310604100000.odex
05-14 13:38:34.817 13030 13030 V frida-lief: android_dlopen_ext loading /data/app/5mYlMtgVXNQw7jE7VjhwjA==/com.spaceapegames.beatstarxxxx-zwWjDXBylgykdq4Q-usTAA==/lib/arm64/libmain.so
05-14 13:38:34.819 13030 13030 V frida-lief: dlopen loading /data/app/5mYlMtgVXNQw7jE7VjhwjA==/com.spaceapegames.beatstarxxxx-zwWjDXBylgykdq4Q-usTAA==/lib/ar64/libunity.so
05-14 13:38:34.819 13030 13030 V frida-lief: loader_dlopen loading /data/app/~~=/lib/arm64/libunity.so
05-14 13:38:34.832 13030 13083 V frida-lief: android_dlopen_ext loading /data/ite.odex
05-14 13:38:34.850 13030 13030 V frida-lief: dlopen loading libvpsextension.so
05-14 13:38:34.850 13030 13030 V frida-lief: loader_dlopen loading libvpsextension.so
05-14 13:38:34.857 13030 13047 V frida-lief: dlopen loading libvpsextension.so
05-14 13:38:34.858 13030 13047 V frida-lief: __loader_dlopen loading libvpsextension.so

Then it crashed as I'm using the original unmodified bridge. Reinstalled frida latest version yesterday and updated frida-il2cpp-bridge to 0.7.13.

vfsfitvnm commented 2 years ago

Wuould you try one thing at time?

falconman44 commented 2 years ago

Would you try one thing at time?

Yup sure.

05-15 14:42:20.779 26933 26933 V frida-lief: __loader_dlopen loading /data/app/~~Ugz9l3HuiHeU8jL5m41PAg==/com.spaceapegames.beatstarxxxx-IdeGU22YhLx1Omi8HJV5SA==/lib/arm64/libunity.so
05-15 14:46:44.896 28197 28251 V frida-lief: android_dlopen_ext loading /data/user_de/0/com.google.android.gms/app_chimera/m/00000033/oat/arm64/DynamiteLoader.odex
05-15 14:46:44.909 28197 28251 V frida-lief: android_dlopen_ext loading /data/user_de/0/com.google.android.gms/app_chimera/m/00000028/oat/arm64/dl-AdsFdrDynamite.integ_221310604100000.odex
05-15 14:46:44.920 28197 28197 V frida-lief: android_dlopen_ext loading /vendor/lib64/hw/android.hardware.graphics.mapper@4.0-impl-qti-display.so
05-15 14:46:44.922 28197 28255 V frida-lief: android_dlopen_ext loading /data/user_de/0/com.google.android.gms/app_chimera/m/00000038/oat/arm64/MeasurementDynamite.odex
05-15 14:48:11.299 28402 28402 V frida-lief: dlopen loading /data/app/~~Ugz9l3HuiHeU8jL5m41PAg==/com.spaceapegames.beatstarxxxx-IdeGU22YhLx1Omi8HJV5SA==/lib/arm64/libunity.so
05-15 14:48:11.325 28402 28402 V frida-lief: dlopen loading libvpsextension.so
05-15 14:48:11.328 28402 28426 V frida-lief: dlopen loading libvpsextension.so

They of course all crash after that.

vfsfitvnm commented 2 years ago

Hmm, so, we must first understand what causes the crash - this is still A12. Is it Interceptor.attach? Is it due to samsung's kernel? Does Interceptor.replace work? Do we need to hook a different dlopen (if there's one)?

I can't dig into this (also, if it's a device specific issue, I honestly don't care), so it's all up to you.

falconman44 commented 2 years ago

I'll do some investigating but I'm my no means a Frida expert.

I'm looking through the source trying to make sense of what forModule in native-wait is doing exactly. From the name I would have to assume it just waits for the relevant libraries to be loaded? That's what it looks like to me.

I'm at work for 4 hours so if you don't see this by then I'll just delete it but could I just replace forModule with a timer for a few seconds if I don't care about attaching it immediately? I have a window of like 10~ seconds to work with which should be more than enough to half ass it.

vfsfitvnm commented 2 years ago

From the name I would have to assume it just waits for the relevant libraries to be loaded?

Exactly.

could I just replace forModule with a timer for a few seconds if I don't care about attaching it immediately?

You could do this then:

setTimeout(() => {
    Il2Cpp.perform(() => {

    });
}, 3000);
falconman44 commented 2 years ago

From the name I would have to assume it just waits for the relevant libraries to be loaded?

Exactly.

could I just replace forModule with a timer for a few seconds if I don't care about attaching it immediately?

You could do this then:

setTimeout(() => {
    Il2Cpp.perform(() => {

    });
}, 3000);

Good point, it does check for the modules first thing doesn't it. I'll see how it goes.

falconman44 commented 2 years ago

Well it doesn't crash with the delay added and it seems perform() is called successfully so that's good enough for me.

vfsfitvnm commented 2 years ago

@falconman44 yep, because at that point, the module (libil2cpp.so) is already loaded and a wait (what caused the crash) is not required anymore.


Uunless there won't be any update, I'll close this issue in a week or so.

falconman44 commented 1 year ago

I'm not sure this is specifically related to Android 12. Since I posted this the only people I've had to get to use a setTimeout(function, 3000) delay are using Samsung Galaxy S22 devices. @350030173 mind sharing what device you're using that fails with the gadget?

350030173 commented 1 year ago

I'm not sure this is specifically related to Android 12. Since I posted this the only people I've had to get to use a setTimeout(function, 3000) delay are using Samsung Galaxy S22 devices. @350030173 mind sharing what device you're using that fails with the gadget?

device: xiaomi 12 Android version: 12

vfsfitvnm commented 1 year ago

I tried to reproduce on a A12 Samsung device, but didn't succeed :/

vfsfitvnm commented 1 year ago

I want to fix this one so bad, can you guys help me out? The thing I don't really get is why it crashed on Gadget - would you describe the exact way (steps, tools, script and so on) to built the APK?

350030173 commented 1 year ago

I want to fix this one so bad, can you guys help me out? The thing I don't really get is why it crashed on Gadget - would you describe the exact way (steps, tools, script and so on) to built the APK?

i try this,it will not crash

function hook_sigaction()
{
    var sigaction = Module.findExportByName(null, "sigaction");
    if (sigaction)
    {
        var before = Process.findRangeByAddress(sigaction);
        //console.log("before:", JSON.stringify(before, null, 4));
        var after = Memory.protect(sigaction, 4096, 'rwx');
        //console.log("after:", after);
    }
    myfun()
}

function myfun() 
{
    Il2Cpp.perform(() =>
    {
        console.log("succ.....");
    }

}
setImmediate(hook_sigaction);
vfsfitvnm commented 1 year ago

Uhm, that's odd. It looks like it's a Frida bug, then.

I also encountered this similar bug myself - dlopen cannot be intercepted in some implementation-specific scenarios...

At this point I'm wondering if it makes sense to keep using Interceptor (it's platform dependent and thus hard to maintain).

The easier, simpler (but anti pattern) way would consist in just polling e.g. Process.findModuleByName within a setInterval...

vfsfitvnm commented 1 year ago

@350030173 I made some changes (pushed in master) - I hook dlopen differently now; are you able to see if it works now?

vfsfitvnm commented 1 year ago

I believe v0.8.7 fixed this issue, as android_dlopen_ext and dlopen aren't hooked anymore. Pinging both of you @350030173 @falconman44, I appreciate any feedback :pray:

350030173 commented 5 months ago

Some games will still crash, even if don't use the frida-il2cpp-bridge and just load a frida-gadget. i think this is frida bug