Skip to content

Use stable fields for ART class spec offset detection#361

Merged
oleavr merged 3 commits into
frida:mainfrom
AeonLucid:fix/art-class-spec-stable
Jul 21, 2025
Merged

Use stable fields for ART class spec offset detection#361
oleavr merged 3 commits into
frida:mainfrom
AeonLucid:fix/art-class-spec-stable

Conversation

@AeonLucid

@AeonLucid AeonLucid commented Jul 20, 2025

Copy link
Copy Markdown
Contributor

Addresses crashes commented under the previous pull request #359.
These fields shouldn't be optimised away.

Edit: Also added an extra check for the art array length. Sometimes it would read a negative number when trying offsets, and it would infinitely loop.

@oleavr

oleavr commented Jul 21, 2025

Copy link
Copy Markdown
Member

Thanks!

Edit: Also added an extra check for the art array length. Sometimes it would read a negative number when trying offsets, and it would infinitely loop.

This seems impossible looking at the code, given that readU* return unsigned values. Would be good to get to the bottom of why, so we don't paper over a bug that might bite us later.

@oleavr oleavr merged commit 020a542 into frida:main Jul 21, 2025
1 of 11 checks passed
@oleavr

oleavr commented Jul 21, 2025

Copy link
Copy Markdown
Member

Thanks! 🙌

oleavr added a commit to frida/frida-core that referenced this pull request Jul 21, 2025
@ExternalAddress4401

ExternalAddress4401 commented Jul 22, 2025

Copy link
Copy Markdown

Sorry to be this guy but I'm trying to track down one of 2 things that might be causing my issues.

With this change my error is now

07-21 20:02:37.145 27126 27126 F DEBUG : Abort message: 'No pending exception expected: java.lang.NoSuchFieldError: no "Ljava/lang/String;" field "path" in class "Ljava/io/File;" or its superclasses

import "frida-il2cpp-bridge";
import Logger from "../lib/Logger.js";
import fs from "frida-fs";
import { decrypt } from "../lib/Encrypter.js";
import { Buffer } from "buffer";
import Java from "frida-java-bridge";

Java.perform(() => {
  Logger.log("Inside java");
  Il2Cpp.perform(async () => {
  Logger.log("Inside");
  const path = "sdcard/script/override.js";

  const script: any = fs.readFileSync(path);
  const code = Buffer.from(script.toString(), "base64").toString();
  const decrypted = decrypt(code);

  Logger.log("decrypted");

  try {
    eval(decrypted);
    Logger.log("eval");
  } catch (e) {
    const error = e as Error;
    Logger.log(`Error running script: ${error.message}`);
  }
  }, "main");
});

This eval's a simple script

import Java from "frida-java-bridge";
import Logger from '../lib/Logger';

Java.perform(() => {
	Logger.log("Hello!");
})

Where Logger contains my aforementioned var Log = Java.use("android.util.Log"); calls. This eval'd script crashes with the error I gave.

You'll notice this uses frida-il2cpp-bridge and when I comment out the calls to Il2Cpp.Perform it NO LONGER crashes.

I find the error peculiar as it relates to this PR but the commented out code points to the library. I'm going to post this in both places to try and narrow down the issue but I'd appreciate any insight if you have it.

@AeonLucid

AeonLucid commented Jul 22, 2025

Copy link
Copy Markdown
Contributor Author

@ExternalAddress4401 Can you provide a minimal script, frida cli arguments and a target app so that I can reproduce the error?

@ExternalAddress4401

ExternalAddress4401 commented Jul 22, 2025

Copy link
Copy Markdown

My setup is somewhat of a mess so I have the smallest repro I can manage at: https://github.com/ExternalAddress4401/frida-repro

  1. Clone this repro
  2. npm install
  3. node build.js <-- this will create a file.js made from device.ts
  4. Copy the contents of file.js into https://www.base64encode.org/ and copy the output
  5. Open agent.ts and replace the const c = ... with your new base64 string
  6. node build.js -agent <-- this will build file.js with the contents of agent.ts instead

I use https://beatstar.en.uptodown.com/android/download as a test. I think this should work for any game that uses Il2CPP though.

  1. Start the game with frida -U -f ... -l file.js (If you're using the beatstar APK then frida -U -f com.spaceapegames.beatstar -l file.js)
  2. Observe the CLI log
[SM G781W::Gadget ]-> Error: java.lang.NoSuchFieldError: no "Ljava/lang/String;" field "path" in class "Ljava/io/File;" or its superclasses
    at <anonymous> (C:\Users\megam\Desktop\repo\file.js:5603)
    at value (C:\Users\megam\Desktop\repo\file.js:16081)
    at m (C:\Users\megam\Desktop\repo\file.js:14522)
    at apply (native)
    at value (C:\Users\megam\Desktop\repo\file.js:15932)
    at m (C:\Users\megam\Desktop\repo\file.js:14469)
    at <anonymous> (C:\Users\megam\Desktop\repo\file.js:16813)
    at <anonymous> (C:\Users\megam\Desktop\repo\file.js:3017)
    at call (native)
    at <anonymous> (C:\Users\megam\Desktop\repo\file.js:2552)
  • You don't actually have to use -f you can start an application and just supply the name of the process as well and it doesn't make a different apparently.

@AeonLucid

Copy link
Copy Markdown
Contributor Author

@ExternalAddress4401 Thanks! I forgot to ask but which device and android version is this on? Any special roms?

If possible you can also message me on discord or telegram (both are @AeonLucid).

@ExternalAddress4401

Copy link
Copy Markdown

@ExternalAddress4401 Thanks! I forgot to ask but which device and android version is this on? Any special roms?

If possible you can also message me on discord or telegram (both are @AeonLucid).

Nope this is a stock ROM and a Samsung Galaxy S20 Canadian variant so it's a locker bootloader and cannot be rooted or anything of that kind.

@AeonLucid

AeonLucid commented Jul 24, 2025

Copy link
Copy Markdown
Contributor Author

@ExternalAddress4401 Thanks! I forgot to ask but which device and android version is this on? Any special roms?
If possible you can also message me on discord or telegram (both are @AeonLucid).

Nope this is a stock ROM and a Samsung Galaxy S20 Canadian variant so it's a locker bootloader and cannot be rooted or anything of that kind.

Thanks for the repro repository. I managed to fix it.

[A015::com.spaceapegames.beatstar ]-> [repro] doing
[repro] inside
[repro] doing
[repro] inside
[A015::com.spaceapegames.beatstar ]-> [repro] got code
[repro] (() => {
 
[repro] hello from eval
[repro] eval

Edit: #362

@AeonLucid AeonLucid deleted the fix/art-class-spec-stable branch July 24, 2025 07:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants