https://buuoj.cn/challenges#[2019%E7%BA%A2%E5%B8%BD%E6%9D%AF]childRE

64 PE

输入 置换顺序存在另一个数组里 UnDecorateSymbolName 比较

先看最后的比较部分

if ( outputString_len == 62 )
{
  v12 = 0;
  v13 = 0i64;
  do
  {
    if ( a1234567890Qwer[outputString[v13] % 23] != a46200860044218[v13] )
      _exit(v12);
    if ( a1234567890Qwer[outputString[v13] / 23] != a55565653255552[v13] )
      _exit(v12 * v12);
    ++v12;
    ++v13;
  }
  while ( v12 < 0x3E );
  sub_7FF6B9151020("flag{MD5(your input)}\n");
  return 0;
}

逆向脚本:

str1 = "(_@4620!08!6_0*0442!@186%%0@3=66!!974*3234=&0^3&1@=&0908!6_0*&"
str2 = "55565653255552225565565555243466334653663544426565555525555222"
str3 = "1234567890-=!@#$%^&*()_+qwertyuiop[]QWERTYUIOP{}asdfghjkl;'ASDFGHJKL:\"ZXCVBNM<>?zxcvbnm,./"
 
tmp1=""
 
for i in range(0x3e):
    tmp1 += chr(str3.index(str1[i]) + str3.index(str2[i])*23)
 
print(tmp1)
private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *)

 UnDecorateSymbolName 函数,作用是按标准去修饰符号名字。修饰符号能增加数据信息,便于重载等高级操作。这里我们需要反过来修饰这个符号得到原来的输入

DWORD IMAGEAPI UnDecorateSymbolName(
  [in]  PCSTR name,
  [out] PSTR  outputString,
  [in]  DWORD maxStringLength,
  [in]  DWORD flags
);

https://learn.microsoft.com/en-us/windows/win32/api/dbghelp/nf-dbghelp-undecoratesymbolname UnDecorateSymbolName 定义

https://www.cnblogs.com/Moomin/p/15810785.html WP

C函数符号名称修饰方式

这里用 undname 工具尝试恢复出修饰的符号

undname ?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.

Undecoration of :- "?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z"
is :- "private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *)"

则原来为

?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z

input_trans1 = trans1(input);
name_ptr = name;
if ( input_trans1 )
{
  trans2((unsigned __int8 **)input_trans1[1]);
  trans2(*(unsigned __int8 ***)(v6 + 16));
  v7 = someindex;
  name_ptr[someindex] = *v8;
  someindex = v7 + 1;
}

接下来看看这段

试输入:

ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_

动调在:

loc_7FF734FF16B1:                       ; CODE XREF: main+74↑j
.text:00007FF734FF16B1 lea     rbx, outputString
.text:00007FF734FF16B8 xor     r9d, r9d                        ; flags
.text:00007FF734FF16BB mov     rdx, rbx                        ; outputString
.text:00007FF734FF16BE mov     r8d, 100h                       ; maxStringLength
.text:00007FF734FF16C4 mov     rcx, r11                        ; name
.text:00007FF734FF16C7 call    cs:UnDecorateSymbolName
.text:00007FF734FF16CD ; 36:   outputString_len = -1i64;
.text:00007FF734FF16CD mov     rcx, 0FFFFFFFFFFFFFFFFh
.text:00007FF734FF16D4 ; 38:     ++outputString_len;

查看 r11 得到变换后的为:(其实就是二叉树遍历前序转后续啦)

PQHRSIDTUJVWKEBXYLZ[MF\]N^_OGCA
st = "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_"
tred="PQHRSIDTUJVWKEBXYLZ[MF\]N^_OGCA"
 
for i in range(len(st)):
    print(st.index(tred[i]), end=",")

得到变换表:

15,16,7,17,18,8,3,19,20,9,21,22,10,4,1,23,24,11,25,26,12,5,27,28,13,29,30,14,6,2,0
import hashlib
 
trans =[15,16,7,17,18,8,3,19,20,9,21,22,10,4,1,23,24,11,25,26,12,5,27,28,13,29,30,14,6,2,0]
 
flag = [0]*len(trans)
 
traned_flag = "?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z"
 
for i in range(len(trans)):
    flag[trans[i]] = traned_flag[i]
    
    
flag = "".join(flag)
# md5 hash
print(hashlib.md5(flag.encode()).hexdigest())
 
63b148e750fed3a33419168ac58083f5