zoukankan      html  css  js  c++  java
  • 从三道题目入门frida

    偶然从看雪看到了一篇入门frida的题目,正好苦于没练手的东西,直接上手一波

    1.第一题jadx打开,也没有壳和混淆,整体非常清晰,判断的逻辑也很简单

    发现其实就是两个输入框,一个用户名一个密码,先拼接起来然后传入VVVVV.VVVV()方法中去校验,跟进去看一手

     其实代码逻辑还是挺清晰的,手逆也不难,但是这里主要还是用hook来做,这里破解是非常容易的,直接hook VVVV()方法的返回值直接返回为true

    ,这样不管输入什么都只会通过,但是这边的话,我们还是选择要得到flag,所以选择在frida中进行爆破,求解,因为在方法中也可以调用原方法,而且

    字符串的位数只有5位,爆破还是挺容易的,不过要注意的地方就是js的字符串和java的不太一样,所以我们需要通过hook java.lang.String类,然后

    去实现java的字符串对象,进而调用原方法

    function main()
    {
        Java.perform(function(){
            var string_class=Java.use("java.lang.String");
            Java.use("com.kanxue.pediy1.VVVVV").VVVV.implementation=function(t,y)
            {
                for(var i=0;i<=9;i++)
                {
                    for(var j=0;j<=9;j++)
                    {
                        for(var k=0;k<=9;k++)
                        {
                            for(var w=0;w<=9;w++){
                                for(var x=0;x<=9;x++)
                                {
                                    var res=string_class.$new(i.toString()+j.toString()+k.toString()+w.toString()+x.toString());
                                    if(this.VVVV(t,res))
                                    {
                                        console.log("right answer:",res);
                                        return true;
                                    }else
                                    {
                                        console.log("wrong answer:",res);
                                    }
                                }
                            }
                        }
                    }
                }
    
            }
        })
    }
    setImmediate(main);

    frida -U --no-pause -f 包名 -l 注入的js。启动就等着结果出来就好了

    第二题走起:

    第二题有点热修复的意思,就是调用文件夹中dex中类的方法,

     其实就是自定义了个classloader,只要hook就完事了,然后和第一题校验逻辑是一样的,爆破就好了

    function main()
    {
        Java.perform(function(){
            console.log("YenKoc");
            Java.enumerateClassLoaders({
                onMatch:function(loader){
                    try{
                        if(loader.findClass("com.kanxue.pediy1.VVVVV"))
                        //if(loader.toString().indexOf('dalvik.system.DexClassLoader')>-1)
                        {
                            console.log("find right classloader");
                            console.log(loader);
                            Java.classFactory.loader=loader;
                            hookVVVV();
                            return;
                        }
                    }catch(error)
                    {
                        console.log("find error"+error);
                    }
                },
                onComplete:function(){
                    console.log("end1");
                }
            })
    
    
    
    
        })
    }
    function hookVVVV(){
        Java.perform(function(){
            console.log('loader',Java.classFactory.loader);
     
     
                for (var i = 0; i <= 9; i++) {
     
                    for (var j = 0; j <= 9; j++) {
                        for (var k = 0; k <= 9; k++) {
                            for (var t = 0; t <= 9; t++) {
                                for (var y = 0; y <= 9; y++) {
                                        var newInput = Java.use('java.lang.String').$new(i.toString()
                                        + j.toString()
                                        + k.toString()
                                        + t.toString()
                                        + y.toString())
                                        //console.log(newInput)
                                        console.log("tmp:",newInput);
                                        var result = Java.use('com.kanxue.pediy1.VVVVV').VVVV(newInput)
                                        if(result == true){
                                            console.log('flag is ',newInput)
                                            return;
                                        }
                                    }
                                }
                            }
                        }
                    }  
     
        })
    }
    setImmediate(main);
    //setTimeout(main,2000);

    有几点坑的地方,第一个就是这个apk是测试用的apk,所以直接adb install是装不了的,我百度了下,修改androidmainfest.xml文件

    把android:testOnly = "true"这个东西删了,二次重打包下,结果还是不行,我丢,然后我又重新adb install -t apk名字,可以安装了

    这是安装测试apk的命令,然后就是这题frida -U --no-pause 包名 -l hook注入的js名字,不要在包名加-f了,加-f是spawn,开始就自启动

    这样会导致找不到classloader的,所以我们要attach上去,之后才能找到。

    第三题:

    和第二题相比就是加了检测frida的方法,init()是native方法,我们用ida打开发现是动态注册,先去找一手jni_onload因为动态注册肯定

    先调用这个方法的,

     动态注册的话,其实本质就是换了个名字,之前静态注册的话,特征太明显了,java_包名_类名_native方法,所以出现了

    动态注册,利用jninativeMethod这个结构体来存储native方法和本地函数的关联

    //JNINativeMethod结构体
    typedef struct {
        const char* name;       //Java中native方法的名字
        const char* signature;  //Java中native方法的描述符
        void*       fnPtr;      //对应JNI函数的指针
    } JNINativeMethod;
    
    /**
     * @param clazz java类名,通过 FindClass 获取
     * @param methods JNINativeMethod 结构体指针
     * @param nMethods 方法个数
     */
    jint RegisterNatives(jclass clazz, const JNINativeMethod* methods, jint nMethods)
    
    //JNI_OnLoad 
    JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved);

    这个就说的很清晰了。就不多bb了,

    说明真正的native方法对应的本地函数是init,我们跟进去一下

     

     发现就是新建了一个线程,检测frida是否占用了端口

    这里处理方式

    1.第一种是重打包,直接不调用init()这个方法了,这个androidkiller的话,很简单的,就不多bb了

    2.直接hook native 方法

    function hook_pthread_create(){
        var pt_create_func = Module.findExportByName(null,'pthread_create');
        var detect_frida_loop_addr = null;
        console.log('pt_create_func:',pt_create_func);
     
       Interceptor.attach(pt_create_func,{
           onEnter:function(){
               if(detect_frida_loop_addr == null)
               {
                    var base_addr = Module.getBaseAddress('libnative-lib.so');
                    if(base_addr != null){
                        detect_frida_loop_addr = base_addr.add(0xe9c)
                        console.log('this.context.x2: ', detect_frida_loop_addr , this.context.x2);
                        if(this.context.x2.compare(detect_frida_loop_addr) == 0) {
                            hook_anti_frida_replace(this.context.x2);
                        }
                    }
     
               }
     
           },
           onLeave : function(retval){
               // console.log('retval',retval);
           }
       })
    }
    function hook_anti_frida_replace(addr){
        console.log('replace anti_addr :',addr);
        Interceptor.replace(addr,new NativeCallback(function(a1){
            console.log('replace success');
            return;
        },'pointer',[]));
     
    }

    这里hook native的手法,我还不太熟悉,直接搬肉丝表哥的代码的233,晚上研究一手

    3.还有就是修改硬编码so,直接就是patch,爆破那种思路,各位大佬也是有手就行

  • 相关阅读:
    《洛谷P2296 寻找道路》
    《浙江科技学院第17届大学生程序设计竞赛:D:合并序列》
    《数论整理二》
    《洛谷P1282 多米诺骨牌》
    《洛谷P2140 小Z的电力管制》
    《洛谷P2798 爆弹虐场》
    Linux下运行C语言程序
    计算圆柱的底面积和体积
    将摄氏温度转化为华氏温度
    如果今天是星期二,那么100天后是星期几?
  • 原文地址:https://www.cnblogs.com/YenKoc/p/13857610.html
Copyright © 2011-2022 走看看