吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 9005|回复: 25
收起左侧

[Android 原创] 对某apk的继续破解

[复制链接]
killer5 发表于 2015-7-24 14:01
最近刚接触android逆向,因此,分析的比较简单,请多多包涵。
apk来源于本论坛,当时帖子的作者,通过修改积分数值,对软件进行了破解,但并未找出注册机制等等,因此下面将对注册机制进行分析。
原帖:http://www.52pojie.cn/forum.php? ... 6orderby%3Ddateline


刚拿到该APK,先安装看看效果,但是安装后会闪退,并给出提示如下:
1.PNG


因此,猜测该APK应该会检查更新,如果有更新,就退出,并提示安装新版本。
载入JEB,进行分析,发现代码进行了混淆。虽然如此,但可以找到activity_register,An_QimenActivity。activity_register用处不是特别大,找到An_QimenActivity中的onCreate方法,发现如下代码:
[Java] 纯文本查看 复制代码
this.getWindow().setSoftInputMode(3);
        if(this.b()) {
            Toast.makeText(this.getApplicationContext(), "本程序已有升级版,可在南方周易程序网站升级更新:www.nfbazi.com", 1)
                    .show();
            this.finish();
        }
        else {。。。}

可以看到,我们的猜测是对的,因此首先去掉该限制,利用apktool反编译,找到An_QimenActivity.smali中的onCreate方法,找到如下代码:
[Java] 纯文本查看 复制代码
if-eqz v0, :cond_0

    invoke-virtual {p0}, Lcom/nfbazi/qimen/An_QimenActivity;->getApplicationContext()Landroid/content/Context;

    move-result-object v0

    const-string v1, "\u672c\u7a0b\u5e8f\u5df2\u6709\u5347\u7ea7\u7248\uff0c\u53ef\u5728\u5357\u65b9\u5468\u6613\u7a0b\u5e8f\u7f51\u7ad9\u5347\u7ea7\u66f4\u65b0\uff1awww.nfbazi.com"

    invoke-static {v0, v1, v7}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;

    move-result-object v0

    invoke-virtual {v0}, Landroid/widget/Toast;->show()V

    invoke-virtual {p0}, Lcom/nfbazi/qimen/An_QimenActivity;->finish()V

    :goto_0

将if-eqz v0修改为if-nez v0,重新打包,签名,即可运行。
2.PNG
分析发现,该软件有10次的限制,10后积分会减为0,当然针对积分的限制,原帖作者已经给出了破解方法。而本文重点介绍该软件的注册机制
点击菜单可以发现注册窗口,因此需要分析该软件的注册机制,找到注册码。
JEB中找到bp类,并找到onClick方法,代码如下:
[Java] 纯文本查看 复制代码
public void onClick(View arg6) {
        int v3 = -16776961;
        if(a.q) {
            this.a.finish();
        }
        else {
            View v0 = this.a.findViewById(2131165230);
            View v1 = this.a.findViewById(2131165231);
            String v0_1 = ((EditText)v0).getText().toString().trim();
            if(v0_1.length() == 0) {
                ((TextView)v1).setTextColor(v3);
                ((TextView)v1).setText("您还没有输入注册码。");
            }
            else if(!d.a(a.o, v0_1)) {
                ((TextView)v1).setTextColor(v3);
                ((TextView)v1).setText("您输入的注册码不对。");
            }
            else {
                ((TextView)v1).setTextColor(-65536);
                ((TextView)v1).setText("注册成功,点击“退出”。");
                activity_register.a(this.a, this.a.getSharedPreferences("pcr", 0));
                activity_register.a(this.a).edit().putString("acc", this.a.a.a(v0_1)).commit();
                activity_register.a(this.a).edit().putString("bcc", this.a.a.a(a.o)).commit();
                a.c("pcr");
            }

            a.p = "a@^*(^*ga$(&%io";
        }
    }

看到注册部分的代码了吧,主要是提取我们输入的注册码,与该软件的真正的注册码进行比较判断。
跟入a.o 发现是一个string,
[Java] 纯文本查看 复制代码
public class a {
    ....
    public static String o;
    ....
    static {
        .....
        a.o = "";
        }
}

然后查看什么时候对a.o进行的赋值,如下:
[Java] 纯文本查看 复制代码
public boolean b() {
        int v6 = 8;
        int v5 = 7;
        Object v0 = this.G.getSystemService("phone");
        String v1 = ((TelephonyManager)v0).getDeviceId();
        String v2 = ((TelephonyManager)v0).getSubscriberId();
        String v0_1 = ((TelephonyManager)v0).getSimSerialNumber();
        if(v1 == null) {
            v1 = "";
        }

        if(v2 == null) {
            v2 = "";
        }

        if(v0_1 == null) {
            v0_1 = "";
        }

        if(a.l == null) {
            a.l = "";
        }

        if(!v1.equals("")) {
            v1 = v1.toUpperCase();
        }

        if(!v2.equals("")) {
            v2 = v2.toUpperCase();
        }

        if(!v0_1.equals("")) {
            v0_1 = v0_1.toUpperCase();
        }

        if(!a.l.equals("")) {
            a.l = a.l.toUpperCase();
        }

        if(v1.length() >= v6) {
            v1 = v1.substring(v1.length() - 7);
        }

        if(v2.length() >= v6) {
            v2 = v2.substring(v2.length() - 7);
        }

        if(v0_1.length() >= v6) {
            v0_1 = v0_1.substring(v0_1.length() - 7);
        }

        if(a.l.length() >= v6) {
            a.l = a.l.substring(a.l.length() - 7);
        }

        if(v1.length() != v5 || (this.d(v1))) {
            if(v2.length() == v5 && !this.d(v2)) {
                v0_1 = String.valueOf(v2) + "B";
                goto label_71;
            }

            if(v0_1.length() == v5 && !this.d(v0_1)) {
                v0_1 = String.valueOf(v0_1) + "C";
                goto label_71;
            }

            if(a.l.length() == v5 && !this.d(a.l)) {
                v0_1 = String.valueOf(a.l) + "E";
                goto label_71;
            }

            v0_1 = this.c();
        }
        else {
            v0_1 = String.valueOf(v1) + "A";
        }

    label_71:
        a.o = String.valueOf(v0_1) + "-2414";
        boolean v0_2 = v0_1.length() > 0 ? true : false;
        return v0_2;
    }

上面便是注册码的产生计算的过程继续查看class d 类。
[Java] 纯文本查看 复制代码
 public static boolean a(String arg3, String arg4) {
        boolean v0 = true;
        a.p = d.a(d.a.a(arg3));
        if(a.p.equals(arg4)) {
            a.q = true;
        }
        else {
            a.q = false;
            v0 = false;
        }

        return v0;
    }

其中a.p中保存了真正的注册码,其中深入分析可知a.p实际上也是一个string。
注册机制的分析就到此结束了。
知道了注册机制,下面就让程序把自己的注册码吐出来
打开反编译的文件d.smali,找到如下代码:
[Java] 纯文本查看 复制代码
.method public static a(Ljava/lang/String;Ljava/lang/String;)Z
    .locals 3

    const/4 v0, 0x1

    const/4 v1, 0x0

    sget-object v2, Lcom/nfbazi/qimen/a/d;->a:Lcom/nfbazi/qimen/a/b;

    invoke-virtual {v2, p0}, Lcom/nfbazi/qimen/a/b;->a(Ljava/lang/String;)Ljava/lang/String;

    move-result-object v2

    invoke-static {v2}, Lcom/nfbazi/qimen/a/d;->a(Ljava/lang/String;)Ljava/lang/String;

    move-result-object v2

    sput-object v2, Lcom/nfbazi/qimen/a/a;->p:Ljava/lang/String;

    sget-object v2, Lcom/nfbazi/qimen/a/a;->p:Ljava/lang/String;

    invoke-virtual {v2, p1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z

    move-result v2

这个便是上面的 public static boolean a(String arg3, String arg4)方法,修改如下:
3.PNG
然后打包,签名,允许程序,并注册,其中注册码随便写。
然后在cmd中输入adb logcat -s SN:V
可以得到注册码如下所示:
4.PNG

然后用程序自己吐出来的注册码进行注册,提示注册成功,并可以升级该apk




免费评分

参与人数 5热心值 +5 收起 理由
dreamnyj + 1 已经处理,感谢您对吾爱破解论坛的支持!
qtfreet00 + 1 我很赞同!
沙耶 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩.
guo19921126 + 1 我很赞同!
木木头上 + 1 不错,楼主继续努力

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

头像被屏蔽
gowupu 发表于 2015-7-24 14:53
提示: 作者被禁止或删除 内容自动屏蔽
 楼主| killer5 发表于 2015-7-24 15:50
gowupu 发表于 2015-7-24 14:53
大牛你还是说普通话吧,放了这些屁,都什么用,没有说到正经上。垃圾。

不是给你这种垃圾看的
redapple0204 发表于 2015-7-24 14:09
SLXSXY 发表于 2015-7-24 14:11
顶一下楼主吧!!!!!!
木木头上 发表于 2015-7-24 14:16
虽然不知道这个软件是干什么的,但还是主持楼主
御豆 发表于 2015-7-24 14:16
支持, 加油吧3!
扯淡的ni 发表于 2015-7-24 14:27
到现在我都不知道这个个是干嘛的软件
maple_1997 发表于 2015-7-24 16:01
新手来学习了,感谢楼主的教程!
沙耶 发表于 2015-7-24 16:06
欢迎分析讨论交流,吾爱破解论坛有你更精彩!
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-28 07:40

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表