多看看STL题就会了,很简单
int __fastcall main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbx
__int64 v4; // rax
char v5; // bl
_BYTE *v6; // rax
_QWORD *v7; // rax
__int64 v8; // rax
__int64 v9; // rax
int i; // [rsp+0h] [rbp-250h]
int j; // [rsp+4h] [rbp-24Ch]
char v13[32]; // [rsp+10h] [rbp-240h] BYREF
char v14[32]; // [rsp+30h] [rbp-220h] BYREF
__int64 v15[64]; // [rsp+50h] [rbp-200h] BYREF
v15[61] = __readfsqword(0x28u);
std::string::basic_string(v13, argv, envp);
memset(v15, 0, 480);
v15[0] = 0x2882D802120ELL;
v15[1] = 0x28529A05954LL;
v15[2] = 0x486088C03LL;
v15[3] = 0xC0FB3B55754LL;
v15[4] = 0xC2B9B7F8651LL;
v15[5] = 0xAE83FB054CLL;
v15[6] = 0x29ABF6DDCB15LL;
v15[7] = 0x10E261FC807LL;
v15[8] = 0x2A82FE86D707LL;
v15[9] = 0xE0CB79A5706LL;
v15[10] = 0x330560890D06LL;
std::operator<<<std::char_traits<char>>(&std::cout, "Input Your flag:");
std::operator>><char>(&std::cin, v13);
if ( std::string::length(v13) != 44 )
exit(0);
v3 = std::string::end(v13);
v4 = std::string::begin(v13);
std::reverse<__gnu_cxx::__normal_iterator<char *,std::string>>(v4, v3);
for ( i = 0; i < (unsigned __int64)(std::string::size(v13) - 1); ++i )
{
v5 = *(_BYTE *)std::string::operator[](v13, i + 1);
v6 = (_BYTE *)std::string::operator[](v13, i);
*v6 ^= v5;
}
for ( j = 0; j < (unsigned __int64)std::string::size(v13) >> 2; ++j )
{
std::string::substr(v14, v13, 4 * j, 4LL);
v7 = (_QWORD *)std::string::operator[](v14, 0LL);
if ( (((unsigned __int64)(unsigned int)*v7 << 15) ^ (unsigned int)*v7) != v15[j] )
{
v8 = std::operator<<<std::char_traits<char>>(&std::cout, "Wrong!!");
std::ostream::operator<<(v8, &std::endl<char,std::char_traits<char>>);
exit(0);
}
std::string::~string(v14);
}
v9 = std::operator<<<std::char_traits<char>>(&std::cout, "Right!!");
std::ostream::operator<<(v9, &std::endl<char,std::char_traits<char>>);
std::string::~string(v13);
return 0;
}
加注释
int __fastcall main(int argc, const char **argv, const char **envp)
{
__int64 v3; // rbx
__int64 v4; // rax
char v5; // bl
_BYTE *v6; // rax
_QWORD *v7; // rax
__int64 v8; // rax
__int64 v9; // rax
int i; // [rsp+0h] [rbp-250h]
int j; // [rsp+4h] [rbp-24Ch]
char input[32]; // [rsp+10h] [rbp-240h] BYREF
char v14[32]; // [rsp+30h] [rbp-220h] BYREF
__int64 v15[64]; // [rsp+50h] [rbp-200h] BYREF
v15[61] = __readfsqword(0x28u);
std::string::basic_string(input, argv, envp);
memset(v15, 0, 480);
v15[0] = 0x2882D802120ELL;
v15[1] = 0x28529A05954LL;
v15[2] = 0x486088C03LL;
v15[3] = 0xC0FB3B55754LL;
v15[4] = 0xC2B9B7F8651LL;
v15[5] = 0xAE83FB054CLL;
v15[6] = 0x29ABF6DDCB15LL;
v15[7] = 0x10E261FC807LL;
v15[8] = 0x2A82FE86D707LL;
v15[9] = 0xE0CB79A5706LL;
v15[10] = 0x330560890D06LL;
std::operator<<<std::char_traits<char>>(&std::cout, "Input Your flag:");// 输出
std::operator>><char>(&std::cin, input); // 输入
if ( std::string::length(input) != 44 ) // 检查输入长度是否为44
exit(0);
v3 = std::string::end(input); // 返回字符串最后一个之后的
v4 = std::string::begin(input); // 返回第一个
std::reverse<__gnu_cxx::__normal_iterator<char *,std::string>>(v4, v3);// std::reverse反转字符串
for ( i = 0; i < (unsigned __int64)(std::string::size(input) - 1); ++i )
{
v5 = *(_BYTE *)std::string::operator[](input, i + 1);// v5 = input[i+1]
v6 = (_BYTE *)std::string::operator[](input, i);// v6 = input[i]
*v6 ^= v5; // input[i] = input[i] ^ input[i+1]
}
for ( j = 0; j < (unsigned __int64)std::string::size(input) >> 2; ++j )// for(j=0;j < len(input)/4 ; j++)
{
std::string::substr(v14, input, 4 * j, 4LL);// 四个一组提取到v14
v7 = (_QWORD *)std::string::operator[](v14, 0LL);// v7 = v14[0]
if ( (((unsigned __int64)(unsigned int)*v7 << 15) ^ (unsigned int)*v7) != v15[j] )// int32强制转64,解密时候要转回来
// (x << 15) ^ x = y
// v15
// unsigned long data[11] = {
// 0x00002882D802120E, 0x0000028529A05954, 0x0000000486088C03, 0x00000C0FB3B55754,
// 0x00000C2B9B7F8651, 0x000000AE83FB054C, 0x000029ABF6DDCB15, 0x0000010E261FC807,
// 0x00002A82FE86D707, 0x00000E0CB79A5706, 0x0000330560890D06
// };
{
v8 = std::operator<<<std::char_traits<char>>(&std::cout, "Wrong!!");
std::ostream::operator<<(v8, &std::endl<char,std::char_traits<char>>);
exit(0);
}
std::string::~string(v14);
}
v9 = std::operator<<<std::char_traits<char>>(&std::cout, "Right!!");
std::ostream::operator<<(v9, &std::endl<char,std::char_traits<char>>);
std::string::~string(input);
return 0;
}
getflag
#include <cstdio>
/*
* 根据给定的 y 和 n 计算出 x
* (x << n) ^ x = y
*/
template<typename T>
T left_Solve_x_correct(T y, unsigned int n) {
T x = 0; // 初始化 x 为 0
unsigned int total_bits = sizeof(T) * 8; // 数据类型的总位数
for (unsigned int i = 0; i < total_bits; ++i) {
T y_i = (y >> i) & 1; // 提取 y 的第 i 位
T x_i;
if (i < n) {
x_i = y_i; // 当 i < n 时,x_i = y_i
} else {
T x_prev = (x >> (i - n)) & 1; // 获取 x 中第 (i - n) 位
x_i = y_i ^ x_prev; // x_i = y_i ^ x_{i - n}
}
x |= (x_i << i); // 将计算得到的 x_i 放回 x 中
}
return x;
}
int main() {
unsigned long long data[11] = {
0x00002882D802120E, 0x0000028529A05954, 0x0000000486088C03, 0x00000C0FB3B55754,
0x00000C2B9B7F8651, 0x000000AE83FB054C, 0x000029ABF6DDCB15, 0x0000010E261FC807,
0x00002A82FE86D707, 0x00000E0CB79A5706, 0x0000330560890D06
};
// 先求解第一层
int i;
for(i=0;i<11;i++)
data[i] = left_Solve_x_correct(data[i], 15);
for(i=0;i<11;i++)
printf("0x%x,", data[i]);// 要从64转32,直接打印出来用python接着写了就不用转换了,比较方便
printf("\n");
}
用python求解第二层
import struct
# 输入的整数数组
a = [0x5105120e, 0x50a5954, 0x90c03, 0x181f5754, 0x18570651, 0x15d054c, 0x53574b15, 0x21c4807, 0x55055707, 0x1c195706, 0x660a0d06]
# 创建一个空字节数组
byte_array = bytearray()
# 将每个整数转换为字节并按小端序添加到字节数组中
for number in a:
byte_array.extend(struct.pack('<I', number)) # '<I'表示小端序的4字节无符号整数
# 输出结果
print(list(byte_array)) # 以列表形式输出字节数组
# 数组从0开始到43!
for i in range((len(byte_array) - 1)):
j = 42 - i
byte_array[j] = byte_array[j] ^ byte_array[j + 1]
flag = ''
for i in byte_array:
flag += chr(i)
print(flag[::-1]) # 反转