一 .bc文件
拿到文件名为baby.bc
bc文件为LLVM IR bitcode文件。官方定义:LLVM是一个模块化和可重用的编译器和工具链技术的集合。
个人理解为bc文件是编译器LLVM的中间代码即IR指令文件,属于编译过程中的未完成的一直格式文件,继续往下编译生成.s汇编代码文件,再之后是可执行文件,往前是编译之前的源文件。
想要完成分析只能继续编译,生成可执行文件,而后利用IDA完成反编译。
clang baby.bc -o baby
新生成的文件为ELF 64位
二、IDA分析
fill_number部分略过不谈,主要是根据输入初始化了map数组(5*5)。
docheck部分是对fill_number之后的map数组进行约束。
重点分析当时就因为这一段读不懂借不出题的部分:
整段的目的是为了确保map的五个元素各不相等,具体原因为:
v1 = m[5 * v0]; if ( *(&v24 + v1) ) break; *(&v24 + v1) = 1; v2 = byte_404041[5 * v0];
对*(&v24+v1)分析,v24是int型数据,即占用四个字节,已经被初始化为0
可以想象成这样的存储。
而v25是2字节的int类型,紧跟在v24后边,是连续的地址,也已经被初始化为0,那么这边栈空间可以这么想象
v1是1-5直接的整数,那么*(&v24+v1)便是在这6个字节的空间中进行寻址,假设v1=1
即*(&v24+1)指向了第二个字节。
特别注意这时的1,是指相对首地址偏移1个字节。
v1,v2,v3,v4,v5是对应了一行的五个元素。if条件不满足后v24偏移v1处被赋值为1,
,等到下一个if时也是不能满足的,也就意味着v24偏移v2处初始值必须是0,那么v2就不能等于v1,以此类推,这是在约束这v1,v2,v3,v4,v5互不相等。
后边类似得约束了一列中的五个元素互不相等。
总结:
IDA反编译中时常出现基址+偏移来表示某个变量的情况。需要区分两种情况:
1.数据类型+地址
2.数组下标寻址
后边则是对行列相邻元素件的大小约束关系,根据n的值来确定,只要不让if与else if条件满足即可,分析略。
最后得到的数独:
MD5后得到flag
闭坑:
在查看map数组的值得时候
一直误以为40404B处的值为4,而在十六进制窗口查看
显然为0;
align意为对齐。align 4是伪指令 4位对齐。真实的数据应当在HEX中查看。
了解对齐:
align n;是汇编中的一条伪指令,意为n位对齐。即下一个数据应当在内存地址为n的倍数的位置开始,其余的位置应当填充为0.
以此出为例,40404B地址出有一天align 4指令,即下一个数据的存放要在地址为4的倍数的位置开始,而40404B恰好是4的倍数,所以此处不影响后边数据的存放。
而404054出有一条指令align 20h,意为下一个数据应当从32的倍数的地址处开始存放,往后直到404060(为32的倍数)才开始有了下一个实际的数据,之前的数据全填充为0。