Android安全-逆向Android安全-Reverse

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

2017-08-22  本文已影响61人  Henry3II

这次要破解的软件是: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

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

上一篇下一篇

猜你喜欢

热点阅读