2021CISCN-逆向-baby.bc-部分知识点总结

一 .bc文件

拿到文件名为baby.bc

2021CISCN-逆向-baby.bc-部分知识点总结

 

bc文件为LLVM IR bitcode文件。官方定义:LLVM是一个模块化和可重用的编译器和工具链技术的集合。

个人理解为bc文件是编译器LLVM的中间代码即IR指令文件,属于编译过程中的未完成的一直格式文件,继续往下编译生成.s汇编代码文件,再之后是可执行文件,往前是编译之前的源文件。

 2021CISCN-逆向-baby.bc-部分知识点总结

 

想要完成分析只能继续编译,生成可执行文件,而后利用IDA完成反编译。

Clang:是一个基于LLVM的C/C++/Objective-C编译器。利用clang完成后面的工作
clang baby.bc -o baby
 

 

 新生成的文件为ELF 64位

二、IDA分析

2021CISCN-逆向-baby.bc-部分知识点总结

 

fill_number部分略过不谈,主要是根据输入初始化了map数组(5*5)。

docheck部分是对fill_number之后的map数组进行约束。

重点分析当时就因为这一段读不懂借不出题的部分:

2021CISCN-逆向-baby.bc-部分知识点总结

 

2021CISCN-逆向-baby.bc-部分知识点总结

 

 

整段的目的是为了确保map的五个元素各不相等,具体原因为:

v1 = m[5 * v0];
if ( *(&v24 + v1) )
break;
*(&v24 + v1) = 1;
v2 = byte_404041[5 * v0]; 

 对*(&v24+v1)分析,v24是int型数据,即占用四个字节,已经被初始化为0

2021CISCN-逆向-baby.bc-部分知识点总结可以想象成这样的存储。

 

而v25是2字节的int类型,紧跟在v24后边,是连续的地址,也已经被初始化为0,那么这边栈空间可以这么想象2021CISCN-逆向-baby.bc-部分知识点总结

 

v1是1-5直接的整数,那么*(&v24+v1)便是在这6个字节的空间中进行寻址,假设v1=1

即*(&v24+1)指向了第二个字节2021CISCN-逆向-baby.bc-部分知识点总结

 

特别注意这时的1,是指相对首地址偏移1个字节。

 v1,v2,v3,v4,v5是对应了一行的五个元素。if条件不满足后v24偏移v1处被赋值为1,

2021CISCN-逆向-baby.bc-部分知识点总结,等到下一个if时也是不能满足的,也就意味着v24偏移v2处初始值必须是0,那么v2就不能等于v1,以此类推,这是在约束这v1,v2,v3,v4,v5互不相等。

 

2021CISCN-逆向-baby.bc-部分知识点总结

 

 

 

后边类似得约束了一列中的五个元素互不相等。

总结:

IDA反编译中时常出现基址+偏移来表示某个变量的情况。需要区分两种情况:

1.数据类型+地址

 int a;
b=*(&a+v1);
//此时根据a的基址进行偏移v1,则v1表示的是偏移v1个字节,即b指向的是某个BYTE型的空间

  

2.数组下标寻址

 int  a[4];
b=a[v1];
//此时的v1表示的偏移是偏移v1*4个字节(int占据4字节),此时的b指向的是某个int型的4字节空
//间

 

 

 2021CISCN-逆向-baby.bc-部分知识点总结

 

 后边则是对行列相邻元素件的大小约束关系,根据n的值来确定,只要不让if与else if条件满足即可,分析略。

最后得到的数独:2021CISCN-逆向-baby.bc-部分知识点总结

 

MD5后得到flag2021CISCN-逆向-baby.bc-部分知识点总结

 

 闭坑:

在查看map数组的值得时候

2021CISCN-逆向-baby.bc-部分知识点总结

 

 一直误以为40404B处的值为4,而在十六进制窗口查看2021CISCN-逆向-baby.bc-部分知识点总结

 

 显然为0;

align意为对齐。align 4是伪指令 4位对齐。真实的数据应当在HEX中查看。

 

了解对齐:

align n;是汇编中的一条伪指令,意为n位对齐。即下一个数据应当在内存地址为n的倍数的位置开始,其余的位置应当填充为0.

以此出为例,40404B地址出有一天align 4指令,即下一个数据的存放要在地址为4的倍数的位置开始,而40404B恰好是4的倍数,所以此处不影响后边数据的存放。

2021CISCN-逆向-baby.bc-部分知识点总结

 

 

而404054出有一条指令align 20h,意为下一个数据应当从32的倍数的地址处开始存放,往后直到404060(为32的倍数)才开始有了下一个实际的数据,之前的数据全填充为0。

 

2021CISCN-逆向-baby.bc-部分知识点总结

上一篇:从 LiveData 迁移到 Kotlin 数据流


下一篇:记录DIV中滚动位置刷新页面位置保持不变