美文网首页Android安全-逆向Android安全-Reverse
Android逆向学习笔记2:玄奥八字

Android逆向学习笔记2:玄奥八字

作者: Henry3II | 来源:发表于2017-08-22 22:56 被阅读61次

    这次要破解的软件是:http://www.xazhouyi.com/android/soft/bazi.html
    声明:1.软件内容不代表本人观点;2.本文内容只用作学习交流使用,若有人利用本文内容进行任何商业目的和非法牟利,带来的任何法律责任将由操作者本人承担,和本文作者没有任何关系。

    第一种尝试:

    打开软件提示未注册:


    Paste_Image.png

    所谓的只能使用1999年,意思就是无论你想要查哪年哪月哪日,它都会只返回1999年的结果:


    Paste_Image.png
    使用AndroidKiller打开,搜索打开软件时的提示“未注册”:
    Paste_Image.png

    然后在public.xml中查找与之对应的索引值,查到索引值为:0x7f060003;在工程搜索中查找该索引值,可以看到在main.smali文件的:cond_b处有未注册的提示。


    Paste_Image.png
    const-string v7, "\u7384\u5965\u516b\u5b577.2\u672a\u6ce8\u518c\uff01"  #未注册字符串
    
    invoke-virtual {p0, v7}, LMy/XuanAo/BaZiYi/main;->setTitle(Ljava/lang/CharSequence;)V
    
    .line 199
    
    invoke-virtual {p0}, LMy/XuanAo/BaZiYi/main;->getResources()Landroid/content/res/Resources;
    
    move-result-object v7
    
    const v8, 0x7f060003
    

    由此可猜想:cond_b为失败分支,所以我们要查找哪里指向了该分支,搜索:cond_b,在该文件中找到如下:

    Paste_Image.png

    可以看到有三个检验函数,每个的 if-eqz v7, :cond_b就是关键点。

    .line 193
    
    :cond_1
    
    sget-object v7, LMy/XuanAo/BaZiYi/main;->m_chkSoft:LMy/XuanAo/BaZiYi/CSoftReg;
    
    invoke-virtual {v7}, LMy/XuanAo/BaZiYi/CSoftReg;->ChkNumA()Z
    
    move-result v7
    
    if-eqz v7, :cond_b
    
    sget-object v7, LMy/XuanAo/BaZiYi/main;->m_chkSoft:LMy/XuanAo/BaZiYi/CSoftReg;
    
    invoke-virtual {v7}, LMy/XuanAo/BaZiYi/CSoftReg;->ChkNumB()Z
    
    move-result v7
    
    if-eqz v7, :cond_b
    
    sget-object v7, LMy/XuanAo/BaZiYi/main;->m_chkSoft:LMy/XuanAo/BaZiYi/CSoftReg;
    
    invoke-virtual {v7}, LMy/XuanAo/BaZiYi/CSoftReg;->ChkNumC()Z
    
    move-result v7
    
    if-eqz v7, :cond_b
    
    .line 195
    
    const-string v7, "\u7384\u5965\u516b\u5b577.2"
    
    invoke-virtual {p0, v7}, LMy/XuanAo/BaZiYi/main;->setTitle(Ljava/lang/CharSequence;)V
    
    .line 196
    
    sput-boolean v10, LMy/XuanAo/BaZiYi/main;->m_regFlag:Z
    

    我们也可以看一下 java代码:

    Paste_Image.png

    与之对应的为:

      if ((!m_chkSoft.ChkNumA()) || (!m_chkSoft.ChkNumB()) || (!m_chkSoft.ChkNumC())) {
    
        break label682;
    
      }
    

    所以将 if-eqz v7, :cond_b改为 if-nez v7, :cond_b,然后编译安装之后便可以看到,软件打开便不会再提示未注册,而且菜单-更多-注册中显示为“已注册”。如图:

    Paste_Image.png

    上述虽然完成了注册,但是还是无法查询非1999年的数据,所以仍需继续破解。

    第二种尝试:

    首先尝试在点击“排八字”时用monitor监听查看logcat信息,结果没有得到什么有用的信息,果断换了方法。

    在菜单-更多-注册中输入随便输入的注册码时,会有如下文字提示:

    Paste_Image.png

    那就从这个提示入手,将其转化为 UNICODE,搜索转换后的\u8BF7\u8F93\u5165\u6CE8\u518C\u53F7,如图:

    Paste_Image.png

    右键查看下源码,可以看到这段字符串位于onClick()函数中:

    Paste_Image.png

    具体代码如下,部分加了注释:

      public void onClick(View paramView)
      {
        if (paramView == this.BtoClose)
        {
          setResult(0);
          finish();
        }
        if (paramView == this.BtoOk)
        {
          if (this.m_bFlag)
          {
            setResult(0);
            finish();
          }
        }
        else {
          return;
        }
        paramView = this.EdtReg.getText().toString().trim();
        if (paramView.length() == 15)   //判断输入的注册码长度是否为15
        {
          int i = 0;
          for (;;)
          {
            if (i >= 15)
            {
              main.m_chkSoft.Fregcode = paramView;
              if ((main.m_chkSoft.ChkNumA()) && (main.m_chkSoft.ChkNumB()) && (main.m_chkSoft.ChkNumC()))   //验证注册码是否正确
              {
                main.m_chkSoft.WriteRegCode(paramView);
                this.m_bFlag = true;
              }
              paramView = getIntent();
              paramView.putExtra("reg", this.m_bFlag);
              setResult(104, paramView);
              finish();
              return;
            }
            if ((paramView.charAt(i) < '0') || (paramView.charAt(i) > '9'))
            {
              Toast.makeText(this, "请输入数字。", 1).show();
              return;
            }
            i += 1;
          }
        }
        Toast.makeText(this, "请输入注册号。", 1).show();  //弹出错误框
      }
    

    据此,在项目中搜索 ChkNumA,找到函数实现部分,右键查看源码,可得到如下:

      public boolean ChkNumA()
      {
        long l1 = 0L;
        char[] arrayOfChar = new char[6];
        if ((this.Fregcode.length() != 15) || (this.Fsoftsn.length() != 12)) {
          return false;
        }
        long l2 = 10000L;
        int i = 1;
        long l3;
        long l4;
        do
        {
          l3 = l1 + (this.Fregcode.charAt(i - 1) - '0') * l2;
          i += 1;
          l4 = l2 / 10L;
          l2 = l4;
          l1 = l3;
        } while (l4 > 0L);
        String str = String.valueOf(((l3 ^ SnCal(1555L)) + 1555L) / 3L - 1555L).trim();
        l1 = str.length();
        str.getChars(0, (int)l1, arrayOfChar, 0);
        if (l1 < 4L)
        {
          l2 = 4L - l1;
          i = (int)(l1 - 1L);
          if (i < 0)
          {
            i = 0;
            label162:
            if (i < (int)l2) {
              break label198;
            }
          }
        }
        else
        {
          i = 1;
        }
        for (;;)
        {
          if (i > 4)
          {
            return true;
            arrayOfChar[((int)(i + l2))] = arrayOfChar[i];
            i -= 1;
            break;
            label198:
            arrayOfChar[i] = '0';
            i += 1;
            break label162;
          }
          if (arrayOfChar[(i - 1)] != this.Fsoftsn.charAt(i - 1)) {
            return false;   //此处有字符串比较,不相等就返回false,考虑改成true
          }
          i += 1;
        }
      }
    

    三个检验函数ChkNumA()、ChkNumB()、ChkNumC()是类似的。找到修改的思路之后,就在AK中修改对应的smali代码。

    Paste_Image.png

    将 const/4 v11, 0x0 改为 const/4 v11, 0x1,三个函数都要修改,这个修改的位置在每个函数smali代码的末尾。然后编译安装,任意输入输入日期发现已经可查询八字了:

    Paste_Image.png

    大概就是这样,还有,我不好什么算命这口。。

    相关文章

      网友评论

      本文标题:Android逆向学习笔记2:玄奥八字

      本文链接:https://www.haomeiwen.com/subject/anjrdxtx.html