[2019红帽杯]childRE
[2019红帽杯]childRE
64位,无壳
动态调试一下,发现没用,inputString是根据我们的输入形成的,但是错的(全0),没用;
有点绕,幸亏学了些数论,密码学,不然可能不会往这方面想
1 | s[a[i] % 23] = b[i] |
把inputString[v14]推出来:
1 | a123 = [ |
private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *)
不知道有什么用,继续逆推看inputString
怎么来的
AI了一下UnDecorateSymbolName(v5, outputString, 0x100u, 0);
,还有微软的解释[unDecorateSymbolName 函数 (dbghelp.h)](unDecorateSymbolName 函数 (dbghelp.h) - Win32 apps | Microsoft Learn)
v5,输入
outinputString,输出
100,长度
0x0000 对应
UNDNAME_COMPLETE
,启用完全取消评分
UnDecorateSymbolName
是一个用于取消修饰 C++ 符号名称的函数,属于 Windows 的 DbgHelp 库。它的主要作用是将经过编译器修饰的符号名称还原为更直观、更易读的形式。函数原型
1
2
3
4
5
6 DWORD WINAPI UnDecorateSymbolName(
_In_ PCTSTR DecoratedName,
_Out_ PTSTR UnDecoratedName,
_In_ DWORD UnDecoratedLength,
_In_ DWORD Flags
);参数说明
DecoratedName
输入参数,表示经过修饰的 C++ 符号名称。修饰的符号通常以问号(?
)开头。UnDecoratedName
输出参数,指向一个字符串缓冲区,用于存储取消修饰后的符号名称。UnDecoratedLength
指定UnDecoratedName
缓冲区的大小(以字符为单位),必须足够大以容纳取消修饰后的名称。Flags
用于控制取消修饰的行为。常见的标志包括:
UNDNAME_COMPLETE
(默认):完全取消修饰。UNDNAME_NAME_ONLY
:仅取消修饰主声明的名称。UNDNAME_NO_ACCESS_SPECIFIERS
:禁用成员的访问说明符。返回值
- 如果函数成功,返回值是
UnDecoratedName
缓冲区中的字符数(不包括 NULL 终止符)。- 如果函数失败,返回值为零,可以通过调用
GetLastError
获取更多错误信息。以下是一个简单的使用示例:
1
2
3
4
5
6
7
8
9
10
int main() {
char str[100] = "?getArgumentTypes@UnDecorator@@CG?AVDName@@XZ";
UnDecorateSymbolName(str, str, sizeof(str), UNDNAME_COMPLETE);
std::cout << str << std::endl;
return 0;
}在这个例子中,
UnDecorateSymbolName
将修饰后的符号名称?getArgumentTypes@UnDecorator@@CG?AVDName@@XZ
转换为更易读的形式
意思是UnDecorateSymbolName
将?getArgumentTypes@UnDecorator@@CG?AVDName@@XZ
(C++ 装饰符号,表示一个函数名)
会将其取消修饰为更易读的形式。类似于我们推出的private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *)
搜了一下,C++ 名称修饰的符号规则,有很多不同规则,装饰名称 |Microsoft 学习
文章最后提到可以使用 undname.exe 将修饰的名称转换为未修饰的形式。此示例显示了它的工作原理:
1 | C:\>undname ?func1@a@@AAEXH@Z |
C++ 编译器的函数名修饰规则 - yxysuanfa - 博客园
根据 Microsoft Visual C++ 的名称修饰规则,将
private: char* __thiscall R0Pxx::My_Aut0_PWN(unsigned char*)
转换为修饰后的状态,可以按照以下步骤进行:1. 类名和成员函数
- 类名:
R0Pxx
- 成员函数:
My_Aut0_PWN
- 访问修饰符:
private
- 调用约定:
__thiscall
(默认的类成员函数调用约定)2. 参数类型
- 参数:
unsigned char*
- 在 Microsoft Visual C++ 的修饰规则中,
unsigned char
通常表示为E
,指针用PA
表示。3. 返回类型
- 返回类型:
char*
char
表示为D
,指针用PA
表示。4. 修饰规则
- 私有成员函数的修饰符为
@@AAE
。- 参数列表以
@Z
结尾。5. 完整修饰后的名称
根据上述规则,
private: char* __thiscall R0Pxx::My_Aut0_PWN(unsigned char*)
的修饰后名称为:
1 >?My_Aut0_PWN@R0Pxx@@AAEPADPEAE@Z解释:
?My_Aut0_PWN@R0Pxx@@
:表示类R0Pxx
的私有成员函数My_Aut0_PWN
。AAE
:表示私有成员函数的修饰符。PAD
:表示返回类型为char*
。PEAE
:表示参数类型为unsigned char*
。@Z
:表示参数列表结束。如果需要进一步确认或解析修饰后的名称,可以使用工具如
undname
或UnDecorateSymbolName
API
?My_Aut0_PWN@R0Pxx@@AAEPADPEAE@Z
到这里就没头绪了,看了大佬的题解
2019 红帽杯 Re WP - Hk_Mayfly - 博客园
弱在了动态调试上,没发现result的变化,按照大佬的方法实际操作了一下
1 | from hashlib import md5 |