日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

红帽杯——childRE

發布時間:2025/3/21 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 红帽杯——childRE 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

查殼

拖進ida

main函數

signed __int64 main() {signed __int64 v0; // rax__int64 v1; // raxconst CHAR *v2; // r11__int64 v3; // r10__int64 v4; // r9const CHAR *v5; // r10signed __int64 v6; // rcx__int64 v7; // raxsigned __int64 result; // raxunsigned int v9; // ecx__int64 v10; // r9int v11; // er10__int64 v12; // r8__int128 v13; // [rsp+20h] [rbp-38h]__int128 v14; // [rsp+30h] [rbp-28h]v13 = 0i64;v14 = 0i64;sub_140001080("%s", &v13);v0 = -1i64;do++v0;while ( *((_BYTE *)&v13 + v0) );if ( v0 != 31 ){while ( 1 )Sleep(0x3E8u);}v1 = sub_140001280(&v13);v2 = name;if ( v1 ){sub_1400015C0(*(_QWORD *)(v1 + 8));sub_1400015C0(*(_QWORD *)(v3 + 16));v4 = dword_1400057E0;v2[v4] = *v5;dword_1400057E0 = v4 + 1;}UnDecorateSymbolName(v2, outputString, 0x100u, 0);v6 = -1i64;do++v6;while ( outputString[v6] );if ( v6 == 62 ){v9 = 0;v10 = 0i64;do{v11 = outputString[v10];v12 = v11 % 23;if ( a1234567890Qwer[v12] != *(_BYTE *)(v10 + 5368722552i64) )_exit(v9);if ( a1234567890Qwer[v11 / 23] != *(_BYTE *)(v10 + 5368722488i64) )_exit(v9 * v9);++v9;++v10;}while ( v9 < 0x3E );sub_140001020("flag{MD5(your input)}\n", v11 / 23, v12, v10);result = 0i64;}else{v7 = sub_1400018A0(std::cout);std::basic_ostream<char,std::char_traits<char>>::operator<<(v7, sub_140001A60);result = 0xFFFFFFFFi64;}return result; }

分析

觀察之后,這道題需要先看下面的,思路倒著回去:

sub_7FF6E48A1020("flag{MD5(your input)}\n", v11 / 23, v11 % 23, v10);

v11/23和v11 % 23根據這里可以算出,

v9 = 0;v10 = 0i64;do{v11 = outputString[v10];if ( a1234567890__Qw[v11 % 23] != *(_BYTE *)(v10 + 140698372945016i64) )_exit(v9);if ( a1234567890__Qw[v11 / 23] != *(_BYTE *)(v10 + 140698372944952i64) )_exit(v9 * v9);++v9;++v10;}

字符串a1234567890__Qw

unsigned char a1234567890__Qw[] = {0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 0x6F, 0x70, 0x5B, 0x5D, 0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4F, 0x50, 0x7B, 0x7D, 0x61, 0x73, 0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3B, 0x27, 0x41, 0x53, 0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3A, 0x22, 0x5A, 0x58, 0x43, 0x56, 0x42, 0x4E, 0x4D, 0x3C, 0x3E, 0x3F, 0x7A, 0x78, 0x63, 0x76, 0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2F, 0x00 };

字符串v10 + 140698372945016i64

unsigned char ida_chars[] = {0x35, 0x35, 0x35, 0x36, 0x35, 0x36, 0x35, 0x33, 0x32, 0x35, 0x35, 0x35, 0x35, 0x32, 0x32, 0x32, 0x35, 0x35, 0x36, 0x35, 0x35, 0x36, 0x35, 0x35, 0x35, 0x35, 0x32, 0x34, 0x33, 0x34, 0x36, 0x36, 0x33, 0x33, 0x34, 0x36, 0x35, 0x33, 0x36, 0x36, 0x33, 0x35, 0x34, 0x34, 0x34, 0x32, 0x36, 0x35, 0x36, 0x35, 0x35, 0x35, 0x35, 0x35, 0x32, 0x35, 0x35, 0x35, 0x35, 0x32, 0x32, 0x32, 0x00 };

字符串v10 + 140698372944952i64

unsigned char ida_chars[] = {0x28, 0x5F, 0x40, 0x34, 0x36, 0x32, 0x30, 0x21, 0x30, 0x38, 0x21, 0x36, 0x5F, 0x30, 0x2A, 0x30, 0x34, 0x34, 0x32, 0x21, 0x40, 0x31, 0x38, 0x36, 0x25, 0x25, 0x30, 0x40, 0x33, 0x3D, 0x36, 0x36, 0x21, 0x21, 0x39, 0x37, 0x34, 0x2A, 0x33, 0x32, 0x33, 0x34, 0x3D, 0x26, 0x30, 0x5E, 0x33, 0x26, 0x31, 0x40, 0x3D, 0x26, 0x30, 0x39, 0x30, 0x38, 0x21, 0x36, 0x5F, 0x30, 0x2A, 0x26, 0x00 };

strchr()函數包含于頭文件:#include<stdio.h>中;

函數原型為:char * strchr(char * str, char/int c);

函數功能為:在字符串str中尋找字符C第一次出現的位置,并返回其位置(地址指針),若失敗則返回NULL;

根據代碼反推出outputString為:

char outputString[63] = {0};int v10 = 0, yu, shang;do {shang = strchr(a1234567890__Qw, ida_chars1[v10]) - a1234567890__Qw;yu = strchr(a1234567890__Qw, ida_chars2[v10])- a1234567890__Qw;outputString[v10] = shang * 23 + yu;v10++;} while (v10 < 62);printf("%s", outputString);

private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *)

然后遇到了 UnDecorateSymbolName這個函數,然后才能求出v2,
函數功能: 函數反修飾指定已修飾的 C++ 符號名

UnDecorateSymbolName(v2, outputString, 0x100u, 0);

參考資料:

  • c/c++函數名修飾規則
  • UnDecorateSymbolName
  • 接下來需要把private: char * __thiscall R0Pxx::My_Aut0_PWN(unsigned char *)通過UnDecorateSymbolName轉換為v2.

    可以知道UnDecorateSymbolName第二個參數為未修飾的名字,第三個參數為長度,第四個參數為0表示完全修飾,第一個參數為輸出地址

  • 無論 __cdecl,__fastcall還是__stdcall調用方式,函數修飾都是以一個“?”開始,后面緊跟函數的名字。再后面是參數表的開始標識和依照參數類型代號拼出的參數表。
  • ?My_Aut0_PWN
  • 對于C++的類成員函數(其調用方式是thiscall),函數的名字修飾與非成員的C++函數稍有不同,首先就是在函數名字和參數表之間插入以“@”字 符引導的類名。
  • ?My_Aut0_PWN@R0Pxx
  • 其次是參數表的開始標識不同,公有(public)成員函數的標識是“@@QAE”,保護(protected)成員函數的標識是 “@@IAE”,私有(private)成員函數的標識是“@@AAE”,假設函數聲明使用了constkeyword,則對應的標識應分別為“@@QBE”,“@@IBE”和“@@ABE”。
  • ?My_Aut0_PWN@R0Pxx@@AAE
  • 接下來就是添加參數了,先加入函數返回值參數,函數的返回值類型為char *
  • 參數表的拼寫代號如下: 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

    ?My_Aut0_PWN@R0Pxx@@AAEPAD
  • 然后是參數的類型unsigned char *,也就是PAE
  • ?My_Aut0_PWN@R0Pxx@@AAEPADPAE
  • 參數表后以“@Z”標識整個名字的結束。假設該函數無參數,則以“Z”標識結束。
  • ?My_Aut0_PWN@R0Pxx@@AAEPADPAE@Z

    輸入ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ASCII碼65 ~ 95

    name也就是v2我們已經算出來了:

    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











    然后到了這里,

    v2也就是name,此時v4等于1E也就是30,然后v5對應的值是A,也就是65

    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,65

    Z0@tRAEyuP@xAAA?M_A0_WNPx@@EPDP

    flag{63b148e750fed3a33419168ac58083f5}

    總結

    以上是生活随笔為你收集整理的红帽杯——childRE的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。