好友
阅读权限10
听众
最后登录1970-1-1
|
在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;-><init>(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;-><init>()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;-><init>()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:具体知识建议学习大佬教程 |
免费评分
-
查看全部评分
|