Xposed 探索之Hook 驾考宝典

Xposed 探索之Hook 驾考宝典一、起因:最近在考驾照,钱是去年年初的时候交的。科目一到前段时间才开始,又碰上疫情。所以耐着性子看了三四遍驾考宝典。1350个题目用两个不同的驾考app各刷了一遍。总担心考不过科目一。尤其是刷了第一遍题目后总感觉还有些内容总结不够。看这个app会员功能有总结,当时还发了个朋友圈要买个会员,问别人有没有会员可以借来使使的(当然,经过大家一致的吐糟,最后迎着苦涩又刷了一遍题目)。所以,过程有点曲折,但是起因就是对这个app的vip功能情有独钟。二、契机:最近在看Xposed的事情,如果你看过之前的文章,你

本文固定链接,转载请先评论点赞

一、起因:

最近在考驾照,钱是去年年初的时候交的。科目一到前段时间才开始,又碰上疫情。所以耐着性子看了三四遍驾考宝典。1350个题目用两个不同的驾考app各刷了一遍。总担心考不过科目一。尤其是刷了第一遍题目后总感觉还有些内容总结不够。看这个app会员功能有总结,当时还发了个朋友圈要买个会员,问别人有没有会员可以借来使使的(当然,经过大家一致的吐糟,最后迎着苦涩又刷了一遍题目)。所以,过程有点曲折,但是起因就是对这个app的vip功能情有独钟。

二、契机:

最近在看Xposed的事情,如果你看过之前的文章,你会知道我为啥看这个框架。总之是折腾之后有点失落。最后决定对这个享誉盛名的app表达一下尊重。我们严肃的表示,我们在探索技术。

三、准备工作:

从他的官网下载了app。保存在桌面。安装了MuMu模拟器。用模拟器安装这个app。
备注:为什么用MuMu模拟器原因有两个:
1、模拟器开发者模式和root都已经做了。Xposed框架基础条件都有
2、在调试功能的时候要经常重启。如果用真机我担心对我的“三老婆”有损。(二老婆是车(暂时没有)三老婆是手机(宝贝着咧))

按照上一个文章所示,搭建好android studio 环境,过程请看:
Android Studio 在MuMu模拟器上实现 xposed简单劫持
工程结构如图:
在这里插入图片描述
MainActivity.java代码如下:

package com.cf.exposedpractice;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity { 
   

    @Override
    protected void onCreate(Bundle savedInstanceState) { 
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btn=(Button)findViewById(R.id.button);

        btn.setOnClickListener(new View.OnClickListener() { 
   
            @Override
            public void onClick(View v) { 
   
                showCenterContent();
            }
        });
    }

    public void showCenterContent()
    { 
   
        TextView centerText=(TextView)findViewById(R.id.centerTextView);

        centerText.setText(GetContent());
    }

    public String GetContent()
    { 
   
        return  "Xposed test";
    }
}

XposedTools.java代码如下:

package com.cf.exposedpractice;

import de.robv.android.xposed.IXposedHookLoadPackage;
import de.robv.android.xposed.XC_MethodHook;
import de.robv.android.xposed.XposedBridge;
import de.robv.android.xposed.XposedHelpers;
import de.robv.android.xposed.callbacks.XC_LoadPackage;

public class XposedTools implements IXposedHookLoadPackage { 
   
    @Override
    public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { 
   

        XposedBridge.log("Loaded app: " + lpparam.packageName);

        if(lpparam.packageName.equals("com.cf.exposedpractice"))
        { 
   
            XposedHelpers.findAndHookMethod("com.cf.exposedpractice.MainActivity", lpparam.classLoader, "GetContent", new XC_MethodHook() { 
   
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable { 
   
                    super.afterHookedMethod(param);

                    XposedBridge.log("GetContent afterHookedMethod");

                    param.setResult("hooked the function of GetContent");
                }
            });
        }

        if(lpparam.packageName.equals("com.handsgo.jiakao.android"))
        { 
   
            XposedHelpers.findAndHookMethod("cn.mucang.android.comment.api.data.UserSimpleJsonData", lpparam.classLoader, "isJiakaoVip", new XC_MethodHook() { 
   
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable { 
   
                    super.afterHookedMethod(param);

                    XposedBridge.log("afterHookedMethod");

                    Object result=param.getResult();

                    boolean v=(boolean)result;

                    XposedBridge.log("afterHookedMethod isJiakaoVip ori v:"+v);

                    param.setResult(true);

                    //打印堆栈查看调用关系
                    StackTraceElement[] wodelogs = new Throwable("wodelog").getStackTrace();

                    for (int i = 0; i < wodelogs.length; i++) { 
   
                        XposedBridge.log("查看堆栈:" + wodelogs[i].toString());
                    }

                    //获取类
                    Class<?> clazz = param.thisObject.getClass();

                    XposedBridge.log("要hook的方法所在的类:" + clazz.getName());
                }
            });

            XposedHelpers.findAndHookMethod("cn.mucang.android.comment.api.data.UserSimpleJsonData", lpparam.classLoader, "isAdmin", new XC_MethodHook() { 
   
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable { 
   
                    super.afterHookedMethod(param);

                    Object result=param.getResult();

                    boolean v=(boolean)result;

                    XposedBridge.log("afterHookedMethod isAdmin ori v:"+v);

                    param.setResult(true);
                }
            });

            XposedHelpers.findAndHookMethod("cn.mucang.android.account.data.AuthUser", lpparam.classLoader, "getExpiredTime", new XC_MethodHook() { 
   
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable { 
   
                    super.afterHookedMethod(param);

                    Object result=param.getResult();

                    Long v=(Long)result;

                    v+=999999999;

                    XposedBridge.log("afterHookedMethod isAdmin ori v:"+v);

                    param.setResult(v);

                    //打印堆栈查看调用关系
                    StackTraceElement[] wodelogs = new Throwable("wodelog").getStackTrace();

                    for (int i = 0; i < wodelogs.length; i++) { 
   
                        XposedBridge.log("查看堆栈:" + wodelogs[i].toString());
                    }

                    //获取类
                    Class<?> clazz = param.thisObject.getClass();

                    XposedBridge.log("要hook的方法所在的类:" + clazz.getName());
                }
            });

            XposedHelpers.findAndHookMethod("cn.mucang.android.account.data.AuthUser", lpparam.classLoader, "getNickname", new XC_MethodHook() { 
   
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable { 
   
                    super.afterHookedMethod(param);

                    Object result=param.getResult();

                    String v=(String)result;

                    XposedBridge.log("afterHookedMethod isAdmin ori v:"+v);

                    param.setResult("Xposed "+v);

                    //打印堆栈查看调用关系
                    StackTraceElement[] wodelogs = new Throwable("wodelog").getStackTrace();

                    for (int i = 0; i < wodelogs.length; i++) { 
   
                        XposedBridge.log("查看堆栈:" + wodelogs[i].toString());
                    }

                    //获取类
                    Class<?> clazz = param.thisObject.getClass();

                    XposedBridge.log("要hook的方法所在的类:" + clazz.getName());
                }
            });

            XposedHelpers.findAndHookMethod("com.handsgo.jiakao.android.main.manager", lpparam.classLoader, "getPracticeVideoCount", new XC_MethodHook() { 
   
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable { 
   
                    super.afterHookedMethod(param);

                    Object result=param.getResult();

                    int v=(int)result;

                    XposedBridge.log("afterHookedMethod getPracticeVideoCount ori v:"+v);

                    param.setResult(v+888);

                    //打印堆栈查看调用关系
                    StackTraceElement[] wodelogs = new Throwable("wodelog").getStackTrace();

                    for (int i = 0; i < wodelogs.length; i++) { 
   
                        XposedBridge.log("查看堆栈:" + wodelogs[i].toString());
                    }

                    //获取类
                    Class<?> clazz = param.thisObject.getClass();

                    XposedBridge.log("要hook的方法所在的类:" + clazz.getName());
                }
            });

            XposedHelpers.findAndHookMethod("com.handsgo.jiakao.android.main.manager", lpparam.classLoader, "LMa", new XC_MethodHook() { 
   
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable { 
   
                    super.afterHookedMethod(param);

                    Object result=param.getResult();

                    int v=(int)result;

                    XposedBridge.log("afterHookedMethod LMa ori v:"+v);

                    param.setResult(v+9999);

                    //打印堆栈查看调用关系
                    StackTraceElement[] wodelogs = new Throwable("wodelog").getStackTrace();

                    for (int i = 0; i < wodelogs.length; i++) { 
   
                        XposedBridge.log("查看堆栈:" + wodelogs[i].toString());
                    }

                    //获取类
                    Class<?> clazz = param.thisObject.getClass();

                    XposedBridge.log("要hook的方法所在的类:" + clazz.getName());
                }
            });
        }
    }
}

看过上面的文章你一定能发现,我这里做了个简单的按钮,点击按钮显示想要的内容。这里这一步是为了测试整个框架有没有生效。因为就我的发现是,在某些不确定的情况下,框架有可能不成功。所以需要价格按钮来确定如果框架成功了,点击按钮显示的就是:hooked the function of GetContent

否则显示的应该是Xposed test。如图:
在这里插入图片描述
另外,因为我使用的输出日志的方法是:XposedBridge.log,所以在Xposed Installler中能看到对应的日志。

四、关于app:

像这种app不可能不代码混淆。所以这个是一个蛋疼的点。我尝试用jadx这个工具反编译这个app。如图:

在这里插入图片描述
反编译的方法很简单,就是直接用工具打开桌面上apk就行。不过我感觉这个东西耗内存。反编译过程内存按照G来算的。

反编译等他执行完了之后执行如图所示反代码混淆:
在这里插入图片描述
事实上只稍微好那么一丢丢。但是比起CSDN或者百度搜索反编译反混淆都是千篇一律的那种要好一些吧。至少看到了不一样的声音。
工具我已经整体打包上传CSDN了,有需要的下载

五、想做什么?

我想看看他的vip功能是怎么做的!
所以,我在jadx上搜索vip。搜索结果显示如下:
在这里插入图片描述
我发现,在包名为:package cn.mucang.android.comment.api.data,类名是:UserSimpleJsonData的java类中,定义了一个名为:jiakaoVip的变量,如图:
在这里插入图片描述
打开这个类,能看到有一些get/set方法。
在这里插入图片描述
进一步,我搜索这个方法有哪些地方赋值了,在jadx中直接右键点击方法名,选择查找用例,如图:
在这里插入图片描述
只有一个地方用到了,如图:
在这里插入图片描述
额。。。。。感觉跟设想的不一样。用户信息中的vip属性不应该是很多地方都用的吗,看这个类的名称:CommentTitleModel,这丫丫的不是啥标题啥的?

我感觉我的思路除了点问题。

回顾一波:
首先是我想通过Xposed框架修改vip属性。所以我通过jadx搜索vip字段。但时并没有如我预想的那样。
然后我在Android Studio 的Xposedtools中对代码进行修改,发现并没有什么用。代码如图:

if(lpparam.packageName.equals("com.handsgo.jiakao.android"))
        { 
   
            XposedHelpers.findAndHookMethod("cn.mucang.android.comment.api.data.UserSimpleJsonData", lpparam.classLoader, "isJiakaoVip", new XC_MethodHook() { 
   
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable { 
   
                    super.afterHookedMethod(param);

                    XposedBridge.log("afterHookedMethod");

                    Object result=param.getResult();

                    boolean v=(boolean)result;

                    XposedBridge.log("afterHookedMethod isJiakaoVip ori v:"+v);

                    param.setResult(true);

                    //打印堆栈查看调用关系
                    StackTraceElement[] wodelogs = new Throwable("wodelog").getStackTrace();

                    for (int i = 0; i < wodelogs.length; i++) { 
   
                        XposedBridge.log("查看堆栈:" + wodelogs[i].toString());
                    }

                    //获取类
                    Class<?> clazz = param.thisObject.getClass();

                    XposedBridge.log("要hook的方法所在的类:" + clazz.getName());
                }
            });
      	}

这个地方我对包名做了限制,只有是包名为:com.handsgo.jiakao.android的应用才起作用。包名是通过jadx中的AndroidManifest.xml看到的,如图:
在这里插入图片描述
顺便贴一下他的签名信息:
在这里插入图片描述
额…矫情了。

言归正传。

既然找不到vip相关的信息,我试着找userinfo信息等关键字。如图:
在这里插入图片描述
上面红框里面那些android.support我就不看了,我看到下面有个包名下面有个AccountManager的类。我感觉这个应该就是用户信息了。
如图:
在这里插入图片描述
这个地方不是一个账号管理Manager嘛,为毛还有Activity,这是哪个程序员写的?拖出去枪毙。
管理功能里面怎么能放Activity咧。你不得通过通知之类的方法去使用啊。搞不懂。因为是反编译还带混淆功能。一时半会看不懂他的逻辑。但是我找到了一个AuthUser的类。点开看看:
在这里插入图片描述
额,看样子这就是个人信息了。但是奇怪的是,这个类中依旧没有vip相关的信息。我得思考。我有点彷徨,我有点犹豫,我有点像撞墙,我有点想去拉大便。。。。。。。

暂停十分钟。。。。。

好了,舒畅。。。。

不管他,先试试这个nickname。代码如下:

XposedHelpers.findAndHookMethod("cn.mucang.android.account.data.AuthUser", lpparam.classLoader, "getNickname", new XC_MethodHook() { 
   
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable { 
   
                    super.afterHookedMethod(param);

                    Object result=param.getResult();

                    String v=(String)result;

                    XposedBridge.log("afterHookedMethod isAdmin ori v:"+v);

                    param.setResult("Xposed "+v);

                    //打印堆栈查看调用关系
                    StackTraceElement[] wodelogs = new Throwable("wodelog").getStackTrace();

                    for (int i = 0; i < wodelogs.length; i++) { 
   
                        XposedBridge.log("查看堆栈:" + wodelogs[i].toString());
                    }

                    //获取类
                    Class<?> clazz = param.thisObject.getClass();

                    XposedBridge.log("要hook的方法所在的类:" + clazz.getName());
                }
            });

这个代码也就是说,如果有地方需要用名称的时候强项在前面加个Xposed 。试试。编译到MuMu模拟器,将ExposedPractice 添加到Xposed Installler模块中,重启模拟器。运行这个app.如图:

在这里插入图片描述
在这里插入图片描述

呵呵,这个功能算是成功了。

但我并不能满足于此,vip还是没有搞定。于是,我继续通过jadx查。

我看视频如果是新用户只能播放3个,我是不是可以修改这个数量,也不知道他们是不是再前端限制的播放次数。反正试试呗。如图:
在这里插入图片描述
这里显示一段文字:可免费观看3个视频,那我搜索“可免费观看”如图:
在这里插入图片描述

点进去,看具体代码:
在这里插入图片描述
嗯,这个LMa的变量应该是用了混淆的结果吧。反正从这个代码中看,是这个变量显示的数量。其中有个类叫:PracticeVideoManager,貌似是个管理类。如图:

在这里插入图片描述
对应的方法在:
在这里插入图片描述

看这个方法,同时发现了另外一个class,如图:
在这里插入图片描述
这里大概就是所谓3次的由来了。试着用代码Hook


            XposedHelpers.findAndHookMethod("com.handsgo.jiakao.android.main.manager.VideoCountModel", lpparam.classLoader, "getPracticeVideoCount", new XC_MethodHook() { 
   
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable { 
   
                    super.afterHookedMethod(param);

                    Object result=param.getResult();

                    int v=(int)result;

                    XposedBridge.log("afterHookedMethod getPracticeVideoCount ori v:"+v);

                    param.setResult(v+888);

                    //打印堆栈查看调用关系
                    StackTraceElement[] wodelogs = new Throwable("wodelog").getStackTrace();

                    for (int i = 0; i < wodelogs.length; i++) { 
   
                        XposedBridge.log("查看堆栈:" + wodelogs[i].toString());
                    }

                    //获取类
                    Class<?> clazz = param.thisObject.getClass();

                    XposedBridge.log("要hook的方法所在的类:" + clazz.getName());
                }
            });

            XposedHelpers.findAndHookMethod("com.handsgo.jiakao.android.main.manager.PracticeVideoManager", lpparam.classLoader, "LMa", new XC_MethodHook() { 
   
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable { 
   
                    super.afterHookedMethod(param);

                    Object result=param.getResult();

                    int v=(int)result;

                    XposedBridge.log("afterHookedMethod LMa ori v:"+v);

                    param.setResult(v+9999);

                    //打印堆栈查看调用关系
                    StackTraceElement[] wodelogs = new Throwable("wodelog").getStackTrace();

                    for (int i = 0; i < wodelogs.length; i++) { 
   
                        XposedBridge.log("查看堆栈:" + wodelogs[i].toString());
                    }

                    //获取类
                    Class<?> clazz = param.thisObject.getClass();

                    XposedBridge.log("要hook的方法所在的类:" + clazz.getName());
                }
            });

重新编译,重启MuMu,运行查看。


报错了:
在这里插入图片描述

额。没有找到这个东东。

啥原因????

额。。。。。。。。。。。我得研究一下。。。。

由于篇幅问题,暂时就到这里吧。主要原因是我还得研究研究。我都是一边研究一边写文章的。所以过程很重要。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

另外:谁有更好的反混淆工具推荐的。请一定留言告知。不胜感激。

好了,再拉屎去…

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/34085.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注