C++写的东西,太长了
第1部分读入9个数
v3 = std::operator<<<std::char_traits<char>>(&std::cout, "give me your key!");
std::ostream::operator<<(v3, &std::endl<char,std::char_traits<char>>);
for ( i = 0; i <= 8; ++i )
{
std::istream::operator>>(&std::cin, &keys[i]);// int[9]
std::to_string((std::__cxx11 *)v22, keys[i]);
std::string::operator+=(v18, v22);
std::string::~string(v22);
}
第2块作了个lamba操作
v4 = std::vector<int>::end(v20);
v5 = std::vector<int>::begin(v20);
std::for_each<__gnu_cxx::__normal_iterator<int *,std::vector<int>>,main::{lambda(int &)#1}>(v5, v4);// 1
他调用了一个for_each的方法
__int64 __fastcall std::for_each<__gnu_cxx::__normal_iterator<int *,std::vector<int>>,main::{lambda(int &)#1}>(
__int64 a1,
__int64 a2)
{
unsigned int v2; // ebx
__int64 v3; // rax
char v5; // [rsp+Fh] [rbp-21h] BYREF
__int64 v6; // [rsp+10h] [rbp-20h] BYREF
__int64 v7[3]; // [rsp+18h] [rbp-18h] BYREF
v7[0] = a1;
v6 = a2;
while ( (unsigned __int8)__gnu_cxx::operator!=<int *,std::vector<int>>(v7, &v6) )
{
v3 = __gnu_cxx::__normal_iterator<int *,std::vector<int>>::operator*(v7);
main::{lambda(int &)#1}::operator()(&v5, v3);
__gnu_cxx::__normal_iterator<int *,std::vector<int>>::operator++(v7);
}
return v2;
}
里边调用另外一个lamba,对输入数字进行第1次加密 异或1
_DWORD *__fastcall main::{lambda(int &)#1}::operator()(__int64 a1, _DWORD *a2)
{
_DWORD *result; // rax
result = a2;
*a2 ^= 1u;
return result;
}
第2部分是个循环,对每个数字调用depart和lambda func,lamdba check分别是分解因子,替换和比较
while ( (unsigned __int8)__gnu_cxx::operator!=<int *,std::vector<int>>(&v16, &v15) )
{
v25 = *(_DWORD *)__gnu_cxx::__normal_iterator<int *,std::vector<int>>::operator*(&v16);
std::allocator<char>::allocator(&v23);
std::string::basic_string(v14, &unk_500E, &v23);
std::allocator<char>::~allocator(&v23);
depart(v25, v14); // 求因子
{lambda(std::string &)#1}::operator()(&func, v14);// OlzEAsGTBq= => 0123456789空格
std::string::basic_string(v24, v14);
v6 = {lambda(std::string,int)#2}::operator()(&check, v24, v31) ^ 1;// 与ans比较
std::string::~string(v24);
if ( v6 )
{
v7 = std::operator<<<std::char_traits<char>>(&std::cout, "Wrong password!");
std::ostream::operator<<(v7, &std::endl<char,std::char_traits<char>>);
system("pause");
exit(0);
}
++v31;
std::string::~string(v14);
__gnu_cxx::__normal_iterator<int *,std::vector<int>>::operator++(&v16);
}
递归求因子
__int64 __fastcall depart(int a1, __int64 a2)
{
char v3[32]; // [rsp+20h] [rbp-60h] BYREF
char v4[40]; // [rsp+40h] [rbp-40h] BYREF
int i; // [rsp+68h] [rbp-18h]
int v6; // [rsp+6Ch] [rbp-14h]
v6 = a1;
for ( i = 2; std::sqrt<int>((unsigned int)a1) >= (double)i; ++i )
{
if ( !(a1 % i) )
{
v6 = i;
depart((unsigned int)(a1 / i), a2);
break;
}
}
std::to_string((std::__cxx11 *)v4, v6); // 最小素因子
std::operator+<char>(v3, &asc_500C, v4); // 空格+str(p)
std::string::operator+=(a2, v3);
std::string::~string(v3);
return std::string::~string(v4);
}
替换
__int64 __fastcall {lambda(std::string &)#1}::operator()(__int64 a1, __int64 a2)
{
......
v25 = 79; // OlzEAsGTBq=
// 0123456789空格
v26 = 48;
v2 = std::string::end(a2);
v3 = std::string::begin(a2);
std::replace<__gnu_cxx::__normal_iterator<char *,std::string>,char>(v3, v2, &v26, &v25);
......
}
比对
_BOOL8 __fastcall {lambda(std::string,int)#2}::operator()(__int64 a1, __int64 a2, int a3)
{
const char *v3; // rbx
const char *v4; // rax
v3 = (const char *)std::string::c_str((char *)&ans[abi:cxx11] + 32 * a3);
v4 = (const char *)std::string::c_str(a2);
return strcmp(v4, v3) == 0;
}
逆向查引用找ans的来源
int __fastcall __static_initialization_and_destruction_0(int a1, int a2)
{
......
if ( a1 == 1 && a2 == 0xFFFF )
{
std::ios_base::Init::Init((std::ios_base::Init *)&std::__ioinit);
__cxa_atexit((void (__fastcall *)(void *))&std::ios_base::Init::~Init, &std::__ioinit, &_dso_handle);
std::allocator<char>::allocator(&v3);
std::string::basic_string(&ans[abi:cxx11], "=zqE=z=z=z", &v3);
std::allocator<char>::~allocator(&v3);
std::allocator<char>::allocator(&v4);
std::string::basic_string((char *)&ans[abi:cxx11] + 32, "=lzzE", &v4);
std::allocator<char>::~allocator(&v4);
......
return __cxa_atexit(_tcf_0, 0LL, &_dso_handle);
}
return result;
}
最后提示flag的组成
v9 = std::operator<<<std::char_traits<char>>(&std::cout, "flag:MRCTF{md5(");
v10 = std::operator<<<char>(v9, v18);
v11 = std::operator<<<std::char_traits<char>>(v10, ")}");
std::ostream::operator<<(v11, &std::endl<char,std::char_traits<char>>);
v12 = std::operator<<<std::char_traits<char>>(
&std::cout,
"md5()->{32/upper case/put the string into the function and transform into md5 hash}");
逆向程序
ans = ["=zqE=z=z=z", "=lzzE", "=ll=T=s=s=E", "=zATT", "=s=s=s=E=E=E", "=EOll=E", "=lE=T=E=E=E", "=EsE=s=z", "=AT=lE=ll"]
str1 = 'OlzEAsGTBq='
str2 = '0123456789*'
fstr = ''
for s in ans:
t = '1'+''.join([str2[str1.index(c)] for c in s ])
fstr += str(eval(t) ^ 1)
print(eval(t))
from hashlib import md5
#from string import toupper
print(md5(fstr.encode()).hexdigest().upper())
#4367FB5F42C6E46B2AF79BF409FB84D3
#flag{4367FB5F42C6E46B2AF79BF409FB84D3}