入门分析crackme apk

查看 123|回复 7
作者:Boltlightning   
在github下载的示例app,下载地址:https://github.com/num1r0/android_crackmes/blob/master/crackme_0x01/app.apkapp安装后运行如下图输入密码,密码成功系统给出flag密码失败提示重新重新尝试1 静态分析使用apk分析工具对apk进行反编译分析,此处使用的是“apk改之理3.5.0(少月版)”,大佬写的工具很好用,导入 apk文件后自动对应于进行反编译。app文档结构比较简单,主要文件夹就是res资源目录、和代码目录。1.1 查看androidmainfest.xml查看可以确认,程序相对较简单,默认启动com.entebra.crackme0x01.MainActivity直接运行。没有 其他可以启动的activity1.2 MainActivity文件分析查看入门代码定义description和name变量通过constructor函数对变量进行初始化赋值,完成constructor函数后description的值为Level:Beginner,name的值为CrackMe 0x01经过初始化函数后,进入android入口函数onCreate,由于函数比较简单,因此把完整代码贴出来method protected onCreate(Landroid/os/Bundle;)V  #函数无返回值    .locals 2    .line 21    #调用父类对p0进行初始化    invoke-virtual {p0}, Lcom/entebra/crackme0x01/MainActivity;->getSupportActionBar()Landroid/support/v7/app/ActionBar;    move-result-object v0    .line 22        #调用ActionBar->hide    invoke-virtual {v0}, Landroid/support/v7/app/ActionBar;->hide()V    .line 23        #调用父类oncrate初始化窗口    invoke-super {p0, p1}, Landroid/support/v7/app/AppCompatActivity;->onCreate(Landroid/os/Bundle;)V    const p1, 0x7f09001b    .line 24        #调用setContentView函数    invoke-virtual {p0, p1}, Lcom/entebra/crackme0x01/MainActivity;->setContentView(I)V    const p1, 0x7f070078    .line 26        #定义p1然后调用对应findViewById函数获取View对象    invoke-virtual {p0, p1}, Lcom/entebra/crackme0x01/MainActivity;->findViewById(I)Landroid/view/View;    move-result-object p1    check-cast p1, Landroid/widget/Button;    const v0, 0x7f070055    .line 27        #同上获取View对象    invoke-virtual {p0, v0}, Lcom/entebra/crackme0x01/MainActivity;->findViewById(I)Landroid/view/View;    move-result-object v0    check-cast v0, Landroid/widget/EditText;    .line 29        #初始化MainActivity$1 #传入之前MainActivity、EditText    new-instance v1, Lcom/entebra/crackme0x01/MainActivity$1;    invoke-direct {v1, p0, v0}, Lcom/entebra/crackme0x01/MainActivity$1;->(Lcom/entebra/crackme0x01/MainActivity;Landroid/widget/EditText;)V#监控鼠标点击,调用onclick函数    invoke-virtual {p1, v1}, Landroid/widget/Button;->setOnClickListener(Landroid/view/View$OnClickListener;)V    return-void1.3 MainActivity$1查看MainActivity$1文件,初始化基本就是同步了标题和actiity,主要关注onclick函数定义p1 flagGuard对象,并进行初始化在初始化flagGuard对象时执行的动作如下:
flagGuard对象初始化时具备3个属性,并对个属性进行赋值如下:pad= "abcdefghijklmnopqrstuvwxyz"scr_flag= "abcdefghijklmnopqrstuvwxyz"flag=""初始化flaguard对象后,处理显示内容,获取editable等内容初始化完显示内容后,调用flagGuard对象的getFlag函数1.3.1 getFlag函数跟进getFlag函数内容,getflag函数内容如下# virtual methods.method public getFlag(Ljava/lang/String;)Ljava/lang/String; #返回字符串类型    .locals 1    .line 11    #初始化Data对象    new-instance v0, Lcom/entebra/crackme0x01/Data;    invoke-direct {v0}, Lcom/entebra/crackme0x01/Data;->()V    #调用data对象的getData函数    .line 12    invoke-virtual {v0}, Lcom/entebra/crackme0x01/Data;->getData()Ljava/lang/String;    #将getData返回的字符串进行equals对比,    move-result-object v0    invoke-virtual {p1, v0}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z    move-result p1# 判断equals结果,如果结果为假跳转到吗到cond_0否则继续执行    if-eqz p1, :cond_0# 调用FlagGuard对象的unscramble()函数并返回一个字符串    .line 13    invoke-direct {p0}, Lcom/entebra/crackme0x01/FlagGuard;->unscramble()Ljava/lang/String;    move-result-object p1#返回unscramble函数返回的结果    return-object p1    :cond_0    #重置p1变量为空并返回    const/4 p1, 0x0    return-object p1.end method通过以上整理发现getFlag函数主要是获取Data的getdata内容,判断该内容是否相等,确定返回内容1.3.1.1 Data对象data对象初始化后初始化secret属性为s3cr37_p4ssw0rd_1337getdata和初始化属性功能是一样的。继续跟进FlagGuard的unscramble函数。1.3.2 unscramble函数可以确定该函数会返回一段字符串.method private unscramble()Ljava/lang/String;    .locals 9    .line 21        #初始化stringBuilder对象    new-instance v0, Ljava/lang/StringBuilder;    invoke-direct {v0}, Ljava/lang/StringBuilder;->()V   #设置v1的值为1337.0    const-wide v1, 0x4094e40000000000L    # 1337.0    .line 22        #将double类型转换为字符串    invoke-static {v1, v2}, Ljava/lang/String;->valueOf(D)Ljava/lang/String;    move-result-object v1#对v2进行赋值    const-string v2, "\\."        #对字符串进行split,返回数组    invoke-virtual {v1, v2}, Ljava/lang/String;->split(Ljava/lang/String;)[Ljava/lang/String;    move-result-object v1    const/4 v2, 0x0    aget-object v1, v1, v2    #将v1数组转化成Integer并返回    invoke-static {v1}, Ljava/lang/Integer;->valueOf(Ljava/lang/String;)Ljava/lang/Integer;    move-result-object v1#将v1转化成int    invoke-virtual {v1}, Ljava/lang/Integer;->intValue()I    move-result v1#定义字符串变量 v3    const-string v3, "qw4r_q0c_nc4nvx3_0i01_srq82q8mx"    .line 23#将字符串转换为字符数组                                                                             invoke-virtual {v3}, Ljava/lang/String;->toCharArray()[C    move-result-object v3#获取v数组长度    array-length v4, v3    :goto_0    if-ge v2, v4, :cond_2    aget-char v5, v3, v2    const-string v6, "Char: "    .line 24    invoke-static {v5}, Ljava/lang/String;->valueOf(C)Ljava/lang/String;    move-result-object v7#输出androidlog    invoke-static {v6, v7}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I    const-string v6, "abcdefghijklmnopqrstuvwxyz"    .line 26    invoke-virtual {v6, v5}, Ljava/lang/String;->indexOf(I)I    move-result v6    const-string v7, "indexOf: "    .line 27    invoke-static {v6}, Ljava/lang/String;->valueOf(I)Ljava/lang/String;    move-result-object v8    invoke-static {v7, v8}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I    if-gez v6, :cond_0    .line 29    invoke-static {v5}, Ljava/lang/String;->valueOf(C)Ljava/lang/String;    move-result-object v5    goto :goto_1    :cond_0    sub-int/2addr v6, v1    const-string v5, "abcdefghijklmnopqrstuvwxyz"    .line 31    invoke-virtual {v5}, Ljava/lang/String;->length()I    move-result v5    rem-int/2addr v6, v5    if-gez v6, :cond_1    const-string v5, "abcdefghijklmnopqrstuvwxyz"    .line 33    invoke-virtual {v5}, Ljava/lang/String;->toCharArray()[C    move-result-object v5    const-string v7, "abcdefghijklmnopqrstuvwxyz"    invoke-virtual {v7}, Ljava/lang/String;->length()I    move-result v7    add-int/2addr v6, v7    aget-char v5, v5, v6    invoke-static {v5}, Ljava/lang/String;->valueOf(C)Ljava/lang/String;    move-result-object v5    goto :goto_1    :cond_1    const-string v5, "abcdefghijklmnopqrstuvwxyz"    .line 35    invoke-virtual {v5}, Ljava/lang/String;->toCharArray()[C    move-result-object v5    aget-char v5, v5, v6    invoke-static {v5}, Ljava/lang/String;->valueOf(C)Ljava/lang/String;    move-result-object v5    :goto_1    const-string v6, "letter "    .line 37    invoke-static {v6, v5}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I    .line 38    invoke-virtual {v0, v5}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;    add-int/lit8 v2, v2, 0x1    goto :goto_0    :cond_2    const-string v1, "FLAG: "    .line 40    invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;    move-result-object v2    invoke-static {v1, v2}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I    .line 41    invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;    move-result-object v0    return-object v0.end method该函数主要功能是通过指定的算法返回一个字符串。运行完毕程序结束,在getData时返回的应该是密码,将密码输入app尝试输入密码后系统正常后续内容。备注:移动安全入门学习随笔,如不正确大佬勿喷。PS:具体知识建议学习大佬教程

函数, 初始化

jinzhu160   

代码用代码块包起来,不然挺乱的
[Java] 纯文本查看 复制代码这里是代码
Boltlightning
OP
  

跟大佬学习,就是排版有点乱
Boltlightning
OP
  


jinzhu160 发表于 2023-1-23 09:09
跟大佬学习,就是排版有点乱

感谢支持!下次注意!
AdmicQ   


正己 发表于 2023-1-22 22:43
代码用代码块包起来,不然挺乱的

收到!感谢版主点评!
Boltlightning
OP
  

学习啦,加油
78zhanghao87   


AdmicQ 发表于 2023-1-24 08:52
学习啦,加油

感谢支持!
Boltlightning
OP
  

排版太乱,看不下去了……
您需要登录后才可以回帖 登录 | 立即注册