从 Frida 的非主线程调用 API 来修改应用程序的 GUI

Posted

技术标签:

【中文标题】从 Frida 的非主线程调用 API 来修改应用程序的 GUI【英文标题】:Calling an API to modify an App's GUI from non-Main thread in Frida 【发布时间】:2021-01-19 11:27:09 【问题描述】:

我刚刚开始使用 Frida,并且已经学习了使用 javascript 和 python 绑定进行代码注入和挂钩的基本教程。我当前的问题是确定如何从非主线程调用 GUI 更新方法。感谢这是不可能的,搜索我发现代码 in java 可以在主线程上安排任务。我不知道的是如何在 JavaScript 中表示这段代码,即如何在 Frida JavaScript 中表示以下 java 代码(在注入代码中):

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

谢谢

【问题讨论】:

第一步是反编译应用程序,例如在 Jadx 中获取匿名内部类的类名(Runner 实现)。 嘿罗伯特,所以我有所有这些信息,我认为更多的是理解要翻译的语法以创建一个新的 Runnable 实例,即使用类似的东西: Runnable = Java.use("java.lang.Runnable" );这将为您提供界面,但是,鉴于您需要设置一个公共运行方法,您如何在 JavaScript 中实际实例化。 不,您看到的课程不是java.lang.Runnable。该类实现了这个类,但是是它所在类的匿名内部类。看反编译代码。 是的,所以发现这很容易(MainActivity$1),但是,我仍在尝试从非主线程执行 GUI 更改代码段。这意味着(尽管对其他建议持开放态度)生成一个用于 runonUiThread 调用的 Run 方法实现,但是在 JavaScript 中执行此操作的命名法似乎具有挑战性。我明白你在说什么 MainActivity$1 确实实现了 Runnable 但我不明白你是如何从这种立场转变为让非主线程在主线程上安排 GUI 更新的。感谢罗伯特的评论。 好的,您想生成一个包含自定义代码的新 Java.lang.Runnable 实现。见弗里达Java.registerClass(..)frida.re/docs/javascript-api/#java-registerclass 【参考方案1】:

在上面罗伯特的评论之后添加答案 - 非常感谢。

// 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
              ;
"""

使用上述方法,您可以从 python 调用 fromage,它会向定义的按钮发出单击事件。调用从非 UI 线程进行,并使用 runOnUiThread 调度到 UI 线程。

【讨论】:

以上是关于从 Frida 的非主线程调用 API 来修改应用程序的 GUI的主要内容,如果未能解决你的问题,请参考以下文章

Frida从入门到入门—安卓逆向菜鸟的frida食用说明

在 SQL Server 中的非主键上添加 @ManyToOne 映射时出现问题

CoreAnimation:[EAGLContext renderbufferStorage:fromDrawable:] 是从非主线程调用的

有没有办法使用 Frida 或任何其他工具通过您自己的参数调用 IOS 应用程序中的方法?

为何invalidate()不可以直接在UI线程中调用

Django中的非主外键