BUUCTF-RE-[2019紅帽杯]easyRE
搜尋關鍵字串
Shift+F12
雙擊進去 Ctrl+x
交叉引用的地方
F5分析
signed __int64 sub_4009C6() { __int64 v0; // rax signed __int64 result; // rax unsigned __int64 v2; // rax __int64 v3; // rax const __m128i *v4; // ST10_8 const __m128i *v5; // ST18_8 const __m128i *v6; // ST20_8 const __m128i *v7; // ST28_8 const __m128i *v8; // ST30_8 const __m128i *v9; // ST38_8 const __m128i *v10; // ST40_8 const __m128i *v11; // ST48_8 const __m128i *v12; // ST50_8 __int64 v13; // ST58_8 int i; // [rsp+Ch] [rbp-114h] char v15; // [rsp+60h] [rbp-C0h] char v16; // [rsp+61h] [rbp-BFh] char v17; // [rsp+62h] [rbp-BEh] char v18; // [rsp+63h] [rbp-BDh] char v19; // [rsp+64h] [rbp-BCh] char v20; // [rsp+65h] [rbp-BBh] char v21; // [rsp+66h] [rbp-BAh] char v22; // [rsp+67h] [rbp-B9h] char v23; // [rsp+68h] [rbp-B8h] char v24; // [rsp+69h] [rbp-B7h] char v25; // [rsp+6Ah] [rbp-B6h] char v26; // [rsp+6Bh] [rbp-B5h] char v27; // [rsp+6Ch] [rbp-B4h] char v28; // [rsp+6Dh] [rbp-B3h] char v29; // [rsp+6Eh] [rbp-B2h] char v30; // [rsp+6Fh] [rbp-B1h] char v31; // [rsp+70h] [rbp-B0h] char v32; // [rsp+71h] [rbp-AFh] char v33; // [rsp+72h] [rbp-AEh] char v34; // [rsp+73h] [rbp-ADh] char v35; // [rsp+74h] [rbp-ACh] char v36; // [rsp+75h] [rbp-ABh] char v37; // [rsp+76h] [rbp-AAh] char v38; // [rsp+77h] [rbp-A9h] char v39; // [rsp+78h] [rbp-A8h] char v40; // [rsp+79h] [rbp-A7h] char v41; // [rsp+7Ah] [rbp-A6h] char v42; // [rsp+7Bh] [rbp-A5h] char v43; // [rsp+7Ch] [rbp-A4h] char v44; // [rsp+7Dh] [rbp-A3h] char v45; // [rsp+7Eh] [rbp-A2h] char v46; // [rsp+7Fh] [rbp-A1h] char v47; // [rsp+80h] [rbp-A0h] char v48; // [rsp+81h] [rbp-9Fh] char v49; // [rsp+82h] [rbp-9Eh] char v50; // [rsp+83h] [rbp-9Dh] char v51[32]; // [rsp+90h] [rbp-90h] int v52; // [rsp+B0h] [rbp-70h] char v53; // [rsp+B4h] [rbp-6Ch] char v54; // [rsp+C0h] [rbp-60h] char v55; // [rsp+E7h] [rbp-39h] char v56; // [rsp+100h] [rbp-20h] unsigned __int64 v57; // [rsp+108h] [rbp-18h] v57 = __readfsqword(0x28u); v15 = 73; v16 = 111; v17 = 100; v18 = 108; v19 = 62; v20 = 81; v21 = 110; v22 = 98; v23 = 40; v24 = 111; v25 = 99; v26 = 121; v27 = 127; v28 = 121; v29 = 46; v30 = 105; v31 = 127; v32 = 100; v33 = 96; v34 = 51; v35 = 119; v36 = 125; v37 = 119; v38 = 101; v39 = 107; v40 = 57; v41 = 123; v42 = 105; v43 = 121; v44 = 61; v45 = 126; v46 = 121; v47 = 76; v48 = 64; v49 = 69; v50 = 67; //v15-v50這是一個字串陣列 memset(v51, 0, sizeof(v51)); v52 = 0; v53 = 0; sub_4406E0(0LL, (__int64)v51); v53 = 0; LODWORD(v0) = sub_424BA0((const __m128i *)v51); if ( v0 == 36 ) { for ( i = 0; ; ++i ) { LODWORD(v2) = sub_424BA0((const __m128i *)v51); if ( i >= v2 ) break; if ( (unsigned __int8)(v51[i] ^ i) != *(&v15 + i) ) //這裡做了一次陣列的異或 { result = 0xFFFFFFFELL; goto LABEL_13; } } sub_410CC0((const __m128i *)"continue!"); memset(&v54, 0, 0x40uLL); v56 = 0; sub_4406E0(0LL, (__int64)&v54); //v54是又一次輸入 v55 = 0; LODWORD(v3) = sub_424BA0((const __m128i *)&v54); if ( v3 == 39 ) { v4 = (const __m128i *)sub_400E44((const __m128i *)&v54);//這裡反覆套用做了十次的base64加密 v5 = (const __m128i *)sub_400E44(v4); v6 = (const __m128i *)sub_400E44(v5); v7 = (const __m128i *)sub_400E44(v6); v8 = (const __m128i *)sub_400E44(v7); v9 = (const __m128i *)sub_400E44(v8); v10 = (const __m128i *)sub_400E44(v9); v11 = (const __m128i *)sub_400E44(v10); v12 = (const __m128i *)sub_400E44(v11); v13 = sub_400E44(v12); if ( !(unsigned int)sub_400360(v13, (__int64)off_6CC090) )//這裡是判斷v13這個結果base64處理之後的值和off_6CC090是不是相等 { sub_410CC0((const __m128i *)"You found me!!!"); sub_410CC0((const __m128i *)"bye bye~"); } result = 0LL; } else { result = 0xFFFFFFFDLL; } } else { result = 0xFFFFFFFFLL; } LABEL_13: if ( __readfsqword(0x28u) != v57 ) sub_444020(); return result; } /* Orphan comments: Vm0wd2VHUXhTWGhpUm1SWVYwZDRWVll3Wkc5WFJ */
sub_400E44:這表明做了Base64加密 這個陣列就是v54的這個陣列
off_6CC090的值是:
把off_6CC090的值解密10次base64之後,得到的內容是網址:https://bbs.pediy.com/thread-254172.htm
這個網址看起來沒東西,flag就不是在這裡。不對勁
回到這裡 發現 有兩組資料 沒見過的 Ctrl+X
它們用的是同一段的函式
再次交叉引用 可以看到 出現了_fini. 這樣的字樣
.fini段的解釋是 此節區包含了可執行的指令,是程序終止程式碼的一部分。程式正常退出時,系統將安排執行這裡的程式碼。
![](https://img2020.cnblogs.com/blog/1775199/202007/1775199-20200720143131041-2075554377.png) 這一段裡面有資料 我們分析該段 ``` unsigned __int64 sub_400D35() { unsigned __int64 result; // rax unsigned __int64 v1; // rt1 unsigned int v2; // [rsp+Ch] [rbp-24h] signed int i; // [rsp+10h] [rbp-20h] signed int j; // [rsp+14h] [rbp-1Ch] unsigned int v5; // [rsp+24h] [rbp-Ch] unsigned __int64 v6; // [rsp+28h] [rbp-8h]v6 = __readfsqword(0x28u);
v2 = sub_43FD20(0LL) - qword_6CEE38;
for ( i = 0; i <= 1233; ++i )
{
sub_40F790(v2);
sub_40FE60();
sub_40FE60();
v2 = (unsigned __int64)sub_40FE60() ^ 0x98765432;
}
v5 = v2;
if ( ((unsigned __int8)v2 ^ byte_6CC0A0[0]) == ‘f’ && (HIBYTE(v5) ^ (unsigned __int8)byte_6CC0A3) == 'g') //通過這裡反向推出v2和v5的值
{
for ( j = 0; j <= 24; ++j )
sub_410E90((unsigned __int8)(byte_6CC0A0[j] ^ *((_BYTE *)&v5 + j % 4)));
}
v1 = __readfsqword(0x28u);
result = v1 ^ v6;
if ( v1 != v6 )
sub_444020();
return result;
}
Byte_6CC0A0[]=[0x40,0x35,0x20] Byte_6CC0A3[]=[0x56,0x5D,0x18,0x22,0x45,0x17,0x2F,0x24,0x6E,0x62,0x3C,0x27,0x54,0x48,0x6C,0x24,0x6E,0x72,0x3C,0x32,0x45,0x5B] 我們可以看到就是v2和Byte_6CC0A0[0]異或後等於'f' v5和Byte_6CC0A3異或後等於'g' 合理推測v2v3v4v5 四個應該是flag 那麼它們對應的應該是Byte_6CC0A0[0]-[3]和Byte_6CC0A3[0] 那麼flag的值就應該在Byte_6CC0A3[]裡面一共25個字元 後面這段資料咋找的思路: 一般出題人不會無緣無故給一段沒用的資料 這段程式碼是會執行的,.fini段,是在程式的結束之後執行。瞭解了init,fini段後基本上都會檢查這兩個段的。 [V&N2020 公開賽]strangeCpp這道題,也是把資料藏起來了沒有引用,需要找。 寫程式的時候一般不會新增無用資料,所以發現有意義的資料看看交叉引用啥的…… 參考來自[](<https://blog.csdn.net/Palmer9/article/details/103940709> ) #解題指令碼 ##第一組異或
key = [73,111,100,108,62,81,110,98,40,111,99,121,127,121,46,105,127,100,96,51,119,125,119,101,107,57,123,105,121,61,126,121,76,64,69,67]
flag = ''
for i in range(len(key)):
flag+=chr(key[i]^i)
print(flag)
##第二組
v5=''
enc='flag'
key1=[0x40,0x35,0x20,0x56,0x5D,0x18,0x22,0x45,0x17,0x2F,0x24,0x6E,0x62,0x3C,0x27,0x54,0x48,0x6C,0x24,0x6E,0x72,0x3C,0x32,0x45,0x5B]
for i in range(4):
v5+=chr(key1[i]^ord(enc[i]))
print(v5)
flag2=''
for i in range(25):
flag2+=chr(key1[i]^ord(v5[i%4]))
print(flag2)