[安全] Frida Labs 0x5

反编译

public class MainActivity extends AppCompatActivity {
 
    /* JADX INFO: renamed from: t1 */
    TextView f103t1;
 
    @Override // androidx.fragment.app.FragmentActivity, androidx.activity.ComponentActivity, androidx.core.app.ComponentActivity, android.app.Activity
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(C0535R.layout.activity_main);
        this.f103t1 = (TextView) findViewById(C0535R.id.textview);
    }
 
    public void flag(int code) {
        if (code == 1337) {
            try {
                SecretKeySpec secretKeySpec = new SecretKeySpec("WILLIWOMNKESAWEL".getBytes(), "AES");
                Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
                IvParameterSpec iv = new IvParameterSpec(new byte[16]);
                cipher.init(2, secretKeySpec, iv);
                byte[] decodedEnc = Base64.getDecoder().decode("2Y2YINP9PtJCS/7oq189VzFynmpG8swQDmH4IC9wKAY=");
                byte[] decryptedBytes = cipher.doFinal(decodedEnc);
                String decryptedText = new String(decryptedBytes);
                this.f103t1.setText(decryptedText);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

我们需要调用 MainActivity.flag(1337)

我的想法是 hook onCreate 然后接着执行 flag, 这也是利用之前的知识可以想到的办法

import Java from "frida-java-bridge";
 
if (Java.available) {
    Java.perform(() => {
        const MainActivity = Java.use("com.ad2001.frida0x5.MainActivity");
        MainActivity.onCreate.overload("android.os.Bundle").implementation = 
        function (savedInstanceState: any) {
            this.onCreate(savedInstanceState);
            this.flag(1337);
        };
    });
} else {
    console.log("No Java VM in this process");
}

frida -U -f com.ad2001.frida0x5 -l _agent.js

Frida Labs 的 官方 solution 提供了另外的解法, 它的思路承接自 0x4, 打算实例化 MainActivity 并调用其方法 flag
会出错, 原文翻译如下:

直接使用 Frida 创建 MainActivity 或任何 Android 组件的实例可能会很棘手,因为涉及到 Android 的生命周期和线程规则。Android 组件(如 Activity 子类)依赖于应用程序上下文才能正常运行。在 Frida 中,你可能缺少必要的上下文。Android UI 组件通常需要一个具有关联 Looper 的特定线程。如果你正在处理 UI 任务,请确保你在具有活动 Looper 的主线程上。Activity 是更大的 Android 应用程序生命周期的一部分。创建 MainActivity 的实例可能需要应用程序处于特定状态,并且通过 Frida 管理整个生命周期可能并不简单。总之,为 MainActivity 创建实例并不是一个好主意。

然后介绍了 choose 方法, 可以在内存中获取类的实例

Java.performNow(function() {
    Java.choose('<Package>.<class_Name>', {
        onMatch: function(instance) {
            // TODO
        },
        onComplete: function() {}
    });
});

onMatch 是找到实例之后要对实例做什么
onComplete 是寻找结束之后要做什么

然后它给出了一个类似这样的做法, 这个做法是使用 frida attach 进程然后粘贴代码的做法

Java.perform(() => {
    Java.choose("com.ad2001.frida0x5.MainActivity", {
        onMatch: (MainActivityIns: any) => {
            console.log("MainActivity found.");
            MainActivityIns.flag(1337);
        }, 
        onComplete: () => {}, 
    });
});