main函数如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
   | int __cdecl main(int argc, const char **argv, const char **envp) {   __int64 v3; // rax   __int64 v4; // rax   const CHAR *v5; // r11   __int64 v6; // r10   int v7; // er9   const CHAR *v8; // r10   __int64 v9; // rcx   __int64 *v10; // rax   unsigned int v12; // ecx   __int64 v13; // r9   __int64 v14; // r8   __int64 v15; // rdx   __int128 v16[2]; // [rsp+20h] [rbp-38h] BYREF
    memset(v16, 0, sizeof(v16));   sub_7FF6BF3D1080("%s", (const char *)v16);    // 输入字符串存入v14   v3 = -1i64;                                   // v3初始值为-1   do     ++v3;   while ( *((_BYTE *)v16 + v3) );               // 0123456789qwertyuiopasdfghjklzx   if ( v3 != 31 )                               // 限制输入字符串长度为31   {     while ( 1 )       Sleep(0x3E8u);   }   v4 = sub_7FF6BF3D1280(v16);   v5 = name;   if ( v4 )   {     sub_7FF6BF3D15C0(*(_QWORD *)(v4 + 8));     sub_7FF6BF3D15C0(*(_QWORD *)(v6 + 16));     v7 = dword_7FF6BF3D57E0;     v5[dword_7FF6BF3D57E0] = *v8;     dword_7FF6BF3D57E0 = v7 + 1;   }   UnDecorateSymbolName(v5, outputString, 0x100u, 0);   v9 = -1i64;   do     ++v9;   while ( outputString[v9] );   if ( v9 == 62 )   {     v12 = 0;     v13 = 0i64;     do     {       v14 = outputString[v13] % 23;       if ( a1234567890Qwer[v14] != a46200860044218[v13] )         _exit(v12);       v15 = outputString[v13] / 23;       if ( a1234567890Qwer[v15] != a55565653255552[v13] )         _exit(v12 * v12);       ++v12;       ++v13;     }     while ( v12 < 62 );     sub_7FF6BF3D1020("flag{MD5(your input)}\n", v15, v14, v13);     return 0;   }   else   {     v10 = sub_7FF6BF3D18A0(std::cout);     std::ostream::operator<<(v10, sub_7FF6BF3D1A60);     return -1;   } }
   | 
 
首先求出outputString
1 2 3 4 5 6 7 8 9
   | str1 = '1234567890-=!@#$%^&*()_+qwertyuiop[]QWERTYUIOP{}asdfghjkl;'+ chr(0x27) + 'A' + 'SDFGHJKL:"ZXCVBNM<>?zxcvbnm,./' str2 = '(_@4620!08!6_0*0442!@186%%0@3=66!!974*3234=&0^3&1@=&0908!6_0*&' str3 = '55565653255552225565565555243466334653663544426565555525555222' input = '' for i in range(62):     m = str1.index(str2[i])     n = str1.index(str3[i])     input += chr((n*23+m)%128) print(input)
  | 
 
运行结果为一个函数名private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *)
关键函数为UnDecorateSymbolName,功能为让函数更容易识别
方法一
参考链接:
C++ 编译器的函数名修饰规则 - yxysuanfa - 博客园 (cnblogs.com)
- 参考资料1
第二个参数为未修饰的名字,第三个参数为长度,第四个参数为0表示完全修饰,第一个参数为输出地址 
- 参考材料2
c++函数名的修饰更为复杂,提供的信息也更为丰富。
无论 __cdecl,__fastcall还是__stdcall调用方式,函数修饰都是以一个“?”开始,后面紧跟函数的名字。再后面是参数表的开始标识和依照参数类型代号拼出的参数表。 
v5 = ?My_Aut0_PWN
- 对于C++的类成员函数(其调用方式是thiscall),函数的名字修饰与非成员的C++函数稍有不同,首先就是在函数名字和参数表之间插入以“@”字 符引导的类名
 
v5 = ?My_Aut0_PWN@R0Pxx
- 其次是参数表的开始标识不同,公有(public)成员函数的标识是“@@QAE”,保护(protected)成员函数的标识是 “@@IAE”,私有(private)成员函数的标识是“@@AAE”,假设函数声明使用了constkeyword,则对应的标识应分别为“@@QBE”,“@@IBE”和“@@ABE”。
 
因为函数为 private,私有成员
所以 v5 = ?My_Aut0_PWN@R0Pxx@@AAE
后面就是添加参数了,先加入函数返回值参数,函数的返回值类型为char *
- 参数表的拼写代号如下:
X–void
D–char
E–unsigned char
F–short
H–int
I–unsigned int
J–long
K–unsigned long(DWORD)
M–float
N–double
_N–bool
U–struct
…
指针的方式有些特别。用PA表示指针,用PB表示const类型的指针。 
char *也就是PAD
所以 v5 = ?My_Aut0_PWN@R0Pxx@@AAEPAD
然后是参数的类型 unsigned char *,也就是PAE
所以 v5 = ?My_Aut0_PWN@R0Pxx@@AAEPADPAE
- 参数表后以“@Z”标识整个名字的结束。假设该函数无参数,则以“Z”标识结束。
 
所以最终v5 = ?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z
方法二
另外一种方法参考 Hk_Mayfly 师傅的博客:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
   | #include <iostream>
  class R0Pxx { public:     R0Pxx() {         My_Aut0_PWN((unsigned char*)"hello");     } private:     char* __thiscall My_Aut0_PWN(unsigned char*); };
  char* __thiscall R0Pxx::My_Aut0_PWN(unsigned char*) {     std::cout << __FUNCDNAME__ << std::endl;
      return 0; }
  int main() {     R0Pxx A;
      system("PAUSE");     return 0; }
 
   | 
 
接下来看上面的置换操作

可以采用动态调试打表的方法
输入串0123456789qwertyuiopasdfghjklzx查看输出

即可求得flag
1 2 3 4 5 6 7 8
   | import hashlib str1 = '0123456789qwertyuiopasdfghjklzx' decoded_str1 = 'yu7io83pa9sdq41fgwhje5klrzxt620' enc = '' str2 = '?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z' for i in range(len(str1)):     enc += str2[decoded_str1.index(str1[i])] print('flag{' + hashlib.md5(enc.encode("utf-8")).hexdigest() + '}')
   |