御剑 发表于 2014-4-24 14:48

超强call3正式版 的简单分析

本帖最后由 御剑 于 2014-4-24 15:23 编辑

【文章标题】:超强call3正式版 的简单分析
【文章作者】: 御剑
【作者邮箱】: 408885352@qq.com
【作者主页】: 无
【作者QQ号】: 无
【软件名称】:超强call3正式版
【下载地址】: http://pan.baidu.com/s/1o6ykas6为方便新手研究我就把这个版本上传百度网盘吧
【加壳方式】: 无
【编写语言】: JAVA
【使用工具】: ApkIDE
【软件介绍】:没什么好介绍的...
【作者声明】: 只是技术交流,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------【详细过程】
小菜也只是刚接触移动安全,对JAVA并不是很了解. 如有失误之处还请见谅...
首先我们先安装并打开超强call3正式版...


发现软件是一注册码方式验证的...那么我们先随便输入一串数字,看看有什么可用信息...


我们发现它会弹出一个提示:”您输入的注册码有误,请重新输入“我们用ApkIDE 打开 超强call3正式版 并搜索“您输入的注册码有误,请重新输入”看看能否给我们带来有用的信息~
我们发现并未搜索到有用的信息...但JAVA的东西似乎都喜欢把关键信息转换为Unicode,或者英文所以我们先把关键信息转换成Unicode 试试
转换后:“\u60a8\u8f93\u5165\u7684\u6ce8\u518c\u7801\u6709\u8bef\uff0c\u8bf7\u91cd\u65b0\u8f93\u5165”
我们发现我们搜索到了一条信息...那么我们双击进去
来到此处:

    .line 71
    :cond_1
    :try_start_1
    const-string v0, "\u60a8\u8f93\u5165\u7684\u6ce8\u518c\u7801\u6709\u8bef\uff0c\u8bf7\u91cd\u65b0\u8f93\u5165"

    const/4 v1, 0x0

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

    move-result-object v0

    .line 72
    invoke-virtual {v0}, Landroid/widget/Toast;->show()V
    :try_end_1
    .catch Ljava/lang/Exception; {:try_start_1 .. :try_end_1} :catch_0

    goto :goto_0






package com.call3;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.telephony.TelephonyManager;
import android.text.Editable;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class VerifyActivity extends Activity
implements View.OnClickListener
{
private Button a;
private Button b;
private TextView c;
private EditText d;
private SharedPreferences e;
private TelephonyManager f;
private ProgressDialog g;

private void a()
{
    if (this.d.getText().toString().trim().equals(""))
    {
      Toast.makeText(this, "请输入注册码", 0).show();
      return;
    }
    try
    {
      String str = DESUtil.encryptDES(this.c.getText().toString().toLowerCase()).substring(0, 6);
      if (this.d.getText().toString().trim().toLowerCase().equals(str.toLowerCase()))
      {
      Toast.makeText(this, "注册成功", 0).show();
      finish();
      startActivity(new Intent(this, MainActivity.class));
      this.e.edit().putBoolean("isRegistered", true).commit();
      return;
      }
    }
    catch (Exception localException)
    {
      localException.printStackTrace();
      return;
    }
    Toast.makeText(this, "您输入的注册码有误,请重新输入", 0).show();
}

public void onClick(View paramView)
{
    switch (paramView.getId())
    {
    default:
      return;
    case 2131165204:
      a();
      return;
    case 2131165205:
    }
    finish();
}

protected void onCreate(Bundle paramBundle)
{
    super.onCreate(paramBundle);
    setContentView(2130903041);
    this.g = new ProgressDialog(this);
    this.g.setCanceledOnTouchOutside(false);
    this.g.setMessage("正在验证,请稍候...");
    this.c = ((TextView)findViewById(2131165202));
    this.a = ((Button)findViewById(2131165204));
    this.b = ((Button)findViewById(2131165205));
    this.d = ((EditText)findViewById(2131165203));
    this.a.setOnClickListener(this);
    this.b.setOnClickListener(this);
    this.e = PreferenceManager.getDefaultSharedPreferences(this);
    this.f = ((TelephonyManager)getSystemService("phone"));
    String str = this.f.getDeviceId();
    this.c.setText(str.substring(-6 + str.length()));
    if (this.e.getBoolean("isRegistered", false))
      startActivity(new Intent(this, MainActivity.class));
}
}


下面我们再对源码进行简单的分析

package com.call3;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.telephony.TelephonyManager;
import android.text.Editable;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class VerifyActivity extends Activity
implements View.OnClickListener
{
private Button a;
private Button b;
private TextView c;
private EditText d;
private SharedPreferences e;
private TelephonyManager f;
private ProgressDialog g;

private void a()
{
    if (this.d.getText().toString().trim().equals(""))//判断是否有输入注册码
    {
      Toast.makeText(this, "请输入注册码", 0).show();   //如果没有则提示"请输入注册码"
      return;//返回
    }
    try
    {
      String str = DESUtil.encryptDES(this.c.getText().toString().toLowerCase()).substring(0, 6);
      if (this.d.getText().toString().trim().toLowerCase().equals(str.toLowerCase()))   //判断注册码是否正确
      {
      Toast.makeText(this, "注册成功", 0).show();//如注册码正确则提示"注册成功"
      finish();
      startActivity(new Intent(this, MainActivity.class));
      this.e.edit().putBoolean("isRegistered", true).commit();//isRegistered 为正确
      return;
      }
    }
    catch (Exception localException)
    {
      localException.printStackTrace();
      return;
    }
    Toast.makeText(this, "您输入的注册码有误,请重新输入", 0).show();//如注册码错误则提示:"您输入的注册码有误,请重新输入"
}

public void onClick(View paramView)
{
    switch (paramView.getId())
    {
    default:
      return;
    case 2131165204:
      a();
      return;
    case 2131165205:
    }
    finish();
}

protected void onCreate(Bundle paramBundle)
{
    super.onCreate(paramBundle);
    setContentView(2130903041);
    this.g = new ProgressDialog(this);
    this.g.setCanceledOnTouchOutside(false);
    this.g.setMessage("正在验证,请稍候...");
    this.c = ((TextView)findViewById(2131165202));
    this.a = ((Button)findViewById(2131165204));
    this.b = ((Button)findViewById(2131165205));
    this.d = ((EditText)findViewById(2131165203));
    this.a.setOnClickListener(this);
    this.b.setOnClickListener(this);
    this.e = PreferenceManager.getDefaultSharedPreferences(this);
    this.f = ((TelephonyManager)getSystemService("phone"));
    String str = this.f.getDeviceId();
    this.c.setText(str.substring(-6 + str.length()));
    if (this.e.getBoolean("isRegistered", false))
      startActivity(new Intent(this, MainActivity.class));
}
}

.method private a()V
    .locals 3

    .prologue
    const/4 v2, 0x0

    .line 53
    iget-object v0, p0, Lcom/call3/VerifyActivity;->d:Landroid/widget/EditText;

    invoke-virtual {v0}, Landroid/widget/EditText;->getText()Landroid/text/Editable;

    move-result-object v0

    invoke-interface {v0}, Landroid/text/Editable;->toString()Ljava/lang/String;

    move-result-object v0

    invoke-virtual {v0}, Ljava/lang/String;->trim()Ljava/lang/String;

    move-result-object v0

    const-string v1, ""

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

    move-result v0

    if-eqz v0, :cond_0//判断是否有输入注册码如有输入则跳转到:cond_0 否则往下执行

    .line 54
    const-string v0, "\u8bf7\u8f93\u5165\u6ce8\u518c\u7801" //"请输入注册码"

    invoke-static {p0, v0, v2}, 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

    .line 79
    :goto_0
    return-void

    .line 59
    :cond_0
    :try_start_0
    iget-object v0, p0, Lcom/call3/VerifyActivity;->c:Landroid/widget/TextView;

    invoke-virtual {v0}, Landroid/widget/TextView;->getText()Ljava/lang/CharSequence;

    move-result-object v0

    invoke-interface {v0}, Ljava/lang/CharSequence;->toString()Ljava/lang/String;

    move-result-object v0

    invoke-virtual {v0}, Ljava/lang/String;->toLowerCase()Ljava/lang/String;

    move-result-object v0

    .line 58
    invoke-static {v0}, Lcom/call3/DESUtil;->encryptDES(Ljava/lang/String;)Ljava/lang/String;

    move-result-object v0

    .line 59
    const/4 v1, 0x0

    .line 60
    const/4 v2, 0x6

    .line 59
    invoke-virtual {v0, v1, v2}, Ljava/lang/String;->substring(II)Ljava/lang/String;

    move-result-object v0

    .line 61
    iget-object v1, p0, Lcom/call3/VerifyActivity;->d:Landroid/widget/EditText;

    invoke-virtual {v1}, Landroid/widget/EditText;->getText()Landroid/text/Editable;

    move-result-object v1

    invoke-interface {v1}, Landroid/text/Editable;->toString()Ljava/lang/String;

    move-result-object v1

    invoke-virtual {v1}, Ljava/lang/String;->trim()Ljava/lang/String;

    move-result-object v1

    invoke-virtual {v1}, Ljava/lang/String;->toLowerCase()Ljava/lang/String;

    move-result-object v1

    .line 62
    invoke-virtual {v0}, Ljava/lang/String;->toLowerCase()Ljava/lang/String;

    move-result-object v0

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

    move-result v0

    if-eqz v0, :cond_1   判断注册码是否正确 如不正确则跳转到 :cond_1 否则往下执行

    .line 64
    const-string v0, "\u6ce8\u518c\u6210\u529f"//“注册成功”

    const/4 v1, 0x0

    invoke-static {p0, v0, v1}, 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

    .line 65
    invoke-virtual {p0}, Lcom/call3/VerifyActivity;->finish()V

    .line 66
    new-instance v0, Landroid/content/Intent;

    const-class v1, Lcom/call3/MainActivity;

    invoke-direct {v0, p0, v1}, Landroid/content/Intent;-><init>(Landroid/content/Context;Ljava/lang/Class;)V

    .line 67
    invoke-virtual {p0, v0}, Lcom/call3/VerifyActivity;->startActivity(Landroid/content/Intent;)V

    .line 68
    iget-object v0, p0, Lcom/call3/VerifyActivity;->e:Landroid/content/SharedPreferences;

    invoke-interface {v0}, Landroid/content/SharedPreferences;->edit()Landroid/content/SharedPreferences$Editor;

    move-result-object v0

    const-string v1, "isRegistered"

    const/4 v2, 0x1

    invoke-interface {v0, v1, v2}, Landroid/content/SharedPreferences$Editor;->putBoolean(Ljava/lang/String;Z)Landroid/content/SharedPreferences$Editor;

    move-result-object v0

    invoke-interface {v0}, Landroid/content/SharedPreferences$Editor;->commit()Z
    :try_end_0
    .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0

    goto :goto_0

    .line 74
    :catch_0
    move-exception v0

    .line 75
    invoke-virtual {v0}, Ljava/lang/Exception;->printStackTrace()V

    goto :goto_0

    .line 71
    :cond_1   //注册失败
    :try_start_1
    const-string v0, "\u60a8\u8f93\u5165\u7684\u6ce8\u518c\u7801\u6709\u8bef\uff0c\u8bf7\u91cd\u65b0\u8f93\u5165" //"输入的注册码有误,请重新输入"

    const/4 v1, 0x0

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

    move-result-object v0

    .line 72
    invoke-virtual {v0}, Landroid/widget/Toast;->show()V
    :try_end_1
    .catch Ljava/lang/Exception; {:try_start_1 .. :try_end_1} :catch_0

    goto :goto_0
.end method


这软件比较简单...所以分析起来也相对容易....
下面我们开始逆向吧


method private a()V
    .locals 3

    .prologue
    const/4 v2, 0x0

    .line 53
    iget-object v0, p0, Lcom/call3/VerifyActivity;->d:Landroid/widget/EditText;

    invoke-virtual {v0}, Landroid/widget/EditText;->getText()Landroid/text/Editable;

    move-result-object v0

    invoke-interface {v0}, Landroid/text/Editable;->toString()Ljava/lang/String;

    move-result-object v0

    invoke-virtual {v0}, Ljava/lang/String;->trim()Ljava/lang/String;

    move-result-object v0

    const-string v1, ""

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

    move-result v0

                        //判断是否有输入注册码如有输入则跳转到:cond_0 否则往下执行
                           
                     //我们发现这里就是关键判断...只要我们不让其跳转到 :cond_0 就能实现破解...那么我们就直接把 if-eqz v0, :cond_0这个判断删除吧

    .line 54
    const-string v0, "\u8bf7\u8f93\u5165\u6ce8\u518c\u7801" //"请输入注册码"

    invoke-static {p0, v0, v2}, 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

    .line 79
    :goto_0
    return-void

    .line 59
    :cond_0
    :try_start_0
    iget-object v0, p0, Lcom/call3/VerifyActivity;->c:Landroid/widget/TextView;

    invoke-virtual {v0}, Landroid/widget/TextView;->getText()Ljava/lang/CharSequence;

    move-result-object v0

    invoke-interface {v0}, Ljava/lang/CharSequence;->toString()Ljava/lang/String;

    move-result-object v0

    invoke-virtual {v0}, Ljava/lang/String;->toLowerCase()Ljava/lang/String;

    move-result-object v0

    .line 58
    invoke-static {v0}, Lcom/call3/DESUtil;->encryptDES(Ljava/lang/String;)Ljava/lang/String;

    move-result-object v0

    .line 59
    const/4 v1, 0x0

    .line 60
    const/4 v2, 0x6

    .line 59
    invoke-virtual {v0, v1, v2}, Ljava/lang/String;->substring(II)Ljava/lang/String;

    move-result-object v0

    .line 61
    iget-object v1, p0, Lcom/call3/VerifyActivity;->d:Landroid/widget/EditText;

    invoke-virtual {v1}, Landroid/widget/EditText;->getText()Landroid/text/Editable;

    move-result-object v1

    invoke-interface {v1}, Landroid/text/Editable;->toString()Ljava/lang/String;

    move-result-object v1

    invoke-virtual {v1}, Ljava/lang/String;->trim()Ljava/lang/String;

    move-result-object v1

    invoke-virtual {v1}, Ljava/lang/String;->toLowerCase()Ljava/lang/String;

    move-result-object v1

    .line 62
    invoke-virtual {v0}, Ljava/lang/String;->toLowerCase()Ljava/lang/String;

    move-result-object v0

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

    move-result v0

    if-eqz v0, :cond_1   判断注册码是否正确 如不正确则跳转到 :cond_1 否则往下执行

    .line 64
    const-string v0, "\u6ce8\u518c\u6210\u529f"//“注册成功”

    const/4 v1, 0x0

    invoke-static {p0, v0, v1}, 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

    .line 65
    invoke-virtual {p0}, Lcom/call3/VerifyActivity;->finish()V

    .line 66
    new-instance v0, Landroid/content/Intent;

    const-class v1, Lcom/call3/MainActivity;

    invoke-direct {v0, p0, v1}, Landroid/content/Intent;-><init>(Landroid/content/Context;Ljava/lang/Class;)V

    .line 67
    invoke-virtual {p0, v0}, Lcom/call3/VerifyActivity;->startActivity(Landroid/content/Intent;)V

    .line 68
    iget-object v0, p0, Lcom/call3/VerifyActivity;->e:Landroid/content/SharedPreferences;

    invoke-interface {v0}, Landroid/content/SharedPreferences;->edit()Landroid/content/SharedPreferences$Editor;

    move-result-object v0

    const-string v1, "isRegistered"

    const/4 v2, 0x1

    invoke-interface {v0, v1, v2}, Landroid/content/SharedPreferences$Editor;->putBoolean(Ljava/lang/String;Z)Landroid/content/SharedPreferences$Editor;

    move-result-object v0

    invoke-interface {v0}, Landroid/content/SharedPreferences$Editor;->commit()Z
    :try_end_0
    .catch Ljava/lang/Exception; {:try_start_0 .. :try_end_0} :catch_0

    goto :goto_0

    .line 74
    :catch_0
    move-exception v0

    .line 75
    invoke-virtual {v0}, Ljava/lang/Exception;->printStackTrace()V

    goto :goto_0

    .line 71
    :cond_1   //注册失败
    :try_start_1
    const-string v0, "\u60a8\u8f93\u5165\u7684\u6ce8\u518c\u7801\u6709\u8bef\uff0c\u8bf7\u91cd\u65b0\u8f93\u5165" //"输入的注册码有误,请重新输入"

    const/4 v1, 0x0

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

    move-result-object v0

    .line 72
    invoke-virtual {v0}, Landroid/widget/Toast;->show()V
    :try_end_1
    .catch Ljava/lang/Exception; {:try_start_1 .. :try_end_1} :catch_0

    goto :goto_0
.end method
OK 修改完毕...咱们在修改保存,重新编译,签名,出来测试下吧


成品:http://www.52pojie.cn/thread-253938-1-1.html

无颜君〃 发表于 2014-4-24 14:52

楼主会JAVA?他这个有电脑端的,不过是JAR的。我不会追JAR,据说很简单。。反编译即可,,

sdzzb 发表于 2014-4-25 16:39

    if (this.e.getBoolean("isRegistered", false))//直接把这个判断删除,直接进入,可以试试
      startActivity(new Intent(this, MainActivity.class));

340421535 发表于 2014-4-24 14:53

貌似很厉害的

诸葛213 发表于 2014-4-24 14:54

感谢分享 回头自己也试试

OllyDbg丶 发表于 2014-4-24 16:59

谢谢老师分享,已经下载了,看完老师的分析受益匪浅

vipcrack 发表于 2014-4-24 17:43

是个DES算法,代码里应该能找到KEY,然后计算机器码的DES结果就应该是注册码了。

TinyTroopers 发表于 2014-4-24 19:05

好强大的样子,但我不知道这个软件是干什么的

哭泣的疼痛 发表于 2014-4-24 19:45

这么叼 看看

shark、小亮 发表于 2014-4-24 20:29

我来看看啊。。

齐德龙 发表于 2014-4-24 23:07

无颜君〃 发表于 2014-4-24 14:52
楼主会JAVA?他这个有电脑端的,不过是JAR的。我不会追JAR,据说很简单。。反编译即可,,

直接JD-GUI + Java ByteCode Editor
页: [1] 2 3 4 5 6
查看完整版本: 超强call3正式版 的简单分析