buu [2019红帽杯]childRE wr

这个题是有一定难度的,它考的知识点不是特别常见,对于萌新来说。

解题步骤:

1、

下载完附件之后先进行查壳在这里插入图片描述
无壳,我们直接拖进ida64中。通过shift+f12查看字符串在这里插入图片描述
找到输出flag的字符串通过这个字符串直接进入这个题的关键函数f5查看伪c代码并进行初步分析
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

通过简单的分析我们可以先写脚本求出outputString[]中的内容


s3478 = "(_@4620!08!6_0*0442!@186%%0@3=66!!974*3234=&0^3&1@=&0908!6_0*&"
s3438 = "55565653255552225565565555243466334653663544426565555525555222"
s = '1234567890-=!@#$%^&*()_+qwertyuiop[]QWERTYUIOP{}asdfghjkl;,ASDFGHJKL:"ZXCVBNM<>?zxcvbnm,./'
p = ''
for i in range(62):
    p += chr(s.index(s3478[i]) + s.index(s3438[i])*23 )#这里有点难懂。先要理清楚a/b = c ...... d a除以b等于c余d 商是c 余数是d。则有c*b+d = a
                                                       #这里通过index()函数返回的值其实就是得到了v11%23的值d和v11/23的值c。然后再用c*23+d就得到了原来outputString中的值  
print (p)

输出为:private: char * _[添加链接描述](https://www.freesion.com/article/6515734088/)_thiscall R0Pxx::My_Aut0_PWN(unsigned char *)

2、

查看UnDecorateSymbolName()函数在这里插入图片描述

了解并理解这个函数是解题的重中之重!!!!

该函数第一个参数为输出地址、第二个参数为未修饰的名字、第三个参数为长度、第四个参数为0表示完全修饰

以下所有资料摘自:https://blog.csdn.net/liweigao01/article/details/78351464

资料一:
无论 __cdecl,__fastcall还是__stdcall调用方式,函数修饰都是以一个“?”開始,后面紧跟函数的名字。
再后面是參数表的開始标识和 依照參数类型代号拼出的參数表。

v2 = ?My_Aut0_PWN

资料二:
对于C++的类成员函数(其调用方式是thiscall)。
函数的名字修饰与非成员的C++函数稍有不同,首先就是在函数名字和參数表之间插入以“@”字 符引导的类名。

v2 = ?My_Aut0_PWN@R0Pxx

资料三:

其次是參数表的開始标识不同,公有(public)成员函数的标识是“@@QAE”,保护(protected)成员函数的标识是 “@@IAE”,私有(private)成员函数的标识是“@@AAE”,
假设函数声明使用了constkeyword,则对应的标识应分别为 “@@QBE”,“@@IBE”和“@@ABE”。

应为函数是private私有成员
所以v2 = ?My_Aut0_PWN@R0Pxx@@AAE
之后就是添加参数,先添加反回值类型参数,在添加函数形参。

资料四:
參数表的拼写代号例如以下所看到的: 
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
所以v2 = ?My_Aut0_PWN@R0Pxx@@AAEPAD
形参类型为unsigned char * 对应PAE
所以v2 = ?My_Aut0_PWN@R0Pxx@@AAEPADPAE

资料五:
參数表后以“@Z”标识整个名字的结束。假设该函数无參数,则 以“Z”标识结束。

最终v2 = ?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z

另一种方法:https://www.cnblogs.com/Mayfly-nymph/p/11869959.html

#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;
}

得到:?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z

3、

之后就是分析这里在这里插入图片描述
我们直接动态调试。在这一句下断点在这里插入图片描述
输入31位字符串
在这里插入图片描述

然后f7单步调试在这里插入图片描述
进入这个函数发现这里的name也就是v2我们已经算出来了,然后发现是一个result给他赋的值
汇编代码为
在这里插入图片描述
这里al就是result的值,记录al的值(这里需要有点耐心。慢慢来一步一步走。别漏了!)
在这里插入图片描述

得到0x50, 0x51, 0x48, 0x52, 0x53, 0x49, 0x44, 0x54, 0x55, 0x4a, 0x56, 0x57, 0x4b, 0x45, 0x42, 0x58, 0x59, 0x4c, 0x5a, 0x5b, 0x4d, 0x46, 0x5c, 0x5d, 0x4e, 0x5e, 0x5f, 0x4f, 0x47, 0x43,
接着f7得到在这里插入图片描述

v2就是name ,此时v4 = 1E
在这里插入图片描述
点进汇编查看此时v5为0x41
在这里插入图片描述

最后上脚本:

a = "?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z"
b = 0x50, 0x51, 0x48, 0x52, 0x53, 0x49, 0x44, 0x54, 0x55, 0x4a, 0x56, 0x57, 0x4b, 0x45, 0x42, 0x58, 0x59, 0x4c, 0x5a, 0x5b, 0x4d, 0x46, 0x5c, 0x5d, 0x4e, 0x5e, 0x5f, 0x4f, 0x47, 0x43, 0x41 
c = list(a)
for i in range(0,len(a)):
    c[b[i]-0x41] = a[i]
a = ''.join(c)
print(a)

得到:Z0@tRAEyuP@xAAA?M_A0_WNPx@@EPDP
最后在MD5 就行了!

flag{63b148e750fed3a33419168ac58083f5}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值