诺莫26
开始:
放入IDA,找到字符串:  找到main函数:
signed __int64 main()
{
signed __int64 v0;
__int64 v1;
const CHAR *v2;
__int64 v3;
__int64 v4;
const CHAR *v5;
signed __int64 v6;
__int64 v7;
signed __int64 result;
unsigned int v9;
__int64 v10;
int v11;
__int64 v12;
__int128 v13;
__int128 v14;
v13 = 0i64;
v14 = 0i64;
sub_140001080("%s", &v13);
v0 = -1i64;
do
++v0;
while ( *((_BYTE *)&v13 + v0) );
if ( v0 != 31 )
{
while ( 1 )
Sleep(0x3E8u);
}
v1 = sub_140001280(&v13);
v2 = name;
if ( v1 )
{
sub_1400015C0(*(_QWORD *)(v1 + 8));
sub_1400015C0(*(_QWORD *)(v3 + 16));
v4 = dword_1400057E0;
v2[v4] = *v5;
dword_1400057E0 = v4 + 1;
}
UnDecorateSymbolName(v2, outputString, 0x100u, 0);
v6 = -1i64;
do
++v6;
while ( outputString[v6] );
if ( v6 == 62 )
{
v9 = 0;
v10 = 0i64;
do
{
v11 = outputString[v10];
v12 = v11 % 23;
if ( a1234567890Qwer[v12] != *(_BYTE *)(v10 + 5368722552i64) )
_exit(v9);
if ( a1234567890Qwer[v11 / 23] != *(_BYTE *)(v10 + 5368722488i64) )
_exit(v9 * v9);
++v9;
++v10;
}
while ( v9 < 0x3E );
sub_140001020("flag{MD5(your input)}\n", v11 / 23, v12, v10);
result = 0i64;
}
else
{
v7 = sub_1400018A0(std::cout);
std::basic_ostream<char,std::char_traits<char>>::operator<<(v7, sub_140001A60);
result = 0xFFFFFFFFi64;
}
return result;
}
大概看了下,倒着解吧:
do
{
v11 = outputString[v10];
v12 = v11 % 23;
if ( a1234567890Qwer[v12] != *(_BYTE *)(v10 + 5368722552i64) )
_exit(v9);
if ( a1234567890Qwer[v11 / 23] != *(_BYTE *)(v10 + 5368722488i64) )
_exit(v9 * v9);
++v9;
++v10;
}
while ( v9 < 0x3E );
这里需要动态调试;  找数据; 
data1 = "1234567890-=!@#$%^&*()_+qwertyuiop[]QWERTYUIOP{}asdfghjkl;'ASDFGHJKL:\"ZXCVBNM<>?zxcvbnm,./"
data2 = '(_@4620!08!6_0*0442!@186%%0@3=66!!974*3234=&0^3&1@=&0908!6_0*&'
data3 = '55565653255552225565565555243466334653663544426565555525555222'
然后顺便看一下outputString:  看来就是我们输入的字符打乱了顺序; 那我们先逆向出被打乱顺序的输入字符,然后尝试找到原字符:
data1 = "1234567890-=!@#$%^&*()_+qwertyuiop[]QWERTYUIOP{}asdfghjkl;'ASDFGHJKL:\"ZXCVBNM<>?zxcvbnm,./"
data2 = '(_@4620!08!6_0*0442!@186%%0@3=66!!974*3234=&0^3&1@=&0908!6_0*&'
data3 = '55565653255552225565565555243466334653663544426565555525555222'
for i in range(62):
pos1 = data1.index(data2[i])
pos2 = data1.index(data3[i])
print(chr(pos2 * 23 + pos1), end = '')
print()
结果: private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *)
好像是一个类函数,outputString是在折这里生成的 查了这个函数; 转
那我们要了解c++的函数修饰方式: c++函数修饰名的方法
然后修饰后的函数应该是: ?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z 是咋样打乱的呢,我们用坐标跟踪: 然后再进行md5解码:
import hashlib
data1 = "1234567890-=!@#$%^&*()_+qwertyuiop[]QWERTYUIOP{}asdfghjkl;'ASDFGHJKL:\"ZXCVBNM<>?zxcvbnm,./"
data2 = '(_@4620!08!6_0*0442!@186%%0@3=66!!974*3234=&0^3&1@=&0908!6_0*&'
data3 = '55565653255552225565565555243466334653663544426565555525555222'
for i in range(62):
pos1 = data1.index(data2[i])
pos2 = data1.index(data3[i])
print(chr(pos2 * 23 + pos1), end = '')
print()
pos2 = "?@7AB83CD9EF:41GH;IJ<5KL=MN>620"
data4 = '?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z'
inp = [0]*31
for i in range(31):
inp[ord(pos2[i]) - ord('0')] = data4[i]
inp_a = "".join(inp)
inmd5 = hashlib.md5()
inmd5.update(inp_a.encode("utf-8"))
print(inmd5.hexdigest())
 了解到打乱的方式是二叉数;
说明: 判断?开头:  如果不是不会反修饰。所以我们动态调试的时候打乱的字符串是什么,outputString就是什么;当然也可以看上面的其他数据
|