无痛单词_1.10.0 逆向思路

无痛单词_1.10.0 逆向思路

搜索方法名:tech.xiangzi.painless.data.remote.model.UserBean.getPro

efe3aedc54cd4714de32172841b3c661_720

点击第一个:

ec4d9d34e107e8f9c0919c4d55deafd0_720

在返回前添加代码:const v0,0x9

7c596f7f72009605cd6b6e796eab08fe_720

修改完成,成品图:

f8a10794efb62479fbc7e718fe8f5f85_720

hook 代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
Java.perform(function () {
    //打印堆栈信息的方法
    function showStacks() {
        console.log(
            Java.use("android.util.Log")
                .getStackTraceString(
                    Java.use("java.lang.Throwable").$new()
                )
        );
    }

    var Intent = Java.use("android.content.Intent");
    Intent.$init.overload('android.content.Context', 'java.lang.Class').implementation = function (context, cls) {
        console.log("Intent(context, cls) called with context: " + context + " and class: " + cls);
        showStacks();
        return this.$init(context, cls);
    };

软件里点击“自定义单词本”后跳转到购买会员的界面,同时控制台打印出堆栈信息:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
java.lang.Throwable
        at android.content.Intent.<init>(Native Method)
        at tech.xiangzi.painless.utils.ext.CustomExtKt.toPayPage(Unknown Source:29)
        at tech.xiangzi.painless.ui.fragment.SettingFragment$showPayDialog$1$1.invoke(Unknown Source:7)
        at tech.xiangzi.painless.ui.fragment.SettingFragment$showPayDialog$1$1.invoke(Unknown Source:0)
        at tech.xiangzi.painless.ui.activity.MainActivity.onClickInterceptor(SourceFile:252)
        at tech.xiangzi.painless.ui.activity.MainActivity.onClickInterceptor$default(Unknown Source:11)
        at tech.xiangzi.painless.ui.fragment.SettingFragment.showPayDialog(Unknown Source:22)
        at tech.xiangzi.painless.ui.fragment.SettingFragment.access$showPayDialog(Unknown Source:0)
        at tech.xiangzi.painless.ui.fragment.SettingFragment$initView$1$4$2.invoke(Unknown Source:85)
        at tech.xiangzi.painless.ui.fragment.SettingFragment$initView$1$4$2.invoke(Unknown Source:8)
        at com.drake.brv.BindingAdapter$BindingViewHolder$2.invoke(Unknown Source:40)
        at com.drake.brv.BindingAdapter$BindingViewHolder$2.invoke(Unknown Source:2)
        at com.drake.brv.listener.ThrottleClickListener.onClick(Unknown Source:24)
        at android.view.View.performClick(View.java:7755)
        at android.view.View.performClickInternal(View.java:7728)
        at android.view.View.access$3700(View.java:862)
        at android.view.View$PerformClick.run(View.java:29337)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:210)
        at android.os.Looper.loop(Looper.java:299)
        at android.app.ActivityThread.main(ActivityThread.java:8307)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:577)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1073)

一个个看过去,定位到关键函数:

4e48c8c0ff2aedad83387f182cb7ea4c

之所以跳转到购买会员的界面是因为getPro()返回值为0,所以将返回值改成1

又发现这样子还不是终生会员,所以我们查看一下getPro()的用例,定位到一个关键函数:

95197d7df5e1b7d096caa1eea26d8e08

getPro()的返回值为9才是终生会员(早知道直接搜索关键字“终生会员”了,绕了那么大一圈……)

做个总结吧:hook定位固然好用,但还是动静态分析结合有更高的效率,例如这个案例,如果一开始就用关键词搜索的效率会更高