前言
好久没做ctf题了,arm指令都快忘光了…..
提起去年太菜没做出的题再分析下。
ida addmap时可以直接把系统库函数全部取出来,放到一个本地文件夹中这样ida即可加载对应的so用于分析。–全部提出system/lib指定目录即可
现在的加载so,不落地手动加载是绝杀…….必须读读linker
debugger里的watch view可以查看任意形式的目标时时信息,支持c变量表达式。十分好用 比如:(char*)R0
题解
这题的垃圾代码比较多,这里看下快速的分析方式。
首先运行一下:
输入flag判断正误
直接拖到jeb里看下
|
|
没什么特别的声明,就一个Activity。
看下他的类与layout
|
|
在public中:
activity_main:
可见为基本的读入字串,在libhello-libs.so中判断结果返回,返回1为正确
接下来ida分析libhello-libs.so:
该so为32位的,init_array段有内容但不影响,无jni_onload,导出部分也没有下坑。找到导出函数:
|
|
分析:
- GetStringUTFChars将utf编码的java字串拷贝到本地c的asll实现
- v1,v10都没用上可知为垃圾代码
- sub_D6EC3364为将v2的字串封装结构体为v9,根据里面库函数的字串应该是string的构造
- sub_D6EC2A08动态调试结果返回和输入没区别…..
- j-aeabi这个函数是关键函数
- 后面俩个的参数对判断结果v5毫无影响,为垃圾函数
之后来看核心判断:
基本流程就是:
对输入异或一个串,判断结果是10个一循环的,取前10位化为longlong,取一个大整数除它,要求余数==0,除数小于商。
值得说说的就是动调看汇编代码或者汇编对照idaF5看比只看F5效率高很多…..F5出来的很难看出在干什么….
把arm指令记熟了应该静态主读汇编以F5为辅也能很快分析出来。
始终确保某寄存器或某地址上的目标数据内容,知道该数据的传递在算法的一部分中可以快速理清思路。
arm大小端存储都可以,默认为小端,longlong系列的指令都是用俩个寄存器传递,R0低32位,R1高32位。遇到不懂的指令去arm手册查。
在F5的结果中参数为R0-R1放,对应的是左-右的参。且将longlong类型识别为俩个参数了
最后写出脚本:
|
|
后记
因为arm架构是基于寄存器的,注意一个反编译函数中许多变量都是寄存器。在局部内是有效的。由于idaF5出的arm代码还不是非常准确,最好是用汇编代码对照着读,c保证大体位置不走丢,汇编保证细节准确性和算法理解。动态调试最好能够配合,可以关注输入与返回等的位置与变动情况。
对于arm指令来说…..直接读汇编辅助读F5比只读F5好太多…….F5出来的简直坑…….
顺便arm指令需要背下来。