0X01

无意间发现一款老司机应用,用起来还不错,但是可恶的是有次数限制。怒。于是念念不忘,要破了他!

0x02

按照以往的经验,先拿到apk中的dex文件,但愿不要加固。

smali2
smali2

不慌 问题不大。才两个包,好找。

入口
入口

找到了splash入口,阅读代码后发现 root后不能使用,使用代理不能使用,模拟器不能使用。

paste image
paste image

那好 先去了。

分析代码
initView
initView

b()方法中有个c方法,返回 检测到您使用的是模拟器或者设备已经root,不允许继续使用,所以 hook c方法 强制返回false 使其能够进入到a.a(activity)中。

XposedHelpers.findAndHookMethod("com.niming.douyin.ui.splash.SplashActivity", cl, "c", new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    XposedBridge.log("SplashActivity beforeHookedMethod   " + param.getResult());
                    param.setResult(false);
                }
            });

b中还有一个方法,!k.b(this.activity),看代码是把所有的模拟器标识都列了出来,不知道为啥禁用模拟器,可能这些限制是为了躲坑。

模拟器识别

使用xp 强制也给他通过

XposedHelpers.findAndHookMethod("com.niming.douyin.ui.splash.SplashActivity", cl, "a", Context.class, new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    XposedBridge.log("SplashActivity beforeHookedMethod   " + param.getResult());
                    param.setResult(false);
                }
            });

这样进入到了f();

接口请求
接口请求
这里走了一个请求domain的接口,请求成功后 调用了
ConfigUtil.getInstance().save(com.niming.douyin.a.a.k, domain);
this.a.d();

保存了一下地址,然后调用

d方法
d方法

这里是先验证一下设备有没有注册过,如果注册过,直接登录,没有注册过,先注册。在几次测试中发现,这个手机设备号在第一次注册就存入到数据库,再次进入会取之前的数据,限制3次就是从这个设备号查出来的。通过抓取接口发现 当满三次的时候,并不会返回成功的数据,所以无法拿到地址。只能通过重新注册获取这免费的三次机会。
所以要hook下这个配置文件,获取是否注册的时候 返回false,重新注册,获取设备号的时候 随机一个,避免重复。

XposedHelpers.findAndHookMethod("com.niming.framework.basedb.ConfigUtil", cl, "getString", String.class, new XC_MethodHook() {
               @Override
               protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                   super.afterHookedMethod(param);
                   if (param.args[0].equals("device_id")) {
                       //随机id
                       String deviceId = String.valueOf(UUID.randomUUID().toString());
                       param.setResult(deviceId);

                   }

               }
           });
           XposedHelpers.findAndHookMethod("com.niming.framework.basedb.ConfigUtil", cl, "getBooleanValue", String.class, new XC_MethodHook() {
               @Override
               protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                   super.afterHookedMethod(param);
                   if (param.args[0].toString().equals("is_device_register")) {
                       param.setResult(false);
                   }

               }
           });

这样每次都会重新注册获取免费的三次机会。

在测试过程中发现 新注册后会跳转到广告页SplashAdActivity,这个界面有个延时操作,很麻烦。

paste image
paste image

d 默认值给了5秒。

paste image

给他强制跳转,代码中有个方法

private void b() {
  MainActivity.a(this.activity);
  finish();
 }

直接能够调用~

XposedHelpers.findAndHookMethod("com.niming.douyin.ui.splash.SplashAdActivity", cl, "initView", Bundle.class, new XC_MethodHook() {

                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    super.afterHookedMethod(param);
                    //去广告
                    XposedHelpers.callMethod(param.thisObject, "b");
                }
            });

这样跳转的时候就能够忽略延时广告,直接跳转了。

0x03

在网络请求测试中发现数据是加密的,当然代码都拿到了,还怕拿不到密码?

paste image

这里有个密码,有点兴奋,but不可能这么明显八。
反码了几次发现不对哦。

paste image

ennnnn….

paste image

e….
我觉得这个TextUtils肯定用到了,戳进去发现是Jni……

paste image

不过没关系。有工具!
找到lib中的security,拖到这个小姐姐身上

paste image

paste image

很明显 仅仅返回的是字符串。从java代码看,应该是不同的环境需要不同的密码取转码。

paste image

解下数据,这波操作可以。

paste image

0x??

__ //todo __

1.三次后自动注册一次 确保一直有次数

2.暴力寻找vip的uuid