本帖最后由 吾爱扣扣 于 2014-8-18 20:51 编辑
将CM载入APK改之理后直接冲到res/values/strings.xml,看作者有没有把关键信息存放在这。 [XML] 纯文本查看 复制代码 <?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Crack Me</string>
<string name="hello_world">这是我用Eclipse编写的第一个App</string>
<string name="action_settings">退出</string>
<string name="tip">请输入注册码</string>
<string name="s1">注册码</string>
<string name="s2">注册</string>
<string name="footer">Written by 吾爱扣扣 2014.8.18</string>
</resources>
结果什么也没找到,于是就奔向smali/com/example/crackme/MainActivity$1.smali(这里要注意,作者自己添加的函数在MainActivity.smali是找不到的)。
发现了关键的代码 [Java] 纯文本查看 复制代码 method public onClick(Landroid/view/View;)V
显然,下面就是按钮事件的内容了~我们往下找 [Java] 纯文本查看 复制代码 .method public onClick(Landroid/view/View;)V
.locals 2
.param p1, "v" # Landroid/view/View;
.prologue
.line 30
iget-object v0, p0, Lcom/example/crackme/MainActivity$1;->this$0:Lcom/example/crackme/MainActivity;
# getter for: Lcom/example/crackme/MainActivity;->zcm:Landroid/widget/EditText;
invoke-static {v0}, Lcom/example/crackme/MainActivity;->access$0(Lcom/example/crackme/MainActivity;)Landroid/widget/EditText;
move-result-object v0
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
iput-object v0, p0, Lcom/example/crackme/MainActivity$1;->regcode:Ljava/lang/String;
.line 31
iget-object v0, p0, Lcom/example/crackme/MainActivity$1;->regcode:Ljava/lang/String;
const-string v1, "\u5199\u4e2aCM\u90fd\u5f88\u96be\u554a"
invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v0
if-eqz v0, :cond_0
.line 32
new-instance v0, Landroid/app/AlertDialog$Builder;
iget-object v1, p0, Lcom/example/crackme/MainActivity$1;->this$0:Lcom/example/crackme/MainActivity;
invoke-direct {v0, v1}, Landroid/app/AlertDialog$Builder;-><init>(Landroid/content/Context;)V
.line 33
const-string v1, "\u63d0\u793a"
invoke-virtual {v0, v1}, Landroid/app/AlertDialog$Builder;->setTitle(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;
move-result-object v0
.line 34
const-string v1, "\u6ce8\u518c\u6210\u529f\uff01"
invoke-virtual {v0, v1}, Landroid/app/AlertDialog$Builder;->setMessage(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;
move-result-object v0
.line 35
invoke-virtual {v0}, Landroid/app/AlertDialog$Builder;->show()Landroid/app/AlertDialog;
.line 42
:goto_0
return-void
.line 37
:cond_0
new-instance v0, Landroid/app/AlertDialog$Builder;
iget-object v1, p0, Lcom/example/crackme/MainActivity$1;->this$0:Lcom/example/crackme/MainActivity;
invoke-direct {v0, v1}, Landroid/app/AlertDialog$Builder;-><init>(Landroid/content/Context;)V
.line 38
const-string v1, "\u63d0\u793a"
invoke-virtual {v0, v1}, Landroid/app/AlertDialog$Builder;->setTitle(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;
move-result-object v0
.line 39
const-string v1, "\u6ce8\u518c\u5931\u8d25\uff01"
invoke-virtual {v0, v1}, Landroid/app/AlertDialog$Builder;->setMessage(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;
move-result-object v0
.line 40
invoke-virtual {v0}, Landroid/app/AlertDialog$Builder;->show()Landroid/app/AlertDialog;
goto :goto_0
.end method
悲惨的发现字符串不是中文,而是Unicode编码,我们Ctrl+A全选,然后右键选择“转换为ASCII”。哈哈,这下字符串就变成我们能看懂的中文了! [Java] 纯文本查看 复制代码 # virtual methods
.method public onClick(Landroid/view/View;)V
.locals 2
.param p1, "v" # Landroid/view/View;
.prologue
.line 30
iget-object v0, p0, Lcom/example/crackme/MainActivity$1;->this$0:Lcom/example/crackme/MainActivity;
# getter for: Lcom/example/crackme/MainActivity;->zcm:Landroid/widget/EditText;
invoke-static {v0}, Lcom/example/crackme/MainActivity;->access$0(Lcom/example/crackme/MainActivity;)Landroid/widget/EditText;
move-result-object v0
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
iput-object v0, p0, Lcom/example/crackme/MainActivity$1;->regcode:Ljava/lang/String;
.line 31
iget-object v0, p0, Lcom/example/crackme/MainActivity$1;->regcode:Ljava/lang/String;
const-string v1, "写个CM都很难啊"
invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v0
if-eqz v0, :cond_0
.line 32
new-instance v0, Landroid/app/AlertDialog$Builder;
iget-object v1, p0, Lcom/example/crackme/MainActivity$1;->this$0:Lcom/example/crackme/MainActivity;
invoke-direct {v0, v1}, Landroid/app/AlertDialog$Builder;-><init>(Landroid/content/Context;)V
.line 33
const-string v1, "提示"
invoke-virtual {v0, v1}, Landroid/app/AlertDialog$Builder;->setTitle(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;
move-result-object v0
.line 34
const-string v1, "注册成功!"
invoke-virtual {v0, v1}, Landroid/app/AlertDialog$Builder;->setMessage(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;
move-result-object v0
.line 35
invoke-virtual {v0}, Landroid/app/AlertDialog$Builder;->show()Landroid/app/AlertDialog;
.line 42
:goto_0
return-void
.line 37
:cond_0
new-instance v0, Landroid/app/AlertDialog$Builder;
iget-object v1, p0, Lcom/example/crackme/MainActivity$1;->this$0:Lcom/example/crackme/MainActivity;
invoke-direct {v0, v1}, Landroid/app/AlertDialog$Builder;-><init>(Landroid/content/Context;)V
.line 38
const-string v1, "提示"
invoke-virtual {v0, v1}, Landroid/app/AlertDialog$Builder;->setTitle(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;
move-result-object v0
.line 39
const-string v1, "注册失败!"
invoke-virtual {v0, v1}, Landroid/app/AlertDialog$Builder;->setMessage(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;
move-result-object v0
.line 40
invoke-virtual {v0}, Landroid/app/AlertDialog$Builder;->show()Landroid/app/AlertDialog;
goto :goto_0
.end method
但是仅仅是这样还不够,我们想要更直观的查看按钮事件还得转换为JAVA代码才行,找到菜单“编辑”->“打开JAVA源码”。
打开后我们选择com.example.crackme/MainActivity,这样就一目了然了~ [Java] 纯文本查看 复制代码 package com.example.crackme;
import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.os.Bundle;
import android.text.Editable;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends Activity
{
private Button btnDo;
private View.OnClickListener btnDoListener = new View.OnClickListener()
{
String regcode;
public void onClick(View paramAnonymousView)
{
this.regcode = MainActivity.this.zcm.getText().toString(); //将编辑框的注册码赋值给变量regcode
if (this.regcode.equals("写个CM都很难啊")) //如果regcode等于"写个CM都很难啊"则继续执行下面的代码
{
new AlertDialog.Builder(MainActivity.this).setTitle("提示").setMessage("注册成功!").show();
return; //执行完毕后返回
}
new AlertDialog.Builder(MainActivity.this).setTitle("提示").setMessage("注册失败!").show(); //注册码不正确则执行这部分
}
};
成功找到注册码:写个CM都很难啊 接下来爆破,由于jd-gui反编译smali为java并不能修改代码,只能查看源码而已。所以我们返回APK改之理,打算直接从smali下手。
这里要了解一下基本的概念 Dalvik 是Google 公司自己设计用于Android 平台的Java 虚拟机,而安卓程序要运行在手机上必须依赖安卓手机系统上的Dalvik 虚拟机,相当于Win 平台上JAVA 程序必须依赖JRE 。而Smali则是指Android平台里的Java虚拟机(Dalvik)所使用的一种语言。
以上是我在查看相关文献之后的个人见解,如有误请指出。
找到关键部分 [Java] 纯文本查看 复制代码 iget-object v0, p0, Lcom/example/crackme/MainActivity$1;->regcode:Ljava/lang/String; //将假码以字符串的形式存放到v0
const-string v1, "写个CM都很难啊" //将真码储存到v1寄存器里
invoke-virtual {v0, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z //判断假码与真码是否相等
move-result v0 //将判断结果存放到v0寄存器里
if-eqz v0, :cond_0 //如果v0=0,也就是如果相等则提示成功,这里我们将eqz改为nez即可达到爆破目的
.line 32
new-instance v0, Landroid/app/AlertDialog$Builder;
iget-object v1, p0, Lcom/example/crackme/MainActivity$1;->this$0:Lcom/example/crackme/MainActivity;
invoke-direct {v0, v1}, Landroid/app/AlertDialog$Builder;-><init>(Landroid/content/Context;)V
.line 33
const-string v1, "提示"
invoke-virtual {v0, v1}, Landroid/app/AlertDialog$Builder;->setTitle(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;
move-result-object v0
.line 34
const-string v1, "注册成功!"
invoke-virtual {v0, v1}, Landroid/app/AlertDialog$Builder;->setMessage(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;
move-result-object v0
.line 35
invoke-virtual {v0}, Landroid/app/AlertDialog$Builder;->show()Landroid/app/AlertDialog;
.line 42
:goto_0
return-void
.line 37
:cond_0
new-instance v0, Landroid/app/AlertDialog$Builder;
iget-object v1, p0, Lcom/example/crackme/MainActivity$1;->this$0:Lcom/example/crackme/MainActivity;
invoke-direct {v0, v1}, Landroid/app/AlertDialog$Builder;-><init>(Landroid/content/Context;)V
.line 38
const-string v1, "提示"
invoke-virtual {v0, v1}, Landroid/app/AlertDialog$Builder;->setTitle(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;
move-result-object v0
.line 39
const-string v1, "注册失败!"
invoke-virtual {v0, v1}, Landroid/app/AlertDialog$Builder;->setMessage(Ljava/lang/CharSequence;)Landroid/app/AlertDialog$Builder;
move-result-object v0
.line 40
invoke-virtual {v0}, Landroid/app/AlertDialog$Builder;->show()Landroid/app/AlertDialog;
goto :goto_0
然后记得一定要先保存再编译,不然编译出来还是修改前的。
最后附上一张Smali条件跳转分支表供大家参考: "if-eq vA, vB,:cond_**" 如果vA等于vB则跳转到:cond_**
"if-ne vA, vB, :cond_**" 如果vA不等于vB则跳转到:cond_**
"if-lt vA, vB, :cond_**" 如果vA小于vB则跳转到:cond_**
"if-ge vA, vB, :cond_**" 如果vA大于等于vB则跳转到:cond_**
"if-gt vA, vB, :cond_**" 如果vA大于vB则跳转到:cond_**
"if-le vA, vB, :cond_**" 如果vA小于等于vB则跳转到:cond_**
"if-eqz vA, :cond_**" 如果vA等于0则跳转到:cond_**
"if-nez vA, :cond_**" 如果vA不等于0则跳转到:cond_**
"if-ltz vA, :cond_**" 如果vA小于0则跳转到:cond_**
"if-gez vA, :cond_**" 如果vA大于等于0则跳转到:cond_**
"if-gtz vA, :cond_**" 如果vA大于0则跳转到:cond_**
"if-lez vA, :cond_**" 如果vA小于等于0则跳转到:cond_**
很长时间以来,Dalvik虚拟机一直被用户指责为拖慢安卓系统运行速度不如IOS的根源。 2014年6月25日,Android L 将正式亮相于召开的谷歌I/O大会,Android L 改动幅度较大,谷歌将直接删除Dalvik,代替它的是传闻已久的ART。
那时候可能真的是安卓程序员的出头之日了!安卓也不会这么容易被 破解了吧?
最后附上Word版的破文
史上最简单的安卓CM追码和爆破.rar
(19.57 KB, 下载次数: 54)
|