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
这里用 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