本帖最后由 freestone 于 2021-03-27 14:47 编辑
本文是新手入门,大佬请忽视
最近要考试,找了一个叫星题库的软件,点开真题准备做,居然需要vip
我等穷b哪有钱买,只能开撸了,居然没加壳 1.直接点击历年真题,跳出了充值vip界面,那么点击这个的时候肯定有判断是否vip的函数调用,不是就跳出购买vip的界面 直接上monitor抓包 定位到com.xinghengedu.xingtiku.topic.viewholder.VipTopicChildrenViewHolder.a
public void mo39548a() { String str; TextView textView; int i; ImageView imageView; int total = this.f54381c.getTotal(); boolean isTopicVip = this.f54384f.getUserPermission().isTopicVip(); SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(this.f54381c.getName()); TopicRecord doTopicInfo = this.f54381c.getDoTopicInfo(); if (doTopicInfo == null) { SpannableString spannableString = new SpannableString("\n 0/" + total); spannableString.setSpan(new AbsoluteSizeSpan(12, true), 0, spannableString.length(), 33); spannableString.setSpan(new ForegroundColorSpan(super.f54387b.getResources().getColor(C9290R.color.sh_textColorGray)), 0, spannableString.length(), 33); spannableStringBuilder.append((CharSequence) spannableString); } else { SpannableString spannableString2 = new SpannableString("\n" + (doTopicInfo.getPosition() + 1) + "/" + total); spannableString2.setSpan(new AbsoluteSizeSpan(12, true), 0, spannableString2.length(), 33); spannableString2.setSpan(this.f54381c.isLastTopicRecord() ? new ForegroundColorSpan(super.f54387b.getResources().getColor(C9290R.color.sh_textColorBlue)) : new ForegroundColorSpan(super.f54387b.getResources().getColor(C9290R.color.sh_textColorGray)), 0, spannableString2.length(), 33); spannableStringBuilder.append((CharSequence) spannableString2); } this.mTvCentre.setText(spannableStringBuilder); this.mTbRight.setVisibility(0); this.mTvContinue.setVisibility(8); if (isTopicVip) { this.mTbRight.setImageResource(C9290R.C9291drawable.sh_ic_topic_donot); textView = this.mTvCentre; str = "#202020"; } else { this.mTbRight.setImageResource(C9290R.C9291drawable.sh_ic_topic_canot); textView = this.mTvCentre; str = "#7a7a7a"; } textView.setTextColor(Color.parseColor(str)); if (this.f54381c.isLastTopicRecord()) { this.mTbRight.setVisibility(8); this.mTvContinue.setVisibility(0); imageView = this.mTbLeftCenter; i = C9290R.C9291drawable.sh_circle_solid_blue; } else { this.mTbRight.setVisibility(0); this.mTvContinue.setVisibility(8); imageView = this.mTbLeftCenter; i = C9290R.C9291drawable.sh_cirle_blue_small; } imageView.setImageResource(i); if (this.f54382d) { this.mTbLeftBottom.setVisibility(4); } else { this.mTbLeftBottom.setVisibility(0); } }
isTopicVip 看到booleanisTopicVip = this.f54384f.getUserPermission().isTopicVip(),很明显,只要hook了isTopicVip一直返回true就是会员了2.我们再深追一下isTopicVip的赋值,发现是在com.xingheng.global.UserInfo里面,如果getVIPLevel=9,就是vip,level只有0和9,我们也可以在这里把初始化UserInfo的this.VIPLevel = "0"改为9 package com.xingheng.global.UserInfo; public boolean isTopicVip(){ return TextUtils.equals(this.getVIPLevel(), "9"); } public String getVIPLevel(){ return this.VIPLevel; } public void UserInfo(){ super(); this.VIPLevel = "0"; this.dedicated = 0; }
3.用frIDA hook看一下//frida -U -f com.xingheng.escollection -l F:\MY_reverse\星题库\fridaa.js Java.perform(function () { var VipTopicChildrenViewHolder = Java.use('com.xinghengedu.xingtiku.topic.viewholder.VipTopicChildrenViewHolder'); VipTopicChildrenViewHolder.a.overload().implementation=function() { this.a(); console.log('hook VipTopicChildrenViewHolder.a start'); } var UserPermissionDelegate = Java.use('com.xingheng.contract_impl.UserPermissionDelegate'); UserPermissionDelegate.isTopicVip.overload().implementation=function() { console.log('hook UserPermissionDelegate.isTopicVip start'); return true; } var UserInfo = Java.use('com.xingheng.global.UserInfo'); UserInfo.isTopicVip.overload().implementation=function() { send('hook UserInfo.isTopicVip start'); // return this.isTopicVip(); return true; } UserInfo.getVIPLevel.overload().implementation=function() { send('hook UserInfo.getVIPLevel start'); return this.isTopicVip(); console.log(this.isTopicVip()); } var NotVipTipsDialogFragment = Java.use('com.xinghengedu.xingtiku.view.NotVipTipsDialogFragment'); NotVipTipsDialogFragment.onCreateView.overload('android.view.LayoutInflater', 'android.view.ViewGroup', 'android.os.Bundle').implementation=function(a1,a2,a3) { send('hook onCreateView start'); return this.onCreateView(a1,a2,a3); // var threadef = Java.use('java.lang.Thread'); // var threadinstance = threadef.$new(); // var stack = threadinstance.currentThread().getStackTrace(); // function Where(stack){ // for(var i = 0; i < stack.length; ++i){ // console.log(stack[i].toString()); // } // } // console.log("Full call stack:" + Where(stack)); } });
4.简单分析得出结论,只要点击真题,就会调用 com.xingheng.contract_impl.UserPermissionDelegate的isTopicVip函数判断是否是vip,而UserInfo里的isTopicVip的初始化只有在第一次安装或者启动时才会判断,思路明朗,写个xp插件用 package com.example.xpdemo51; 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 HookMain implements IXposedHookLoadPackage { @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam loadPackageParam) throws Throwable { XposedBridge.log("进入xp"); if (loadPackageParam.packageName.equals("com.xingheng.escollection")) { Class clazz = loadPackageParam.classLoader.loadClass("com.xingheng.contract_impl.UserPermissionDelegate"); XposedHelpers.findAndHookMethod(clazz, "isTopicVip", new XC_MethodHook() { protected void beforeHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable { super.beforeHookedMethod(param); XposedBridge.log("Hook成功"); } protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult(true); } }); } } [/b][/size][/b][/size][/size][/font] [font=宋体][size=6][size=12pt][b][size=12pt][b]}[/b][/size][/b][/size][/size][/font][font=宋体][size=6][size=12pt][b][size=12pt][b]
之后就可以愉快的刷题了 传一下插件,下载链接放在下方隐藏内容中
里面有个debug版本的apk可以直接装 老铁们 要装xposed才能用的 老铁们 不装xposed用不了的
更多资源,请访问 大神论坛
游客你好,如果您要查看本帖隐藏链接需要登录才能查看,
请先登录
|