0x01 观察题目

  用模拟器运行程序,看到题目营造了一个情景让我们破解应用的登录系统,先随便输入一串数字,提示我们密码不对,请继续破解。

0x02 静态暴破

  首先将AliCrackme_1.apk用apktool进行反编译。

  反编译成功后得到输出文件夹:

  在eclipse中新建Java Project,将反编译文件夹设为工程目录,我们来看一看工程结构。

  接下来查找一下“密码”,发现没有做编码,定位到了string.xml文件中:

<?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">UFO</string>
    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>
    <string name="dialog_title">提示</string>
    <string name="dialog_error_tips">密码不对,请继续破解</string>
    <string name="dialog_good_tips">恭喜!!!破解成功!!!</string>
    <string name="dialog_ok">确定</string>
</resources>

  对应string name是"dialog_error_tips",顺便记录一下破解成功的string name,根据已有的线索追踪引用dialog_error_tips的位置,不难定位到public.xml文件。

  可以看到其id为0x7f0a0011,而顺带记录下0x7f0a0012。顺藤摸瓜,看看哪里引用了0x7f0a0011,发现在MainActivity$1与R$String这两个文件中该字符串有出没,但显然后者没有有效信息,于是进入第一个smali文件,找到id所在位置,对应代码块如下:

  发现下面一大片位于:cond_0中,而整个:cond_0位于onClick函数内,这应该就是按钮的点击事件的处理函数,先看看在这里:cond_0中都做了哪些操作。   首先new-instance新创建了一个实例,随后const v6作为中间变量,不断调用AlertDialog$Builder中的setMessage函数构造Dialog的各部分字符串,在.line 67处显示了对话框,也就是我们看到的密码不正确的提示框。再往下翻,紧接着goto :goto_0,发现goto_0处就直接return-void了。   分析完了:cond_0内的逻辑,来看看哪些地方跳到了这儿。大致浏览一番,定位到了如下代码块:

    if-eqz v4, :cond_0
    const-string v6, ""
    invoke-virtual {v4, v6}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
    move-result v6
    if-nez v6, :cond_0
    invoke-virtual {v4, v2}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
    move-result v6
    if-eqz v6, :cond_0
    .line 55
    iget-object v6, p0, Lcom/example/simpleencryption/MainActivity$1;->this$0:Lcom/example/simpleencryption/MainActivity;
    invoke-static {v6}, Lcom/example/simpleencryption/MainActivity;->access$1(Lcom/example/simpleencryption/MainActivity;)V

  首先判断v4是否等于零,是的话跳转到:cond_0,后面连续几个判断都跳到了:cond_0,说明v4,v6的值代表了输入的密码是否正确,这里我们直接黑掉这几个判断,代码顺利执行到.line 55,这里access$1函数引起了我们的关注,于是进入MainActivity中找到access$1,函数代码如下:

.method static synthetic access$1(Lcom/example/simpleencryption/MainActivity;)V
    .locals 0
    .prologue
    .line 73
    invoke-direct {p0}, Lcom/example/simpleencryption/MainActivity;->showDialog()V
    return-void
.end method

  函数内部又调用了showDiglog,找到showDiglog函数,发现与onClick函数的:cond_0逻辑神似,也是构造对话框,意外发现了一串熟悉的id: 0x7f0a0012

.method private showDialog()V
    .locals 3
    .prologue
    .line 74
    new-instance v0, Landroid/app/AlertDialog$Builder;
    invoke-direct {v0, p0}, Landroid/app/AlertDialog$Builder;-><init>(Landroid/content/Context;)V
    .line 75
    .local v0, "builder":Landroid/app/AlertDialog$Builder;
    const v1, 0x7f0a0012
    invoke-virtual {v0, v1}, Landroid/app/AlertDialog$Builder;->setMessage(I)Landroid/app/AlertDialog$Builder;
    .line 76
    const v1, 0x7f0a0010
    invoke-virtual {v0, v1}, Landroid/app/AlertDialog$Builder;->setTitle(I)Landroid/app/AlertDialog$Builder;
    .line 77
    const v1, 0x7f0a0013
    .line 78
    new-instance v2, Lcom/example/simpleencryption/MainActivity$2;
    invoke-direct {v2, p0}, Lcom/example/simpleencryption/MainActivity$2;-><init>(Lcom/example/simpleencryption/MainActivity;)V
    .line 77
    invoke-virtual {v0, v1, v2}, Landroid/app/AlertDialog$Builder;->setPositiveButton(ILandroid/content/DialogInterface$OnClickListener;)Landroid/app/AlertDialog$Builder;
    .line 84
    invoke-virtual {v0}, Landroid/app/AlertDialog$Builder;->show()Landroid/app/AlertDialog;
    .line 85
    return-void
.end method

  很明显我们找到了提示成功信息的地方。最后回编译apk文件,打上签名在模拟器上安装应用,随便输入密码,点击确认,可以看到已经破解成功了。

0x03 总结

  考虑到暴破相对来说有点低级了,下一篇将尝试从动态调试的角度重新审视此题,并真正意义上的破解出该题的正确密码。

--- END ---