-
-
[原创]Android逆向入门之switch
-
发表于: 2013-10-30 09:52 6805
-
标 题: Android逆向入门之switch
作 者: 0x明天去要饭
时 间: 2013-10-30 9:50:00
链 接: http://bbs.pediy.com/showthread.php?p=1235203
原 文: http://www.sanwho.com/229.html(带语法着色)
一、效果展示
密钥处的文本框id为txtValue,程序将根据输入密钥的长度判断注册是否成功(为演示方便所以挑了非常简单的注册算法),密钥有8位、12位、16位、20位4种,分别对应标准版、专业版、企业版、旗舰版。
二、Java源代码
Java源文件名为SwitchActivity.java,核心代码如下:
Button.OnClickListener onClickListener = new Button.OnClickListener()
{
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.btnSubmit:
EditText txtValue = (EditText) findViewById(R.id.txtValue);
int len = txtValue.getText().toString().length();
switch (len)
{
case 8:
MessageBox("注册码有效, 适用于标准版");
break;
case 12:
MessageBox("注册码有效, 适用于专业版");
break;
case 16:
MessageBox("注册码有效, 适用于企业版");
break;
case 20:
MessageBox("注册码有效, 适用于旗舰版");
break;
default:
MessageBox("注册码无效!");
break;
}
break;
}
}
};
/*
* 弹出提示
*/
private void MessageBox(String str)
{
Toast.makeText(this, str, Toast.LENGTH_LONG).show();
}
三、反编译成java
通过反编译可以发现:
反编译出来的switch语句在结构解析上存在一点问题,但是基本不影响阅读。
四、反编译成.smali
反编译后会得到两个文件,一个为SwitchActivity.smali,一个为SwitchActivity$1.smali,核心代码在SwitchActivity$1.smali这个文件中,详细分析如下:
# onClick方法
.method public onClick(Landroid/view/View;)V
.locals 4
.parameter “v”
.prologue
.line 37
invoke-virtual {p1}, Landroid/view/View;->getId()I
move-result v2 # v2 = p1.getId();
packed-switch v2, :pswitch_data_0 # switch(v2), 通过pswitch_data_0进行匹配
#———– switch出口开始 ———-
.line 65
:goto_0
return-void
#———– switch出口结束 ———-
.line 40
:pswitch_0 # switch(v2)入口
iget-object v2, p0, Lcom/sanwho/crackdemo/SwitchActivity$1;->this$0:Lcom/sanwho/crackdemo/SwitchActivity;
const v3, 0x7f080008 # txtValue Id
invoke-virtual {v2, v3}, Lcom/sanwho/crackdemo/SwitchActivity;->findViewById(I)Landroid/view/View;
move-result-object v1 # v1为txtValue的View对象;
check-cast v1, Landroid/widget/EditText; # 把txtValue转换成EditText对象
.line 41
.local v1, txtValue:Landroid/widget/EditText;
invoke-virtual {v1}, Landroid/widget/EditText;->getText()Landroid/text/Editable;
move-result-object v2 # v2 = txtValue.getText();
invoke-interface {v2}, Landroid/text/Editable;->toString()Ljava/lang/String;
move-result-object v2 # v2 = txtValue.getText().toString();
invoke-virtual {v2}, Ljava/lang/String;->length()I
move-result v0 # v0 = txtValue.getText().toString().length();
.line 42
.local v0, len:I
sparse-switch v0, :sswitch_data_0 # switch(v0), 通过sswitch_data_0表进行匹配
# —– default开始 —–
.line 60
iget-object v2, p0, Lcom/sanwho/crackdemo/SwitchActivity$1;->this$0:Lcom/sanwho/crackdemo/SwitchActivity;
const-string v3, “\u6ce8\u518c\u7801\u65e0\u6548!” # 注册码无效
#calls: Lcom/sanwho/crackdemo/SwitchActivity;->MessageBox(Ljava/lang/String;)V
# SwitchActivity.MessageBox(“注册码无效”);
invoke-static {v2, v3}, Lcom/sanwho/crackdemo/SwitchActivity;->access$0(Lcom/sanwho/crackdemo/SwitchActivity;Ljava/lang/String;)V
goto :goto_0
# —– default结束 —–
# —– case 8开始 —–
.line 45
:sswitch_0 # 对应sparse-switch表中的第一项, 即8
iget-object v2, p0, Lcom/sanwho/crackdemo/SwitchActivity$1;->this$0:Lcom/sanwho/crackdemo/SwitchActivity;
const-string v3, “\u6ce8\u518c\u7801\u6709\u6548, \u9002\u7528\u4e8e\u6807\u51c6\u7248″ # 注册码有效, 适用于标准版
#calls: Lcom/sanwho/crackdemo/SwitchActivity;->MessageBox(Ljava/lang/String;)V
# SwitchActivity.MessageBox(“注册码有效, 适用于标准版”);
invoke-static {v2, v3}, Lcom/sanwho/crackdemo/SwitchActivity;->access$0(Lcom/sanwho/crackdemo/SwitchActivity;Ljava/lang/String;)V
goto :goto_0
# —– case 8结束 —–
# —– case 12开始 —–
.line 49
:sswitch_1 # 对应sparse-switch表中的第二项, 即12
iget-object v2, p0, Lcom/sanwho/crackdemo/SwitchActivity$1;->this$0:Lcom/sanwho/crackdemo/SwitchActivity;
const-string v3, “\u6ce8\u518c\u7801\u6709\u6548, \u9002\u7528\u4e8e\u4e13\u4e1a\u7248″ # 注册码有效, 适用于专业版
#calls: Lcom/sanwho/crackdemo/SwitchActivity;->MessageBox(Ljava/lang/String;)V
# SwitchActivity.MessageBox(“注册码有效, 适用于专业版”);
invoke-static {v2, v3}, Lcom/sanwho/crackdemo/SwitchActivity;->access$0(Lcom/sanwho/crackdemo/SwitchActivity;Ljava/lang/String;)V
goto :goto_0
# —– case 12结束 —–
# —– case 16开始 —–
.line 53
:sswitch_2 # 对应sparse-switch表中的第三项, 即16
iget-object v2, p0, Lcom/sanwho/crackdemo/SwitchActivity$1;->this$0:Lcom/sanwho/crackdemo/SwitchActivity;
const-string v3, “\u6ce8\u518c\u7801\u6709\u6548, \u9002\u7528\u4e8e\u4f01\u4e1a\u7248″ # 注册码有效, 适用于企业版
#calls: Lcom/sanwho/crackdemo/SwitchActivity;->MessageBox(Ljava/lang/String;)V
# SwitchActivity.MessageBox(“注册码有效, 适用于企业版”);
invoke-static {v2, v3}, Lcom/sanwho/crackdemo/SwitchActivity;->access$0(Lcom/sanwho/crackdemo/SwitchActivity;Ljava/lang/String;)V
goto :goto_0
# —– case 16结束 —–
# —– case 20开始 —–
.line 57
:sswitch_3 # 对应sparse-switch表中的第四项, 即20
iget-object v2, p0, Lcom/sanwho/crackdemo/SwitchActivity$1;->this$0:Lcom/sanwho/crackdemo/SwitchActivity;
const-string v3, “\u6ce8\u518c\u7801\u6709\u6548, \u9002\u7528\u4e8e\u65d7\u8230\u7248″ # 注册码有效, 适用于旗舰版
#calls: Lcom/sanwho/crackdemo/SwitchActivity;->MessageBox(Ljava/lang/String;)V
# SwitchActivity.MessageBox(“注册码有效, 适用于旗舰版”);
invoke-static {v2, v3}, Lcom/sanwho/crackdemo/SwitchActivity;->access$0(Lcom/sanwho/crackdemo/SwitchActivity;Ljava/lang/String;)V
goto :goto_0
# —– case 20结束 —–
# —– 第一重switch表开始 —–
.line 37
:pswitch_data_0
.packed-switch 0x7f080004
:pswitch_0
.end packed-switch
# —– 第一重switch表结束 —–
# —– 第二重switch表开始 —–
.line 42
:sswitch_data_0
.sparse-switch
0×8 -> :sswitch_0 # case(8), 跳到sswitch_0
0xc -> :sswitch_1 # case(12), 跳到sswitch_1
0×10 -> :sswitch_2 # case(16), 跳到sswitch_2
0×14 -> :sswitch_3 # case(20), 跳到sswitch_3
.end sparse-switch
# —– 第二重switch表结束 —–
.end method
相关文件下载: android逆向入门之switch.rar
作 者: 0x明天去要饭
时 间: 2013-10-30 9:50:00
链 接: http://bbs.pediy.com/showthread.php?p=1235203
原 文: http://www.sanwho.com/229.html(带语法着色)
一、效果展示
密钥处的文本框id为txtValue,程序将根据输入密钥的长度判断注册是否成功(为演示方便所以挑了非常简单的注册算法),密钥有8位、12位、16位、20位4种,分别对应标准版、专业版、企业版、旗舰版。
二、Java源代码
Java源文件名为SwitchActivity.java,核心代码如下:
Button.OnClickListener onClickListener = new Button.OnClickListener()
{
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.btnSubmit:
EditText txtValue = (EditText) findViewById(R.id.txtValue);
int len = txtValue.getText().toString().length();
switch (len)
{
case 8:
MessageBox("注册码有效, 适用于标准版");
break;
case 12:
MessageBox("注册码有效, 适用于专业版");
break;
case 16:
MessageBox("注册码有效, 适用于企业版");
break;
case 20:
MessageBox("注册码有效, 适用于旗舰版");
break;
default:
MessageBox("注册码无效!");
break;
}
break;
}
}
};
/*
* 弹出提示
*/
private void MessageBox(String str)
{
Toast.makeText(this, str, Toast.LENGTH_LONG).show();
}
三、反编译成java
通过反编译可以发现:
反编译出来的switch语句在结构解析上存在一点问题,但是基本不影响阅读。
四、反编译成.smali
反编译后会得到两个文件,一个为SwitchActivity.smali,一个为SwitchActivity$1.smali,核心代码在SwitchActivity$1.smali这个文件中,详细分析如下:
# onClick方法
.method public onClick(Landroid/view/View;)V
.locals 4
.parameter “v”
.prologue
.line 37
invoke-virtual {p1}, Landroid/view/View;->getId()I
move-result v2 # v2 = p1.getId();
packed-switch v2, :pswitch_data_0 # switch(v2), 通过pswitch_data_0进行匹配
#———– switch出口开始 ———-
.line 65
:goto_0
return-void
#———– switch出口结束 ———-
.line 40
:pswitch_0 # switch(v2)入口
iget-object v2, p0, Lcom/sanwho/crackdemo/SwitchActivity$1;->this$0:Lcom/sanwho/crackdemo/SwitchActivity;
const v3, 0x7f080008 # txtValue Id
invoke-virtual {v2, v3}, Lcom/sanwho/crackdemo/SwitchActivity;->findViewById(I)Landroid/view/View;
move-result-object v1 # v1为txtValue的View对象;
check-cast v1, Landroid/widget/EditText; # 把txtValue转换成EditText对象
.line 41
.local v1, txtValue:Landroid/widget/EditText;
invoke-virtual {v1}, Landroid/widget/EditText;->getText()Landroid/text/Editable;
move-result-object v2 # v2 = txtValue.getText();
invoke-interface {v2}, Landroid/text/Editable;->toString()Ljava/lang/String;
move-result-object v2 # v2 = txtValue.getText().toString();
invoke-virtual {v2}, Ljava/lang/String;->length()I
move-result v0 # v0 = txtValue.getText().toString().length();
.line 42
.local v0, len:I
sparse-switch v0, :sswitch_data_0 # switch(v0), 通过sswitch_data_0表进行匹配
# —– default开始 —–
.line 60
iget-object v2, p0, Lcom/sanwho/crackdemo/SwitchActivity$1;->this$0:Lcom/sanwho/crackdemo/SwitchActivity;
const-string v3, “\u6ce8\u518c\u7801\u65e0\u6548!” # 注册码无效
#calls: Lcom/sanwho/crackdemo/SwitchActivity;->MessageBox(Ljava/lang/String;)V
# SwitchActivity.MessageBox(“注册码无效”);
invoke-static {v2, v3}, Lcom/sanwho/crackdemo/SwitchActivity;->access$0(Lcom/sanwho/crackdemo/SwitchActivity;Ljava/lang/String;)V
goto :goto_0
# —– default结束 —–
# —– case 8开始 —–
.line 45
:sswitch_0 # 对应sparse-switch表中的第一项, 即8
iget-object v2, p0, Lcom/sanwho/crackdemo/SwitchActivity$1;->this$0:Lcom/sanwho/crackdemo/SwitchActivity;
const-string v3, “\u6ce8\u518c\u7801\u6709\u6548, \u9002\u7528\u4e8e\u6807\u51c6\u7248″ # 注册码有效, 适用于标准版
#calls: Lcom/sanwho/crackdemo/SwitchActivity;->MessageBox(Ljava/lang/String;)V
# SwitchActivity.MessageBox(“注册码有效, 适用于标准版”);
invoke-static {v2, v3}, Lcom/sanwho/crackdemo/SwitchActivity;->access$0(Lcom/sanwho/crackdemo/SwitchActivity;Ljava/lang/String;)V
goto :goto_0
# —– case 8结束 —–
# —– case 12开始 —–
.line 49
:sswitch_1 # 对应sparse-switch表中的第二项, 即12
iget-object v2, p0, Lcom/sanwho/crackdemo/SwitchActivity$1;->this$0:Lcom/sanwho/crackdemo/SwitchActivity;
const-string v3, “\u6ce8\u518c\u7801\u6709\u6548, \u9002\u7528\u4e8e\u4e13\u4e1a\u7248″ # 注册码有效, 适用于专业版
#calls: Lcom/sanwho/crackdemo/SwitchActivity;->MessageBox(Ljava/lang/String;)V
# SwitchActivity.MessageBox(“注册码有效, 适用于专业版”);
invoke-static {v2, v3}, Lcom/sanwho/crackdemo/SwitchActivity;->access$0(Lcom/sanwho/crackdemo/SwitchActivity;Ljava/lang/String;)V
goto :goto_0
# —– case 12结束 —–
# —– case 16开始 —–
.line 53
:sswitch_2 # 对应sparse-switch表中的第三项, 即16
iget-object v2, p0, Lcom/sanwho/crackdemo/SwitchActivity$1;->this$0:Lcom/sanwho/crackdemo/SwitchActivity;
const-string v3, “\u6ce8\u518c\u7801\u6709\u6548, \u9002\u7528\u4e8e\u4f01\u4e1a\u7248″ # 注册码有效, 适用于企业版
#calls: Lcom/sanwho/crackdemo/SwitchActivity;->MessageBox(Ljava/lang/String;)V
# SwitchActivity.MessageBox(“注册码有效, 适用于企业版”);
invoke-static {v2, v3}, Lcom/sanwho/crackdemo/SwitchActivity;->access$0(Lcom/sanwho/crackdemo/SwitchActivity;Ljava/lang/String;)V
goto :goto_0
# —– case 16结束 —–
# —– case 20开始 —–
.line 57
:sswitch_3 # 对应sparse-switch表中的第四项, 即20
iget-object v2, p0, Lcom/sanwho/crackdemo/SwitchActivity$1;->this$0:Lcom/sanwho/crackdemo/SwitchActivity;
const-string v3, “\u6ce8\u518c\u7801\u6709\u6548, \u9002\u7528\u4e8e\u65d7\u8230\u7248″ # 注册码有效, 适用于旗舰版
#calls: Lcom/sanwho/crackdemo/SwitchActivity;->MessageBox(Ljava/lang/String;)V
# SwitchActivity.MessageBox(“注册码有效, 适用于旗舰版”);
invoke-static {v2, v3}, Lcom/sanwho/crackdemo/SwitchActivity;->access$0(Lcom/sanwho/crackdemo/SwitchActivity;Ljava/lang/String;)V
goto :goto_0
# —– case 20结束 —–
# —– 第一重switch表开始 —–
.line 37
:pswitch_data_0
.packed-switch 0x7f080004
:pswitch_0
.end packed-switch
# —– 第一重switch表结束 —–
# —– 第二重switch表开始 —–
.line 42
:sswitch_data_0
.sparse-switch
0×8 -> :sswitch_0 # case(8), 跳到sswitch_0
0xc -> :sswitch_1 # case(12), 跳到sswitch_1
0×10 -> :sswitch_2 # case(16), 跳到sswitch_2
0×14 -> :sswitch_3 # case(20), 跳到sswitch_3
.end sparse-switch
# —– 第二重switch表结束 —–
.end method
相关文件下载: android逆向入门之switch.rar
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
赞赏
他的文章
看原图
赞赏
雪币:
留言: