Search code examples
javascriptfrida

Calling an API to modify an App's GUI from non-Main thread in Frida


I'm just starting using Frida and have been through fundamental tutorials for code injection and hooking using JavaScript and the python bindings. My current problem is in determining how to call a GUI update method from the non-Main thread. Appreciate it's not possible to do and searching I have found code in java that would schedule a task on the Main thread. What I don't know is how to represent this code in JavaScript i.e. how do you represent the following java code in Frida JavaScript (in the injection code):

   android_View.getActivity().runOnUiThread(new Runnable() 
   {
      @Override
      public void run() 
      {
          android_View.setVisibility(View.VISIBLE);
      }
    }

Thank you


Solution

  • Adding the answer following Robert's comment above - thanks that helped a lot.

    // Assign the javascript code to a variable.
    jsCode = """
    // Create a method called Cheese that will be exported.
    function Cheese()
    {
        // Perform the code from injected context.
        Java.perform(function ()
        {
            // Variable to store the view representing the button 
            // to click programmatically.
            var view;
            // Define the Runnable type javascript wrapper.
            var Runnable = Java.use("java.lang.Runnable");
    
            // Find the MainActivity class in myApp.
            Java.choose("com.example.myApp.MainActivity", 
            {
                // Once it has been found execute the following code.
                onMatch:    function(instance)
                            {
                                // Get the view representing button to click.
                                // 2131436712 id derived from decompiling app.
                                view = instance.findViewById(2131436712);
                                // Define a new class that implements Runnable and provide
                                // the implementation of the run() method which, will 
                                // execute from the Main thread.
                                const MyRunnable = Java.registerClass({
                                                               name:'com.example.MyRunnable',
                                                               implements: [Runnable],
                                                               methods: {
                                                                // run executes button click.            
                                                                run(){
                                                                      instance.onClick(view);
                                                                     },
                                                               }
                                                          });
    
                                // Create an instance of the class just created.
                                var MyGuiUpdate = MyRunnable .$new();
                                // Schedule the run method in MyGuiUpdate to 
                                // execute on the UI thread.
                                instance.runOnUiThread(MyGuiUpdate );
    
                            },
                onComplete:function(){}
            });
        });
    }
    // Export Cheese function to python with name fromage
    rpc.exports = {
                       fromage:Cheese
                  };
    """
    

    Using the above you can call fromage from python and it will issue a click event to the button defined. The call is made from a non-UI thread and scheduled onto the UI thread using runOnUiThread.