工具 :Jadx AndroidKiller frida
熟练使用jadx ,Androidkiller frida,了解android逆向流程分析,熟悉Smali汇编以及Frida脚本编写,通过Jadx 流程分析android 中逻辑代码。AndroidKiller修改Smali汇编方式修改执行流程重新打包绕过某些逻辑条件判断,frida hook在逆向中占有重要地位,熟练掌握?frida hook基础知识是逆向必不可少的内容。
一、loginActivity
流程分析
解题
方法一:逻辑算法计算获取密码
通过逻辑算法输入用户名计算出返回的字符串即为密码。
public class Main {
? ?public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException {
? ? ? ?String inputs1="PwnGuo";
? ? ? String str =a(inputs1,inputs1);
?
? ? ? System.out.println("log:"+str);
? }
? ?public static String a(String str, String str2) throws InvalidKeyException, NoSuchAlgorithmException {
?
? ? ? ? ? ?SecretKeySpec secretKeySpec = new SecretKeySpec(str2.getBytes(), "HmacSHA256");
? ? ? ? ? ?Mac instance = Mac.getInstance("HmacSHA256");
? ? ? ? ? ?instance.init(secretKeySpec);
?
? ? ? ? ? ?return a(instance.doFinal(str.getBytes())) ;
? }
? ?private static String a(byte[] bArr) {
? ? ? ?StringBuilder sb = new StringBuilder();
? ? ? ?int i = 0;
? ? ? ?while (bArr != null && i < bArr.length) {
? ? ? ? ? ?String hexString = Integer.toHexString(bArr[i] & 255);
? ? ? ? ? ?if (hexString.length() == 1) {
? ? ? ? ? ? ? ?sb.append('0');
? ? ? ? ? }
? ? ? ? ? ?sb.append(hexString);
? ? ? ? ? ?i++;
? ? ? }
? ? ? ?return sb.toString().toLowerCase();
? }
}
//log:12638599104995570fcae7895cc54a57e485d9818887ba6762c5abaaebe670dc
方法二:Smali 汇编修改绕过
1.AndroidKiller 直接硬编码修改成功跳过
2.AndroidKiller插桩方式输出计算后的密码成功完成
? 用户名 :123456 密码:b8ad08a3a547e35829b821b75370301dd8c4b06bdd7771f9b541a75914068718
方法三:hook Java 层函数
通过hook a方法的返回参数获得密码
function hook_java() {
? ?Java.perform(function () {
? ? ? ?var LoginActivity = Java.use("com.example.androiddemo.Activity.LoginActivity");
? ? ? ?console.log(LoginActivity);
? ? ? ?LoginActivity.a.overload('java.lang.String', 'java.lang.String').implementation = function (str, str2) {
? ? ? ? ? ?var result = this.a(str, str2); ? ? //调用原来的函数
? ? ? ? ? ?console.log("LoginActivity.a:", str, str2, result);
? ? ? ? ? ?return result;
? ? ? };
?
? ? ? ?var FridaActivity1 = Java.use("com.example.androiddemo.Activity.FridaActivity1");
? ? ? ?console.log(FridaActivity1);
?
? ? ? ?//hook函数,没有调用原来的函数,直接返回值
? ? ? ?FridaActivity1.a.implementation = function (barr) {
? ? ? ? ? ?console.log("FridaActivity1.a");
? ? ? ? ? ?return "R4jSLLLLLLLLLLOrLE7/5B+Z6fsl65yj6BgC6YWz66gO6g2t65Pk6a+P65NK44NNROl0wNOLLLL=";
? ? ? };
?
? ? ? ?console.log("hook_java");
? });
}
二、FridaActivity1
流程分析
解题
方法一: Smali 汇编修改
直接修改onCheck()方法中返回值
?
或者修改a(byte[] bArr)方法中返回值。
方法二:hook Java 层函数
修改函数返回值或参数
function hook_java() {
? ?Java.perform(function () {
? ? ? ?var FridaActivity1 = Java.use("com.example.androiddemo.Activity.FridaActivity1");
? ? ? ?console.log(FridaActivity1);
? ? ? ?//hook函数,没有调用原来的函数,直接返回值
? ? ? ?FridaActivity1.a.implementation = function (barr) {
? ? ? ? ? ?console.log("FridaActivity1.a");
? ? ? ? ? ?return "R4jSLLLLLLLLLLOrLE7/5B+Z6fsl65yj6BgC6YWz66gO6g2t65Pk6a+P65NK44NNROl0wNOLLLL=";
? ? ? };
?
? ? ? ?console.log("hook_java");
? });
}
三、FridaActivity2
流程分析
解题
通过分析 static_bool_var bool_var参数为true时第二关通关成功,修改参数或调用setStatic_bool_var()/setBool_var()方法即可
方法一:修改跳转语句
方法二:直接调用方法
?方法三:hook Java 层函数
调用静态函数和调用非静态函数
function call_FridaActivity2() {
? ?//主动调用函数
? ?Java.perform(function () {
? ? ? ?var FridaActivity2 = Java.use("com.example.androiddemo.Activity.FridaActivity2");
? ? ? ?//调用静态函数
? ? ? ?FridaActivity2.setStatic_bool_var(); ? ?
? ? ? ?//Java.choose 非静态函数调用
? ? ? ?Java.choose("com.example.androiddemo.Activity.FridaActivity2", {
? ? ? ? ? ?onMatch: function (instance) {
? ? ? ? ? ? ? ?instance.setBool_var();
? ? ? ? ? },
? ? ? ? ? ?onComplete: function () {
?
? ? ? ? ? }
? ? ? });
? });
}
四、FridaActivity3
流程分析
静态/非静态成员变量通过满足if语句使通关成功
在Smali汇编中静态成员变量与非静态成员变量区别
?
解题
方法一:修改成员变量boolan值
方法二:设置成员变量
设置静态成员变量,非静态成员变量和函数名相同的成员变量
function call_FridaActivity3() {
? ?Java.perform(function () {
? ? ? ?var FridaActivity3 = Java.use("com.example.androiddemo.Activity.FridaActivity3");
? ? ? ?//设置静态成员变量
? ? ? ?FridaActivity3.static_bool_var.value = true; ? ? ?
? ? ? ?console.log(FridaActivity3.static_bool_var.value);
? ? ? ?Java.choose("com.example.androiddemo.Activity.FridaActivity3", {
? ? ? ? ? ?onMatch: function (instance) {
? ? ? ? ? ? ? ?//设置非静态成员变量的值
? ? ? ? ? ? ? ?instance.bool_var.value = true;
? ? ? ? ? ? ? ?//设置有相同函数名的成员变量的值
? ? ? ? ? ? ? ?instance._same_name_bool_var.value = true;
? ? ? ? ? ? ? ?console.log(instance.bool_var.value, instance._same_name_bool_var.value);
? ? ? ? ? },
? ? ? ? ? ?onComplete: function () {
? ? ? ? ? }
? ? ? });
? });
}
五、FridaActivity4
流程分析
解题
方法一:Smali修改返回值
方法二:hook 内部类
//方式一
function hook_InnerClasses() {
? ?Java.perform(function () {
? ? ? ?
? ? ? ?var InnerClasses = Java.use("com.example.androiddemo.Activity.FridaActivity4$InnerClasses");
? ? ? ?console.log(InnerClasses);
? ? ? ?InnerClasses.check1.implementation = function () {
? ? ? ? ? ?return true;
? ? ? };
? ? ? ?InnerClasses.check2.implementation = function () {
? ? ? ? ? ?return true;
? ? ? };
? ? ? ?InnerClasses.check3.implementation = function () {
? ? ? ? ? ?return true;
? ? ? };
? ? ? ?InnerClasses.check4.implementation = function () {
? ? ? ? ? ?return true;
? ? ? };
? ? ? ?InnerClasses.check5.implementation = function () {
? ? ? ? ? ?return true;
? ? ? };
? ? ? ?InnerClasses.check6.implementation = function () {
? ? ? ? ? ?return true;
? ? ? };
? });
}
//方式二
//枚举类的函数
function hook_enum_function() {
? ?Java.perform(function () {
? ? ? ?//hook 类的多个函数
? ? ? ?var class_name = "com.example.androiddemo.Activity.FridaActivity4$InnerClasses";
? ? ? ?var InnerClasses = Java.use(class_name);
? ? ? ?var all_methods = InnerClasses.class.getDeclaredMethods();
? ? ? ?for (var i = 0; i < all_methods.length; i++) {
? ? ? ? ? ?var method = (all_methods[i]);
? ? ? ? ? ?var methodStr = method.toString();
? ? ? ? ? ?var substring = methodStr.substr(methodStr.indexOf(class_name) + class_name.length + 1);
? ? ? ? ? ?var methodname = substring.substr(0, substring.indexOf("("));
? ? ? ? ? ?console.log(methodname);
? ? ? ? ? ?InnerClasses[methodname].implementation = function () {
? ? ? ? ? ? ? ?console.log("hook_mul_function:", this);
? ? ? ? ? ? ? ?return true;
? ? ? ? ? }
? ? ? }
? });
}
六、FridaActivity5
流程分析
动态加载dex ,调用check()方法,返回参数满足条件语句通关成功。
解题
方法一:Smali修改条件语句
getDynamicDexCheck()接口调用判断成立,只需修改check()方法满足条件。
方法二:hook动态加载的Dex
function hook_dyn_dex() {
? ?Java.perform(function () {
? ? ? ?var FridaActivity5 = Java.use("com.example.androiddemo.Activity.FridaActivity5");
? ? ? ?Java.choose("com.example.androiddemo.Activity.FridaActivity5", {
? ? ? ? ? ?onMatch: function (instance) {
? ? ? ? ? ? ? ?console.log(instance.getDynamicDexCheck().$className);
? ? ? ? ? }, onComplete: function () {
?
? ? ? ? ? }
? ? ? });
? ? ? ?//hook 动态加载的dex
? ? ? ?Java.enumerateClassLoaders({
? ? ? ? ? ?onMatch: function (loader) {
? ? ? ? ? ? ? ?try {
? ? ? ? ? ? ? ? ? ?if (loader.findClass("com.example.androiddemo.Dynamic.DynamicCheck")) {
? ? ? ? ? ? ? ? ? ? ? ?console.log(loader);
? ? ? ? ? ? ? ? ? ? ? ?Java.classFactory.loader = loader; ? ? ?//切换classloader
? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? } catch (error) {
?
? ? ? ? ? ? ? }
?
? ? ? ? ? }, onComplete: function () {
? ? ? ? ? }
? ? ? });
? ? ? ?var DynamicCheck = Java.use("com.example.androiddemo.Dynamic.DynamicCheck");
? ? ? ?console.log(DynamicCheck);
? ? ? ?DynamicCheck.check.implementation = function () {
? ? ? ? ? ?console.log("DynamicCheck.check");
? ? ? ? ? ?return true;
? ? ? }
? });
}
七、FridaActivity6
流程分析
解题
方法一:Smali修改条件语句
方法二:hook java类
//方式一:直接返回参数为真
function hook_FridaActivity6() {
? ?Java.perform(function () {
? ? ? ?var Frida6Class0 = Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class0");
? ? ? ?Frida6Class0.check.implementation = function () {
? ? ? ? ? ?return true;
? ? ? };
? ? ? ?var Frida6Class1 = Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class1");
? ? ? ?Frida6Class1.check.implementation = function () {
? ? ? ? ? ?return true;
? ? ? };
? ? ? ?var Frida6Class2 = Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class2");
? ? ? ?Frida6Class2.check.implementation = function () {
? ? ? ? ? ?return true;
? ? ? };
? });
}
//方式二:枚举class
function hook_enum_class() {
? ?Java.perform(function () {
? ? ? ?Java.enumerateLoadedClasses({
? ? ? ? ? ?onMatch: function (name, handle) {
? ? ? ? ? ? ? ?if (name.indexOf("com.example.androiddemo.Activity.Frida6") >= 0) {
? ? ? ? ? ? ? ? ? ?console.log(name);
? ? ? ? ? ? ? ? ? ?var fridaclass6 = Java.use(name);
? ? ? ? ? ? ? ? ? ?fridaclass6.check.implementation = function () {
? ? ? ? ? ? ? ? ? ? ? ?console.log("frida 6 check:", this);
? ? ? ? ? ? ? ? ? ? ? ?return true;
? ? ? ? ? ? ? ? ? };
? ? ? ? ? ? ? }
? ? ? ? ? }, onComplete: function () {
? ? ? ? ? }
? ? ? })
? });
}
?
|