标 题: Android逆向入门之for循环
作 者: 0x明天去要饭
时 间: 2013-10-28 19:40:00
链 接:
http://bbs.pediy.com/showthread.php?t=168001
原 文:
http://www.sanwho.com/203.html
本文是我学习过程中的一点记录,属于入门级知识,相信对于新手来说有一定的帮助,若发现错误请及时指正,感谢jack_jia大牛的指导,谢谢!
一、效果展示
起始数值处的文本框id为txtValue1,结束数值处的文本框id为txtValue2。
二、Java源代码
Java源文件名为ForActivity.java,核心代码如下:
Button.OnClickListener onClickListener = new Button.OnClickListener()
{
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.btnSubmit:
EditText txtValue1 = (EditText) findViewById(R.id.txtValue1);
EditText txtValue2 = (EditText) findViewById(R.id.txtValue2);
int from = Integer.parseInt(txtValue1.getText().toString());
int end = Integer.parseInt(txtValue2.getText().toString());
if (from > end)
{
MessageBox("起始数值不能大于结束数值!");
}
else
{
int sum = 0;
for (int i = from; i <= end; i++)
{
StringBuilder ss;
sum += i;
}
MessageBox("累加结果:" + Integer.toString(sum));
}
break;
}
}
};
/*
* 弹出提示
*/
private void MessageBox(String str)
{
Toast.makeText(this, str, Toast.LENGTH_LONG).show();
}
三、反编译成java
通过反编译可以发现:
1、 反编译出来的switch语句默认会添加default选项进行处理;
2、 for循环将转换成使用if语句进行判断,源码中i <= end的判断将转换成m>j这种判断方式;
3、 反编译后得到的java代码与源代码几乎一样。
四、反编译成.smali
反编译后会得到两个文件,一个为ForActivity.smali,一个为ForActivity$1.smali,核心代码在ForActivity$1.smali这个文件中,详细分析如下:
# virtual methods
.method public onClick(Landroid/view/View;)V
.locals 9
.parameter “v”
.prologue
.line 36
invoke-virtual {p1}, Landroid/view/View;->getId()I # p0为this指针, p1为第一个参数, 即View对象
move-result v6 # v6=p1.getId(), v6中为View对象的id
packed-switch v6, :pswitch_data_0 # switch(v6)
# —————– 程序出口开始 ——————
.line 58
:goto_0 # for循环出口
return-void # return;
# —————– 程序出口结束 ——————
# —————– 获取控件内容开始 ——————
.line 39
:pswitch_0
iget-object v6, p0, Lcom/sanwho/crackdemo/ForActivity$1;->this$0:Lcom/sanwho/crackdemo/ForActivity; # v6保存this指针
const v7, 0x7f080001 # v7 = txtValue1, 该id保存在public.xml中
invoke-virtual {v6, v7}, Lcom/sanwho/crackdemo/ForActivity;->findViewById(I)Landroid/view/View; # findViewById(txtValue1)
move-result-object v4 # v4为txtValue1对应的View对象
check-cast v4, Landroid/widget/EditText; # 将View对象转换成EditText, 完成后v4中是txtValue1对象, 失败会抛出ClassCastException异常
.line 40
.local v4, txtValue1:Landroid/widget/EditText;
iget-object v6, p0, Lcom/sanwho/crackdemo/ForActivity$1;->this$0:Lcom/sanwho/crackdemo/ForActivity;
const v7, 0x7f080003 # v7 = txtValue2
invoke-virtual {v6, v7}, Lcom/sanwho/crackdemo/ForActivity;->findViewById(I)Landroid/view/View;
move-result-object v5 # v5为txtValue2对应的View对象
check-cast v5, Landroid/widget/EditText; # 将View对象转换成EditText, 完成后v5中是txtValue2对象
.line 41
.local v5, txtValue2:Landroid/widget/EditText;
invoke-virtual {v4}, Landroid/widget/EditText;->getText()Landroid/text/Editable; # 根据.line 39处可知,v4中为txtValue1对象
move-result-object v6 # v6 = txtValue1.getText();
invoke-interface {v6}, Landroid/text/Editable;->toString()Ljava/lang/String;
move-result-object v6 # v6 = txtValue1.getText().toString();
invoke-static {v6}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I
move-result v1 # v1 = Integer.parseInt(v6); 也就是起始数值
.line 42
.local v1, from:I
invoke-virtual {v5}, Landroid/widget/EditText;->getText()Landroid/text/Editable; # 根据.line 40处可知,v5中为txtValue2对象
move-result-object v6 # v6 = txtValue2.getText();
invoke-interface {v6}, Landroid/text/Editable;->toString()Ljava/lang/String;
move-result-object v6 # v6 = txtValue2.getText().toString();
invoke-static {v6}, Ljava/lang/Integer;->parseInt(Ljava/lang/String;)I
move-result v0 # v0 = Integer.parseInt(v6); 也就是结束数值
# —————– 获取控件内容结束 ——————
.line 43
.local v0, end:I
if-le v1, v0, :cond_0 # if v1 <= v0, 即起始数值 <= 结束数值, 则跳到cond_0
# —————– 起始数值 > 结束数值时开始 ——————
.line 45
iget-object v6, p0, Lcom/sanwho/crackdemo/ForActivity$1;->this$0:Lcom/sanwho/crackdemo/ForActivity;
const-string v7, “\u8d77\u59cb\u6570\u503c\u4e0d\u80fd\u5927\u4e8e\u7ed3\u675f\u6570\u503c!” # 起始数值不能大于结束数值
#calls: Lcom/sanwho/crackdemo/ForActivity;->MessageBox(Ljava/lang/String;)V
invoke-static {v6, v7}, Lcom/sanwho/crackdemo/ForActivity;->access$0(Lcom/sanwho/crackdemo/ForActivity;Ljava/lang/String;)V
goto :goto_0
# —————– 起始数值 > 结束数值时结束 ——————
# —————– 起始数值 <= 结束数值时开始 —————–
.line 49
:cond_0
const/4 v3, 0×0 # v3 = 0, 即int sum = 0;
.line 50
.local v3, sum:I
move v2, v1 # v2 = v1, v2即源码中的i变量
.local v2, i:I
:goto_1 # for循环主要入口
if-le v2, v0, :cond_1 # if 当前数值 <= 结束数值, 跳到cond_1; 否则循环结束, 显示累加结果
.line 54
iget-object v6, p0, Lcom/sanwho/crackdemo/ForActivity$1;->this$0:Lcom/sanwho/crackdemo/ForActivity; # v6指向MessageBox方法
new-instance v7, Ljava/lang/StringBuilder; # v7为StringBuilder对象
const-string v8, “\u7d2f\u52a0\u7ed3\u679c\uff1a” # v8 = “累加结果:”
invoke-direct {v7, v8}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V # 以v8为参数调用StringBuilder构造函数
invoke-static {v3}, Ljava/lang/Integer;->toString(I)Ljava/lang/String; # 把int型的sum值转成字符串
move-result-object v8 # v8 = Integer.toString(v3); 此时v8中为sum的值
invoke-virtual {v7, v8}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; # 把累加结果和sum的值进行追加
move-result-object v7 # v7 为 “累加结果:” + Integer.toString(sum)的StringBuilder对象;
invoke-virtual {v7}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; # 将v7转为字符串对象
move-result-object v7 # v7 = “累加结果:” + Integer.toString(sum);
#calls: Lcom/sanwho/crackdemo/ForActivity;->MessageBox(Ljava/lang/String;)V
invoke-static {v6, v7}, Lcom/sanwho/crackdemo/ForActivity;->access$0(Lcom/sanwho/crackdemo/ForActivity;Ljava/lang/String;)V # 调用MessageBox显示字符串
goto :goto_0 # 跳到goto_0
# —————– 起始数值 <= 结束数值时结束 —————–
.line 52
:cond_1 # 加1操作入口
add-int/2addr v3, v2 # v3 = v3 + v2, 即sum += i
.line 50
add-int/lit8 v2, v2, 0×1 # v2 = v2 + 1, , 即i = i + 1
goto :goto_1 # 跳到for循环入口继续比对
.line 36
nop
:pswitch_data_0
.packed-switch 0x7f080004
:pswitch_0
.end packed-switch
.end method
相关源码下载:
android逆向之for循环.zip
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课