周末参加了一下RWCTF体验赛(正赛搞不动),做了道安卓的逆向题,挺有意思,分享下我的思路。
直接拖进手机,发现是个贪吃蛇游戏,通过四个方向划动控制蛇蛇的方向,那可能就要通关或者长度达到一定条件才能拿到flag:
把APK拖进GDA,直接看。
没有加固,不涉及native层,这是好事:
涉及的就是snakeView,直接看代码有点费时费力,发现这个游戏你撞墙或者撞到自己,会提示要求重来,这里有个弹框,我习惯直接hook打印调用堆栈,用来定位(当然这里不这样直接找也能找到)。
直接能定位到了,就是在run线程里,跟进去最后执行的函数如图:
发现label_0127中的判断(大于55很可疑),动态调试一下可以看看这里:
根据上面分析的位置,在判断是否大于55的地方下断点,用jeb进行动态调试。
当你吃到方块的时候,会触发断点。
将值修改成大于55。
放过跑起来,发现刷新的方块图片变成了字母,那这里就可以推测,当这个值大于55时,开始逐个刷新字母方块,最后可能就是flag:
继续跟进,发现加载图片时,是执行了b方法(同样不触发上面条件则是a方法):
这里我解压,找了下apk中的资源,找到了所有刷新时生成的方块图片资源(不同方法加载前缀a或b的png,其中bx.png是用来生成flag的图片):
根据上面的判断,接下来问题就在b方法中的this.f这个数组内容是什么,v就是从0开始递增可以不用管(label_0127中只改了c为1,v++),找到f:
可以看到是在初始化这个类时通过a.a方法,解密了一串字符串,得到一个数组,再赋值给f,同样通过动态调试可以获取到。
然后就对照上面资源里面图片的命名,对号入座就可以了:
EK33PG01NGD0N0TG1V3UPPP
最后不要忘记,舍掉第一位,因为b方法第一次执行,v已经是1了,然后加上flag包裹就可以了。