BUUCTF-RE-[Zer0pts2020]easy strcmp
首先查壳发现啥也没有,然后静态分析,看到代码十分简单,以为是签到题
将flag提交上去显示错误,说明这道题另有玄机
可以看到这道题除了main函数还有各种其他的不知名函数
说明并不这么简单,查看其他师傅的思路,发现在执行main函数之前实际上还调用了一大堆其他的函数,比如__libc_start_main函数
我们可以在start函数中看见它的调用:
其中__libc_start_main将init作为初始化函数,将fini作为终止函数,我们跟进init函数看看请况
发现给了两个偏移值v4 = &off_55CB63800DF0 - funcs_889;
,我们可以在这里找到一个函数
查看它的逻辑:
int (**sub_55CB63600795())(const char *s1, const char *s2)
{
int (**result)(const char *, const char *); // rax
result = &strcmp;
qword_55CB63801090 = (__int64 (__fastcall *)(_QWORD, _QWORD))&strcmp;
off_55CB63801028 = sub_55CB636006EA;
return result;
可以看到,这里实际上将strcmp
和sub_55CB636006EA
调换了地址,当程序在执行strcmp时,实际上调用的是sub_55CB636006EA,这也解释了为什么我们一开始输入的flag为什么会导致错误
我们进一步查看sub_55CB636006EA的程序逻辑:
然后写出解密脚本:
#include<stdio.h>
int main(){
char p[] = "zer0pts{********CENSORED********}";
long long key[4] = {0, 0x410A4335494A0942, 0x0B0EF2F50BE619F0, 0x4F0A3A064A35282B};
for (int i =0;i<4;i++){
*(long long *)&(p[i*8]) += key[i];
}
printf("%s",(char *)p);
}