美文网首页Android逆向笔记
Android逆向练习 crackme0502

Android逆向练习 crackme0502

作者: h080294 | 来源:发表于2017-10-25 22:38 被阅读134次

    今天继续练习简单的crackme。
    先看一下界面,还是输入注册码,点击检测后弹Toast提示成功、失败。

    反编译APK

    几种方式
    1、直接用apktool反编译,得到smali代码
    2、直接解压apk,得到的dex文件用BytecodeViewer打开(翻译成java源码)
    3、d2j-dex2jar工具打成jar包,然后用jd-jui打开读java源码

    定位代码:

    先搜注册码相关的字符,找到onClick().


     this.btnCheckSN.setOnClickListener(new View.OnClickListener()
        {
          public void onClick(View paramAnonymousView)
          {
            if (new MainActivity.SNChecker(MainActivity.this, MainActivity.this.edtSN.getText().toString()).isRegistered()) {}
            for (String str = "注册码正确";; str = "注册码错误")
            {
              Toast.makeText(MainActivity.this, str, 0).show();
              return;
            }
          }
        });
    

    可以看到这里判断了个isRegistered(),然后下面的发编译代码有点问题。不过没关系,先看一眼isRegistered()函数:

    public boolean isRegistered()
        {
          int i = 0;
          if ((this.sn == null) || (this.sn.length() < 8)) {
            return false;
          }
          int j = this.sn.length();
          if (j == 8) {
            switch (this.sn.charAt(0))
            {
            default: 
              bool = false;
              if (bool) {
                switch (this.sn.charAt(3))
                {
                default: 
                  bool = false;
                }
              }
              break;
            }
          }
          do
          {
            for (;;)
            {
              return bool;
              bool = true;
              break;
              bool = true;
            }
            bool = false;
          } while (j != 16);
          int k = 0;
          label145:
          if (k >= j) {
            if (i % 6 != 0) {
              break label181;
            }
          }
          label181:
          for (boolean bool = true;; bool = false)
          {
            break;
            i += this.sn.charAt(k);
            k++;
            break label145;
          }
        }
    

    按照以往的经验,直接一劳永逸将isRegistered()返回true就行了。修改smali时,我们直接在函数开始的地方插入代码,让它返回true。

        const/4 v0, 0x1
        return v0
    

    然后我们看下上面提到的有错误的地方,就是这段:

     if (new MainActivity.SNChecker(MainActivity.this, MainActivity.this.edtSN.getText().toString()).isRegistered()) {}
            for (String str = "注册码正确";; str = "注册码错误")
            {
              Toast.makeText(MainActivity.this, str, 0).show();
              return;
            }
    

    到smali中查看,通过分析得知其实是反编译成java代码的时候产生的问题。

       .line 45
        .local v0, "checker":Lcom/droider/crackme0502/MainActivity$SNChecker;
        invoke-virtual {v0}, Lcom/droider/crackme0502/MainActivity$SNChecker;->isRegistered()Z
    
        move-result v2  #isRegistered()的结果
    
        if-eqz v2, :cond_0 #如果为false,就到cond_0
    
        const-string v1, "\u6ce8\u518c\u7801\u6b63\u786e"   #unicode转码 -> 注册码正确
    
        .line 46
        .local v1, "str":Ljava/lang/String;
        :goto_0         #开始循环
        iget-object v2, p0, Lcom/droider/crackme0502/MainActivity$2;->this$0:Lcom/droider/crackme0502/MainActivity;
    
        const/4 v3, 0x0
    
        #调用toast方法,v2相当于MainActivity.this,v1是str,v3=0
        invoke-static {v2, v1, v3}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
    
        move-result-object v2
    
        invoke-virtual {v2}, Landroid/widget/Toast;->show()V
    
        .line 47
        return-void
    
        .line 45
        .end local v1    # "str":Ljava/lang/String;
        :cond_0       #isRegistered()的结果位false跳到这里
        const-string v1, "\u6ce8\u518c\u7801\u9519\u8bef"   #unicode转码 -> 注册码错误
    
        goto :goto_0
    .end method
    

    好了,打包apk试验,却发现应用闪退。。。看一眼logcat,发现了程序被修改的log提示。所以应该是某些地方做了某种验证,不符合后就kill掉应用。这里有两种方法,一种是搜索提示“程序被修改”字符,不过一般的是不会给你任何提示的;另一种是搜索finish()方法或者android.os.killprocess()方法。我们来搜索一下,果然在MyApp中发现了两处:

    结合jd-jui代码

    很明显的用了Java反射机制,手动调用了isRegistered()方法,参数是字符串1111。如果1111通过了验证或者调用isRegistered()失败,则用killProcess干掉本应用进程。知道了原理,也就好解决了,直接将两处killProcess()的调用nop掉就可以了。

    重新打包验证,随便输入字符都能验证通过了。

    crackme0502 APK连接:
    链接: https://pan.baidu.com/s/1kVeNCoB 密码: b5km

    相关文章

      网友评论

        本文标题:Android逆向练习 crackme0502

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