[安全] Frida Labs 0x7
先讲一下 Frida 中一个类的引用的 $init 和 $new 的关联与不同
$init 是对应 Java 类的构造函数, 返回 void
$new 对应了 Java 中的 new 操作, 负责 alloc 一块内存空间并对其调用 $init 方法
也就是说 通常 new 一个对象的实际调用如下
$new分配内存$new调用$init初始化这块内存$new返回对象
由于 $new 这里是我们 frida 这里的 new, 不对应着 Java 层里的函数, 因此不能 hook, 只能把它当成一个返回对象的操作
而 $init 是构造函数, 不需要返回值
使用 $new 的时候传递的参数要和 $init 的参数符合
反编译
public class Checker {
int num1;
int num2;
Checker(int a, int b) {
this.num1 = a;
this.num2 = b;
}
}
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);
Checker ch = new Checker(123, 321);
try {
flag(ch);
} catch (InvalidKeyException e) {
throw new RuntimeException(e);
} catch (NoSuchAlgorithmException e2) {
throw new RuntimeException(e2);
} catch (BadPaddingException e3) {
throw new RuntimeException(e3);
} catch (IllegalBlockSizeException e4) {
throw new RuntimeException(e4);
} catch (NoSuchPaddingException e5) {
throw new RuntimeException(e5);
}
}
public void flag(Checker A) throws BadPaddingException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, InvalidKeyException {
if (A.num1 > 512 && 512 < A.num2) {
Cipher cipher = Cipher.getInstance("AES");
SecretKeySpec secretKeySpec = new SecretKeySpec("MySecureKey12345".getBytes(), "AES");
cipher.init(2, secretKeySpec);
byte[] decryptedBytes = Base64.getDecoder().decode("cL/bBqDmfO0IXXJCVFwYLeHp1k3mQr+SP6rlQGUPZTY=");
String decrypted = new String(cipher.doFinal(decryptedBytes));
this.f103t1.setText(decrypted);
}
}
}根据之前学过的做法, 可以想到 hook onCreate() 在其之后再调用一个传入构造参数大于 512 的 Checker 的 flag 方法
import Java from "frida-java-bridge";
if (Java.available) {
Java.perform(() => {
const MainActivity = Java.use("com.ad2001.frida0x7.MainActivity");
const Checker = Java.use("com.ad2001.frida0x7.Checker");
const checker = Checker.$new(514, 514);
MainActivity.onCreate.overload("android.os.Bundle").implementation =
function (savedInstanceState: any) {
this.onCreate(savedInstanceState);
this.flag(checker);
};
});
} else {
console.log("No Java VM in this process");
}当然, 也有另外一种做法, 我们可以 hook Checker 类的构造函数, 让其在 onCreate 时第一次调用 flag 时候构造出来的对象就能通过判断条件
那也就是 hook $init 函数
import Java from "frida-java-bridge";
if (Java.available) {
Java.perform(() => {
const Checker = Java.use("com.ad2001.frida0x7.Checker");
Checker.$init.overload("int", "int").implementation =
function (a: number, b: number) {
this.$init(a + 512, b + 512);
};
});
} else {
console.log("No Java VM in this process");
}以上的脚本均通过 frida -U -f com.ad2001.frida0x7 -l _agent.js 运行