1、编写一个验证app给下一位同学。app功能如下:如果用户名和口令输入正确则显示“恭喜你通过验证!”,否则显示“验证失败!”
2、在获得上一位同学编写的app后,争取能够突破用户和口令的验证,让app显示“恭喜你通过验证!”
收到文件,首先用apktool查看文件解包:
输入命令
apktool d app-deBUG.apk -o ./decode -f
\decode\smali\com\example\myapplication
头文件:
注释:
上面这三部分是类似于框架的androID studio 新建activity时的文件头
接下来是声明字段,可以看到有两个EditText
接下来的Virtual method就是方法的具体内容了,我们来分析一下
tips:跳转语句基础
.line 23 iget-object v0, p0, Lcom/example/myapplication/MainActivity$1;->val$editText:LandroID/Widget/EditText; invoke-virtual {v0}, LandroID/Widget/EditText;->getText()LandroID/text/Editable; move-result-object v0 invoke-virtual {v0}, Ljava/lang/Object;->toString()Ljava/lang/String; move-result-object v0
很简单,声明一个EditText,并将getText的值给v0
line24.line 24 .local v0, "user":Ljava/lang/String; iget-object v1, p0, Lcom/example/myapplication/MainActivity$1;->val$editText1:LandroID/Widget/EditText; invoke-virtual {v1}, LandroID/Widget/EditText;->getText()LandroID/text/Editable; move-result-object v1 invoke-virtual {v1}, Ljava/lang/Object;->toString()Ljava/lang/String; move-result-object v1
和line23一样,将输入的值赋给v1
line25.line 25 .local v1, "pwd":Ljava/lang/String; const-string v2, "admin" invoke-virtual {v0, v2}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z move-result v2 const-string v3, "\u7528\u6237\u540d\u6216\u5bc6\u7801\u9519\u8bef\uff01" const-string v4, "" const/4 v5, 0x1 if-eqz v2, :cond_2
unicode转中文:line25这里的pwd是一个string字符串,现在没有被初始化
equals的调用,用来判断V0(输入的值) V2(赋值为admin)是否相等,第三行最后的Z代表类别为Boolean真假
如果相等返回1,不相等返回0,所以最后有个 if-eqz v2, :cond_2,v0和v2不相等(账号错误)的话则跳转到cond_2
这段代码的意思就是判断用户名输入是否为admin,若不是admin,跳转到cond_2
.line 26 const-string v2, "password" invoke-virtual {v1, v2}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z move-result v2 if-eqz v2, :cond_0
line26这里v2被设为password,比较v1(输入)和v2是否相等
和line25同理,如果v1和v2不相等(密码错误)则前往cond_0,如果为真,则执行line27
.line 27 iget-object v2, p0, Lcom/example/myapplication/MainActivity$1;->this$0:Lcom/example/myapplication/MainActivity; const-string v3, "\u606d\u559c\u4f60\u767b\u5f55\u6210\u529f\uff01" invoke-static {v2, v3, v5}, 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 goto :goto_0
unicode转中文:这是用户名和密码都正确的结果,v3被置为输出正确的提示,invoke一个makeText函数输出v3的内容,然后goto_0(结束)
line29-30——cond_0.line 29 :cond_0 invoke-virtual {v1, v4}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z move-result v2 if-eqz v2, :cond_1
这是cond_0的内容,调用equal判断v1是否为空(line25里v4被置为空)
如果判断结果等于0(密码不为空)则跳转到cond_1,否则执行line30的报错提示
.line 30 iget-object v2, p0, Lcom/example/myapplication/MainActivity$1;->this$0:Lcom/example/myapplication/MainActivity; const-string v3, "\u5bc6\u7801\u4e0d\u53ef\u4e3a\u7a7a\uff01" invoke-static {v2, v3, v5}, 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 goto :goto_0
unicode转中文:这是cond_0的结果,即输出“密码不可为空”后退出。
line33——cond_1.line 33 :cond_1 iget-object v2, p0, Lcom/example/myapplication/MainActivity$1;->this$0:Lcom/example/myapplication/MainActivity; invoke-static {v2, v3, v5}, 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 goto :goto_0
cond_1的内容是输出v3的值,因为初始值是“用户名或密码错误”,所以直接输出v3的值即可
line36-37——cond_2.line 36 :cond_2 invoke-virtual {v0, v4}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z move-result v2 if-eqz v2, :cond_3
判断用户名v0是否为空,跳转来自line25的判断,原理同cond_0
如果判断结果等于0(用户名不为空)则跳转到cond_1,否则执行line37的报错提示
.line 37 iget-object v2, p0, Lcom/example/myapplication/MainActivity$1;->this$0:Lcom/example/myapplication/MainActivity; const-string v3, "\u7528\u6237\u540d\u4e0d\u53ef\u4e3a\u7a7a\uff01" invoke-static {v2, v3, v5}, 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 goto :goto_0
unicode转中文:这是cond_2的结果,即输出用户名不可为空后退出。line40——cond_3
.line 40 :cond_3 iget-object v2, p0, Lcom/example/myapplication/MainActivity$1;->this$0:Lcom/example/myapplication/MainActivity; invoke-static {v2, v3, v5}, 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
line42.line 42 :goto_0 return-voID
结束
总结代码分析完毕,大概思路:
判断用户名和密码是否为admin和password
若正确,更改v3的值并输出正确破解提示若错误,判断输入是否为空– 若为空,输出为空的报错
– 若非空,则输出原来的v3值(错误提示)二、更改
思路有很多,因为代码的逻辑有点奇怪,是先判断是否正确再判断是否为空,所以可以把前面的用户名和密码比对字符串都置为空也能实现;又或者,把用户名输错时跳cond_2和密码输错时跳cond_0都设置成永真1,不跳转,那么执行完line27的正确语句后正常结束也能实现。
这里我们尝试永真
.line 25 .local v1, "pwd":Ljava/lang/String; const-string v2, "admin" invoke-virtual {v0, v2}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z move-result v2 const-string v3, "\u7528\u6237\u540d\u6216\u5bc6\u7801\u9519\u8bef\uff01" const-string v4, "" const/4 v5, 0x1 if-ne v2,v2, :cond_2 .line 26 const-string v2, "password" invoke-virtual {v1, v2}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z move-result v2 if-ne v2,v2, :cond_0
将这两处的跳转更改为和自己做对比即可,记得改前先备份,方便回溯
接下来在cmd中用apktool打包,使用命令
apktool b ./decode -o fake.apk -f
意思是选定decode打包编译成fake.apk文件
输入命令:
keytool -genkeypair -keyalg RSA -valIDity 100 -keystore rsa.keystore -alias mykeypair
意思是生成一个使用RSA,有效期100天的rsa.keystore文件,mykeypair用以索引证书链
自定义密钥库口令,随意填写或直接多次回车跳到最后确定选Y结束,最后可以再次回车
以上是内存溢出为你收集整理的Android逆向学习#2全部内容,希望文章能够帮你解决Android逆向学习#2所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)