入门分析crackme apk
在github下载的示例app,下载地址:https://github.com/num1r0/android_crackmes/blob/master/crackme_0x01/app.apkapp安装后运行如下图https://image.3001.net/images/20220401/1648794804_62469cb4d9eb37295be58.png!small输入密码,密码成功系统给出flag密码失败提示重新重新尝试https://image.3001.net/images/20220401/1648794805_62469cb57890d5752c50e.png!small1 静态分析使用apk分析工具对apk进行反编译分析,此处使用的是“apk改之理3.5.0(少月版)”,大佬写的工具很好用,导入 apk文件后自动对应于进行反编译。https://image.3001.net/images/20220401/1648794806_62469cb6163f3e96c00c4.png!smallapp文档结构比较简单,主要文件夹就是res资源目录、和代码目录。1.1 查看androidmainfest.xmlhttps://image.3001.net/images/20220401/1648794806_62469cb6af0d2a21508f4.png!small查看可以确认,程序相对较简单,默认启动com.entebra.crackme0x01.MainActivity直接运行。没有 其他可以启动的activity1.2 MainActivity文件分析查看入门代码https://image.3001.net/images/20220401/1648794807_62469cb738117e1ef14c6.png!small定义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文件,https://image.3001.net/images/20220401/1648794807_62469cb7b05f127b594cd.png!small初始化基本就是同步了标题和actiity,主要关注onclick函数https://image.3001.net/images/20220401/1648794808_62469cb833d005d267a84.png!small定义p1 flagGuard对象,并进行初始化https://image.3001.net/images/20220401/1648794808_62469cb8bedc098ab1f05.png!small在初始化flagGuard对象时执行的动作如下:flagGuard对象初始化时具备3个属性,并对个属性进行赋值如下:pad= "abcdefghijklmnopqrstuvwxyz"scr_flag= "abcdefghijklmnopqrstuvwxyz"flag=""初始化flaguard对象后,处理显示内容,获取editable等内容https://image.3001.net/images/20220401/1648794809_62469cb938913ead0d0dc.png!small初始化完显示内容后,调用flagGuard对象的getFlag函数https://image.3001.net/images/20220401/1648794809_62469cb995f35f0aedb14.png!small1.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_1337https://image.3001.net/images/20220401/1648794809_62469cb9eb3df600e61bf.png!smallgetdata和初始化属性功能是一样的。https://image.3001.net/images/20220401/1648794810_62469cba5f1a96629164b.png!small继续跟进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;)https://image.3001.net/images/20220401/1648795020_62469d8c0bc8ffaff6387.png!small?1648795020636输入密码后系统正常后续内容。https://image.3001.net/images/20220401/1648795051_62469dabdae01f3e4fa06.png!small?1648795052486备注:移动安全入门学习随笔,如不正确大佬勿喷。PS:具体知识建议学习大佬教程 jinzhu160 发表于 2023-1-23 09:09
跟大佬学习,就是排版有点乱
感谢支持!下次注意! 正己 发表于 2023-1-22 22:43
代码用代码块包起来,不然挺乱的
我是小白,怎么样 代码用代码块包起来?我不会操作,看大神贴的代码方法很想学{:1_899:}{:1_899:} 代码用代码块包起来,不然挺乱的
这里是代码 正己 发表于 2023-1-22 22:43
代码用代码块包起来,不然挺乱的
收到!感谢版主点评! 学习啦,加油 AdmicQ 发表于 2023-1-24 08:52
学习啦,加油
感谢支持! 排版太乱,看不下去了…… 排序有点乱,不过感谢分享 学习。。。。
页:
[1]
2