[安全] Frida Labs 0x3

反编译之后的源代码

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(C0536R.layout.activity_main);
        Button btn = (Button) findViewById(C0536R.id.button);
        this.f103t1 = (TextView) findViewById(C0536R.id.textView);
        btn.setOnClickListener(new View.OnClickListener() { // from class: com.ad2001.frida0x3.MainActivity.1
            @Override // android.view.View.OnClickListener
            public void onClick(View v) {
                if (Checker.code == 512) {
                    // 解密流程 ...
                }
                Toast.makeText(MainActivity.this.getApplicationContext(), "TRY AGAIN", 1).show();
            }
        });
    }
}
 
public class Checker {
    static int code = 0;
 
    public static void increase() {
        code += 2;
    }
}

由此可见解密依靠的是 Checker.code == 512 这个条件, 于是我们有两个思路

  1. hook code, 直接修改其值为 512
  2. 调用 increase(), 使其运行 256 次

hook 一个静态变量的模板是这样的

Java.perform(function () {
    var <class_reference> = Java.use("<package_name>.<class>");
    <class_reference>.<variable>.value = <value>;
})
import Java from "frida-java-bridge";
 
if (Java.available) {
    Java.perform(() => {
        const checker = Java.use("com.ad2001.frida0x3.Checker");
        checker.code.value = 512;
        // for (let i = 0; i < 256; ++i) {
        //     checker.increase();
        //     console.log(`increase ${i} times`);
        // }
        console.log(checker.code);
        console.log("finish");
    });
} else {
    console.log("No Java VM in this process");
}

checker.code 打印出来大概是这个样子的, 所以也能理解它为什么是修改 value

Java.Field{holder: <class: com.ad2001.frida0x3.Checker>, fieldType: 1, fieldReturnType: I, value: 512}