安卓逆向高阶之frida hook java层

1. 初次hook Java 层函数

在这里插入图片描述

登录走else if 逻辑,hook a 方法

function hook_java() {
    Java.perform(function () {
        console.log('进入hook。。。')
        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) {
        // LoginActivity.a.implementation = function(str, str2) {
            var result = this.a(str, str2);     //调用原来的函数
            console.log("LoginActivity.a:", str, str2, result);
            return result;
        };
    

        console.log("hook_java");
    });
}


手机端随便输入用户名和密码:
在这里插入图片描述

frida

在这里插入图片描述

发现a方法的两个入参都是用户名,后面那个就是加密后的密码

可以复制一下这个密码登录,还用111做用户名:

在这里插入图片描述

成功进入第一关。

2. hook 修改函数返回值

点击第一关显示 Check Failed! 还进不了下一关,
在这里插入图片描述

跳到FridaActivity1声明:

在这里插入图片描述

我们还需要hook这里面的a方法的返回值让它恒等于那串字符串就ok了,接着往下写

function hook_java() {
    Java.perform(function () {
        console.log('进入hook。。。')
        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) {
        // LoginActivity.a.implementation = function(str, str2) {
            var result = this.a(str, str2);     //调用原来的函数
            console.log("LoginActivity.a:", str, str2, result);
            return result;
        };
        console.log('aaaaaaaa66666')

        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");
    });
}

运行后再点击成功进入第2关,

在这里插入图片描述

3. hook调用静态函数和非静态函数

进入第三关同理,需要我们跳到FridaActivity2的声明里看代码逻辑:

在这里插入图片描述

静态函数直接use class然后调用方法,非静态函数需要先choose实例然后调用。

hook代码:

function call_FridaActivity2() {
    //主动调用函数
    Java.perform(function () {
        console.log('进入hook FridaActivity2。。。')
        var FridaActivity2 = Java.use("com.example.androiddemo.Activity.FridaActivity2");
        FridaActivity2.setStatic_bool_var();    //调用静态函数
        
		// 调用非静态函数
        Java.choose("com.example.androiddemo.Activity.FridaActivity2", {
            onMatch: function (instance) {
                instance.setBool_var();
            },
            onComplete: function () {

            }
        });
        console.log('hook FridaActivity2结束')
    });
}

运行frida:

在这里插入图片描述

手机端点击一下就可以进入下一关了:

在这里插入图片描述

4. hook设置成员变量

跳转到下一关即第3关声明代码:
在这里插入图片描述

这里可以看出我们需要hook的是: static_bool_var 、bool_var和same_name_bool_var 三个成员变量。

注意:

设置成员变量的值,写法是xx.value = yy,其他方面和函数一样。

如果有一个成员变量和成员函数的名字相同,则在其前面加一个下划线

function call_FridaActivity3() {
    Java.perform(function () {
        console.log('进入hook call_FridaActivity3 ...')
        var FridaActivity3 = Java.use("com.example.androiddemo.Activity.FridaActivity3");
        FridaActivity3.static_bool_var.value = true;        //设置静态成员变量

        console.log('当前FridaActivity3.static_bool_var的值:',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('当前same_name_bool_var的值:', instance._same_name_bool_var.value);
                console.log('当前bool_var的值:',instance.bool_var.value);
            },
            onComplete: function () {

            }
        });
        console.log('hook call_FridaActivity3完成')
    });
}

运行frida:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cV6ouLCT-1679480288662)(npm install frida.assets/image-20230322145216804.png)]

手机再点击就可以进入第四关了:

在这里插入图片描述

5. hook内部类

跳转到第四关的声明:

在这里插入图片描述

这里需要hook内部类的check1() - check6()

hook代码:

function hook_InnerClasses() {
    Java.perform(function () {
        console.log('hook进入 hook_InnerClasses')
        //hook内部类
        var InnerClasses = Java.use("com.example.androiddemo.Activity.FridaActivity4$InnerClasses");
        console.log('innerClasses',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;
        };
        console.log('hook_InnerClasses完成')
    });
}

或者枚举

function hook_mul_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;
            }

        }

    });
}

运行后成功hook,手机就可点击进入下一关:

在这里插入图片描述

6. hook 动态加载dex

跳转到第5关的声明:

在这里插入图片描述

想通过就走else if 逻辑,getDynamicDexCheck().check() 这个是动态加载dex ,调用check()方法,返回参数满足条件语句则通关成功。

可以通过enumerateClassLoaders来枚举加载进内存的classloader,再loader.findClass(xxx)寻找是否包括我们想要的interface的实现类,最后通过Java.classFactory.loader = loader来切换classloader,从而加载该实现类。

hook代码:

function hook_dyn_dex() {
    Java.perform(function () {
        console.log('hook进入 FridaActivity5...')
        var FridaActivity5 = Java.use("com.example.androiddemo.Activity.FridaActivity5");
        Java.choose("com.example.androiddemo.Activity.FridaActivity5", {
            onMatch: function (instance) {
                console.log('instance.getDynamicDexCheck().$className-->',instance.getDynamicDexCheck().$className);
            }, onComplete: function () {

            }
        });


        //hook 动态加载的dex
        Java.enumerateClassLoaders({
            onMatch: function (loader) {
                try {
                    if (loader.findClass("com.example.androiddemo.Dynamic.DynamicCheck")) {
                        console.log('loader-->',loader);
                        Java.classFactory.loader = loader;      //切换classloader
                    }
                } catch (error) {

                }

            }, onComplete: function () {

            }
        });

        var DynamicCheck = Java.use("com.example.androiddemo.Dynamic.DynamicCheck");
        console.log('DynamicCheck--->',DynamicCheck);
        DynamicCheck.check.implementation = function () {
            console.log("进入DynamicCheck.check");
            return true;
        }
        console.log("hook dex完成");
    });
}

在这里插入图片描述

接着点击就可以进入下一关了:

在这里插入图片描述

7. 枚举class

跳转到第6关的声明:

在这里插入图片描述

Frida6Class0、Frida6Class1、Frida6Class2都是下面这种形式
在这里插入图片描述

可以挨个hook静态函数

function hook_FridaActivity6() {
    Java.perform(function () {
        console.log('进入hook_FridaActivity6')
        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;
        };
        console.log('hook_FridaActivity6 完成!')
    });
}

或者枚举class

function hook_mul_class() {
    Java.perform(function () {
        console.log('hook 进入枚举类')
        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 () {

            }
        })
        console.log('hook6 完成!')
    });
}

在这里插入图片描述

之后再点击就可以进入下一关了:

在这里插入图片描述

到第7关结束。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰履踏青云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值