先用DIE看一下这是啥
放到虚拟机里运行一下
随便输入一个数字,发现这里有长度检查,太短或者太长了。
先用IDA打开看一下吧,主函数
发现有一个构造函数,后面有两个函数一个计算量长度,另一个检查是否通过,最后才输出了flag。但是这里我们直接去看flag的v22是看不到东西的,因为它是在运行中计算出来的。我们先看构造函数。
a1是传入的参数,其实是v23[120]。这里把a2分别放到+16,48两个位置,然后把327a6c4304ad5938eaf0efb6cc3e53dc放到+80的 位置。
再看检查长度的函数
检查完长度之后,又对+16进行了两次操作。显然必须长度满足条件,才能继续下面的操作。注意这里使用了指针,所以看似没有对this进行修改,其实已经通过v4和v2两个指针,修改了其中的内容。
最后再看getserial函数。
这里检查了一下是否通过,条件其实就是+16和+80是不是相等。这两个其实分别是输入的字符被操作之后,和+80的那一大长串。
通过之后,再看后面的代码
只不过是把我们输入的内容外面套了一个flag{}进行输入而已。
那现在我们就可以写一个反向的代码,从+80还原我们的输入。
那这就应该是flag了。同时我们也可以输入第一行的内容到原程序,看看是不是会输出flag
果然在全部检查通过后输出了一样的flag。
代码如下
#include <iostream>
#include<string>
int main()
{
char v23[120];
std::string calculatedstring = "327a6c4304ad5938eaf0efb6cc3e53dc";
for (int j = 0; ; ++j)
{
bool result = j <= calculatedstring.length();
if (!result)
break;
calculatedstring[j] = calculatedstring[j] - 11 ^ 0x13;
}
for (int i = 0; i <= calculatedstring.length(); ++i)
{
calculatedstring[i] = calculatedstring[i] - 23 ^ 0x50;
}
std::cout << calculatedstring<<std::endl;
std::cout << "flag{" << calculatedstring << "}" << std::endl;
//flag{tMx~qdstOs~crvtwb~aOba}qddtbrtcd}
return 0;
}