
题目逻辑并不难理解,只是遇到了船新的知识点UnDecorateSymbolName。
题目逻辑;
- 验证输入长度是否为31
- 将输入打乱,其实就是将输入存储到树中
- UnDecorateSymbolName函数发挥作用,得到outputstring
- 校验
首先可以从最后的校验,得出outputstring的值,查看a4,a5两个比较数据在表a1的位置,outputstring的元素模23是a4的下标,/23是a5的下标
1 2 3 4 5 6 7 8 9 10 11 12 13
| data1 = '(_@4620!08!6_0*0442!@186%%0@3=66!!974*3234=&0^3&1@=&0908!6_0*&' data2 = '55565653255552225565565555243466334653663544426565555525555222' table = "1234567890-=!@#$%^&*()_+qwertyuiop[]QWERTYUIOP{}asdfghjkl;'ASDFGHJKL:\"ZXCVBNM<>?zxcvbnm,./"
positions_data1 = [table.index(c) for c in data1 if c in table] positions_data2 = [table.index(c) for c in data2 if c in table]
print("data1在table中的位置:", positions_data1) print("data2在table中的位置:", positions_data2)
for i in range(62): print(chr(positions_data1[i]+positions_data2[i]*23),end='') //private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *)
|
接下来就是由outputstring字符串反推出v5,核心是要理解UnDecorateSymbolName函数
一个函数名称经编译器修饰后会变成一段记录其各种信息(返回值、参数等)的字符串,具体规则可见c, c++函数名编译符号修饰符说明-CSDN博客
UnDecorateSymbolName的函数可以根据上述字符串,还原出我们声明的函数信息
1
| private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *) 与 ?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z 相对应
|
然后将字符串?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z顺序还原即可

1 2 3 4 5 6 7 8 9 10 11
| data11 = '$%8^&94*(0)_-52+q=we!6rt@yu#731' data22 = '1234567890-=!@#$%^&*()_+qwertyu' index=[]*31 for i in range(31): index.append(data11.find(data22[i])) print('')
flag0='?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z' for i in range(31): print(flag0[index[i]],end='') print(flag0)
|
//Z0@tRAEyuP@xAAA?M_A0_WNPx@@EPDP