本题有三种解题方式,下文会一一列举:
第一解法:
常规逆向分析,apk拖进jadx寻找入口点。
这里提一个点,可以看到该app还注册了一个广播,且exported="true",表示允许进行外部调用。先记下,后面会提到。
进入入口分析,可以看到调用了Check.checkPassword方法,且只有返回值为True的时候才能继续。
进入Check类分析看下:
这里我们主要关注两个信息点:
1、pass的长度必须为12
2、且想要让该方法返回true,这必须满足以下条件:在12次循环中的pass[len] = (char) (((255 - len) - 100) - pass[len]);表达式计算之后每一位的pass[len]的值必须等于字符‘0’的char值。(0的ASCII码十进制为48,明白这个条件后,口算即知,key为kjihgfedcba`)
写个脚本解一下:
key = list('000000000000')
for i in range(12):
value = 255 - 100 - i - ord(key[i])
key[i] = chr(value)
print("".join(str(i) for i in key))
输入key进入下一步,可以看到这里发了一个广播。
进一步查看manifest.xml,我们知道触发该广播需要输入"android.is.very.fun",而GetAndChange为广播的接收器。
在接收器中,接收到广播后,会intent到NextContent。
进NextContent分析看下,可以看到Change方法中对Assets中zip文件做了处理,最后转化为一个jpg文件并set到界面上了。
至此全部逻辑分析完毕,手机上层层输入密码,进入最后一步,看到flag。
第二解法:
无需破解第一层密码,记得上文提过广播允许进行外部调用,我们使用adb工具构造广播直接唤出flag。
adb shell am broadcast -a android.is.very.fun
第三解法:
看懂解密最后一步直接解压出apk中assets目录中的timg.zip文件。
(注意不要解压该文件,而是修改该文件后缀名,随意更改为jpg等,得到flag图片)