csky6688 发表于 2015-7-24 15:49

对某apk的继续破解

本帖最后由 csky6688 于 2015-7-24 20:07 编辑

今天不知道怎么的,论坛登录不了,所以在某首发了
-----------------------------------------------------------------------
最近刚接触android逆向,因此,分析的比较简单,请多多包涵。
apk来源于本论坛,当时帖子的作者,通过修改积分数值,对软件进行了逆向,但并未找出注册机制等等,因此下面将对注册机制进行分析。

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

因此,猜测该APK应该会检查更新,如果有更新,就退出,并提示安装新版本。
载入JEB,进行分析,发现代码进行了混淆。虽然如此,但可以找到activity_register,An_QimenActivity。activity_register用处不是特别大,找到An_QimenActivity中的onCreate方法,发现如下代码:
this.getWindow().setSoftInputMode(3);
      if(this.b()) {
            Toast.makeText(this.getApplicationContext(), "本程序已有升级版,可在南方周易程序网站升级更新:www.nfbazi.com", 1)
                  .show();
            this.finish();
      }
      else {。。。}可以看到,我们的猜测是对的,因此首先去掉该限制,利用apktool反编译,找到An_QimenActivity.smali中的onCreate方法,找到如下代码:
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,重新打包,签名,即可运行。

分析发现,该软件有10次的限制,10后积分会减为0,当然针对积分的限制,原帖作者已经给出了分析方法。而本文重点介绍该软件的注册机制
点击菜单可以发现注册窗口,因此需要分析该软件的注册机制,找到注册码。
在JEB中找到bp类,并找到onClick方法,代码如下:
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
public class a {
    ....
    public static String o;
    ....
    static {
      .....
      a.o = "";
      }
}然后查看什么时候对a.o进行的赋值,如下:
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 类。
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,找到如下代码:
.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)方法,修改如下:


然后打包,签名,允许程序,并注册,其中注册码随便写。
然后在cmd中输入adb logcat -s SN:V
可以得到注册码如下所示:

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

冷瞳 发表于 2015-7-24 15:51

{:5_124:}沙发 你这让我激情无线啊- -

寻寻觅觅 发表于 2015-7-24 15:56

坐凳子 看不懂

923004243 发表于 2015-7-24 16:11

楼主我建议你做一个新手系列   

雪里红 发表于 2015-7-24 18:25

都希望出教程

csky6688 发表于 2015-7-24 18:52

923004243 发表于 2015-7-24 16:11
楼主我建议你做一个新手系列

我也是刚接触,能力还达不到的

csky6688 发表于 2015-7-24 19:45

雪里红 发表于 2015-7-24 18:25
都希望出教程

等能力达到了,会出一些视频的,只是现在还达不到那个高度{:5_121:}

A00 发表于 2015-7-25 11:19

不错的分享

tony2526 发表于 2015-7-25 13:51

教程不错,挺详细的,期待楼主更多的教程出来,顶下{:5_116:}

我好想世界末日 发表于 2016-5-29 18:27

感觉一脸懵逼 看不懂这些代码
页: [1] 2 3
查看完整版本: 对某apk的继续逆向