This is the AMP version of this page.
If you want to load the real page instead, click this text.

Discussion Embedding a GUI inside a Frida script

Mesidex

Platinian
Hello,

I was wondering if anyone has been successful in embedding any kind of GUI (e.g. a WebView) inside a Frida script that can directly change the values of Frida-hooked functions. I'm currently trying to come up with solutions as such a feat would tremendously reduce the time needed on the modders end and allow for more streamlined UI customization as opposed to what other solutions (like LGL Mod Menu) offer.

Patching would ideally be done via objection as its API allows for efficient patching without having to recompile APKs multiple times (unless the overlay permission has to be added in the manifest, which could be done during the compilation process of objection) -
I have also filed a request of a feature (that is very easily achievable) on their repository to add a --skip-signing argument to skip any signing steps done by objection.
 
It is possible, but a lot of boilerplate needs to be set up first just to create UI elements.
I wrote up an example that will create a button that when clicked, prints out a toast.
Note that this button uses the app's default style, so if you want a custom style, you'll have to do things like call setBackground.
If you want multiple views, it would be best to create a LinearLayout or some other layout and add views to that, then add the layout to the root view.
You should be able to apply this for a WebView, though.

JavaScript:
// We need to get an instance of the main activity.
var activity;

// If you know the activity class, you can replace android.app.Activity with it's class name
// (e.g. for MIUI calculator, you could use com.miui.calculator.cal.CalculatorActivity)
// Java.choose just iterates all objects until it finds one with a certain class (?)
Java.choose("android.app.Activity", {
    onMatch: (obj) => activity = obj,
    onComplete: () => {}
});

// Runs a function on the main thread, a.k.a. the UI thread.
// Any extra arguments passed will be passed to `func`.
function RunOnMainThread(func) {
    var args = Array.prototype.slice.call(arguments, 1);

    // We create our own runnable, then pass it to runOnUiThread.
    // source: https://stackoverflow.com/questions/65790594
    var runnable = Java.registerClass({
        name: "com.whatever.UIRunnable",
        implements: [ Java.use("java.lang.Runnable") ],
        methods: {
            run() {
                func.apply(null, args);
            }
        }
    }).$new();

    activity.runOnUiThread(runnable);
}

// We get the root view, and cast it to a ViewGroup. (https://developer.android.com/reference/android/view/ViewGroup)
// We can then call addView to add our own view.
var rootView = Java.cast(activity.getWindow().getDecorView().getRootView(), Java.use("android.view.ViewGroup"));

// We create a basic button (https://developer.android.com/reference/android/widget/Button), that when clicked, prints out a toast.
var Button = Java.use("android.widget.Button");
var btn = Button.$new(activity);

btn.setText(Java.use("java.lang.String").$new("Click me!"));
btn.setMinWidth(500);
btn.setMinHeight(250);
btn.setX(200.);
btn.setY(200.);
btn.setOnClickListener(Java.registerClass({
    name: "com.whatever.OnClickListener",
    implements: [ Java.use("android.view.View$OnClickListener") ],
    methods: {
        onClick(view) {
            // Already in main thread, so we don't need to do anything.
            Java.use("android.widget.Toast").makeText(activity, Java.use("java.lang.String").$new("You clicked!"), 5).show();
        }
    }
}).$new());

RunOnMainThread(() => {
    // We also need a LayoutParams (https://developer.android.com/reference/android/view/ViewGroup.LayoutParams) that describe how the view is layed out.
    rootView.addView(btn, Java.use("android.view.ViewGroup$LayoutParams").$new(500, 250));
});
 
Hello Vector4,

I'm glad to hear that Frida's API allows for this. I actually started implementing something of similar nature after talking to the author of frida-il2cpp-bridge, but your example made me understand the process much clearer as well as give more insight to the necessary API features.

I will also look into how I can implement a WebView. It could, perhaps, be made into a cross-platform utility as Objection can cross-compile the Frida script into both final iOS and Android binaries.

Thank you for your kind contribution and detailed comments, they will be of help to anyone looking for this topic.
 
Well WebView is a dead end, i just started coding the menu using normal ui component, and decided to use LGL style. i might also do a full implementation/copy of imgui but only if someone join me xD, it will be too much work

 
Well WebView is a dead end, i just started coding the menu using normal ui component, and decided to use LGL style. i might also do a full implementation/copy of imgui but only if someone join me xD, it will be too much work


Yeah, I went through with the route of hooking via injection since you'd skip the recompilation step entirely by only requiring the original APK to be installed (better against modded app protection) – I also felt better using QT/Dear ImGUI to handle hooking as well as the UI.

My approach, however, might require some workarounds for non-rooted devices.

There are definitely more benefits to internal mods via injection, but I don't want to make this longer than necessary lol.

 
That look good, is that on iOS ? And why using imgui for hooking? You could just use
Frida interceptor and imgui only for handling ui. Can I get your dm discord or whatever? I think we could be exchanging some great knowledge. And by the way my approach is meant to be used with Frida on termux. So you will not pull your PC everytime xD.
 

Hi,

Haha, it seems that I used some misleading wording – apologies :)

What I mean is that the frontend is built with QT QML or Dear ImGUI, whereas the backend works by hooking the functions (via a hooking lib like And64InlineHook or a custom implementation) of a target process by utilizing BroadcastReceivers and Intents / the concept of IPC.

I'll get back to you later if you want to chat on discord or telegram lol

You might have already visited frida-snippets, but there's a section for BroadcastReceivers if you'd like to check it out. You can also check this out.