在第一篇文章结束后 学会使用了ApkTool进行编译apk文件,那么今天就开始分析这些文件
以一个最简单的登陆程序为例子:hello.apk
使用apkTool进行反编译,输入命令: apktool d HelloAndroid.apk -o helloAndroid得到如下资源:
目录说明
- res目录下存放着程序中所有的资源文件
- smali目录下存放了所有反汇编的程序代码
- 这些目录的子目录和开发时时一致的
寻找突破口
- 对于一般的Android程序来说,错误提示通常是指引关键代码的风向标,在错误提示附近一般是程序的核心验证处
- 这些提示的字符串,可能硬编码到源码中,也可能引用自 res/values目录下的string.xml文件
- 以我们上述案列的 用户名或密码错误 在string.xml中找到对应的字符 unsuccess
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="abc_action_mode_done">Done</string> <string name="abc_action_bar_home_description">Navigate home</string> <string name="abc_action_bar_up_description">Navigate up</string> <string name="abc_action_menu_overflow_description">More options</string> <string name="abc_searchview_description_search">Search</string> <string name="abc_searchview_description_query">Search query</string> <string name="abc_searchview_description_clear">Clear query</string> <string name="abc_searchview_description_submit">Submit query</string> <string name="abc_searchview_description_voice">Voice search</string> <string name="abc_activitychooserview_choose_application">Choose an app</string> <string name="abc_activity_chooser_view_see_all">See all</string> <string name="abc_shareactionprovider_share_with_application">Share with %s</string> <string name="abc_shareactionprovider_share_with">Share with</string> <string name="app_name">你好!安卓</string> <string name="hello_world">用户名:</string> <string name="action_settings">设置</string> <string name="first">第一次进入</string> <string name="changeFont">点击我</string> <string name="password">密 码:</string> <string name="unsuccess">用户名或密码错误</string> <string name="success">登陆成功</string> </resources>
- 随后在同级目录下打开 public.xml 搜索 unsuccess
<?xml version="1.0" encoding="utf-8"?> <resources> <public type="string" name="abc_shareactionprovider_share_with" id="0x7f0a000c" /> <public type="string" name="app_name" id="0x7f0a000d" /> <public type="string" name="hello_world" id="0x7f0a000e" /> <public type="string" name="action_settings" id="0x7f0a000f" /> <public type="string" name="first" id="0x7f0a0010" /> <public type="string" name="changeFont" id="0x7f0a0011" /> <public type="string" name="password" id="0x7f0a0012" /> <public type="string" name="unsuccess" id="0x7f0a0013" /> <public type="string" name="success" id="0x7f0a0014" /> <public type="style" name="Widget.AppCompat.ActionBar" id="0x7f0b0000" /> <public type="style" name="Widget.AppCompat.Light.ActionBar" id="0x7f0b0001" /> <public type="style" name="Widget.AppCompat.ActionBar.Solid" id="0x7f0b0002" /> <public type="style" name="Widget.AppCompat.Light.ActionBar.Solid" id="0x7f0b0003" /> // 省略部分代码 </resources>
- 在smali目录中搜索内容为 0x7f0a0013 的文件,打开文件 MainActivity.smali
move-result-object v4 invoke-interface {v4}, Landroid/text/Editable;->toString()Ljava/lang/String; move-result-object v0 .line 54 .local v0, "passWord":Ljava/lang/String; invoke-virtual {p0, v2, v0}, Lcom/learn/MainActivity;->cheakSN(Ljava/lang/String;Ljava/lang/String;)Z move-result v4 if-eqz v4, :cond_0 # 如果不为0,就跳转到cond_0 标记处 .line 55 const v4, 0x7f0a0014 # 提示登陆成功 invoke-static {p0, v4, v5}, Landroid/widget/Toast;->makeText(Landroid/content/Context;II)Landroid/widget/Toast; move-result-object v4 invoke-virtual {v4}, Landroid/widget/Toast;->show()V goto :goto_0 .line 57 :cond_0 # 跳转到这里 const v4, 0x7f0a0013 # 提示登陆失败 invoke-static {p0, v4, v5}, Landroid/widget/Toast;->makeText(Landroid/content/Context;II)Landroid/widget/Toast; move-result-object v4 invoke-virtual {v4}, Landroid/widget/Toast;->show()V goto :goto_0
把 if-eqz 修改为 if-nez
if-eqz是Dalvik指令集中的一个条件跳转指令,类似的还有 if-eqz,if-gez,if-lez等
最后保存文件
重新编译Apk并签名
- 修改完Smali代码后,需要重新打包并签名
- 先用apktool对文件进行打包 :
apktool b HelloAndroid -o HelloAndroid
.apk
- 编译后的apk由于没有签名,直接安装会提示安装失败,需要我们下载signapk工具进行签名
- 解压缩signapk到c盘,以管理员方式运行 java -jar signapk.jar testkey.x509.pem testkey.pk8 HelloAndroid.apk hello.apk
- 最后测试安装,可以看到及时不输入任何值,也会提示登陆成功
本文含有隐藏内容,请 开通VIP 后查看