secret-galaxy-300
腦洞題,直接沒說法,就以後別碰這種腦洞題就行,,,,沒任何幫助
顯示界面
OD打開後,顯示這個鬼東西。然後就沒了。
ida靜態分析
看到上方輸出框有字符串,所以我們來查找字符串ctrl+F12
好熟悉的東西,但就是最後一個沒有輸出。盲猜是flag,然後根據交叉引用
去找源地址。
找到了地址是0x4013ED
,把它放入edx
僞代碼是這個東西,啥也看不到,動用OD吧,動調一下
OD動調
拖動進去之後,直接ctrl +G 輸入地址0x4013ED
,然後下個斷點,
不斷地F8
之後,到達函數末端時,再回關鍵點看看
flag:aliens_are_around_us
Replace
首先呢,它屬於加了upx
殼的,需要用脫殼工具處理一下,然後直接找到核心僞代碼,進行爆破。。
核心代碼
首先呢
三個if判斷作用
- 最外面的if是用來判斷輸入字符的個數,以此作爲第一層判斷
- 第二層if和第三層if用來篩選
byte_402150
和byte_402151
,其實它倆都是同一個數組,只是找偏移的時候在[ ]裏面多加1就行,
一個while循環作用
- 因爲
byte_402150
數組和byte_4021A0
的長度不一樣,而且其中一個數組的長度挺長的,所以直接用個無限循環,直到賦值完之後直接break即可
接下來上數組:
byte_402150
好傢伙,這是一個字符數組,然後呢,該怎麼找出來呢?
簡單,直接找hex View-1
找準起始位置,找準結束位置,把16進制數據,全部拷貝出來,然後依次加上0x
,說實話,把我手都加麻了。。。。我在這裏直接拷貝出來給你們吧,否則你們也會麻。。。
0x32,0x61, 0x34, 0x39, 0x66, 0x36, 0x39, 0x63, 0x33, 0x38, 0x33,0x39,0x35,
0x63, 0x64, 0x65, 0x39, 0x36, 0x64, 0x36, 0x64, 0x65, 0x39, 0x36, 0x64, 0x36,
0x66,0x34,0x65, 0x30, 0x32, 0x35, 0x34, 0x38, 0x34, 0x39, 0x35, 0x34, 0x64,
0x36, 0x31, 0x39, 0x35,0x34,0x34, 0x38,0x64, 0x65, 0x66, 0x36, 0x65, 0x32,
0x64, 0x61, 0x64, 0x36, 0x37, 0x37, 0x38,0x36,0x65, 0x32, 0x31, 0x64, 0x35,
0x61, 0x64, 0x61, 0x65, 0x36, 0x00
接下來上數組:
byte_4021A0
找出方法一樣的,
往下看,一眼望不到邊。。難不成我們得一個一個慢慢複製?不可能,直接hex窗口
把它們拷貝出來之後,加上0x
,說實話,把我手都加麻了。。。。我在這裏直接拷貝出來給你們吧,否則你們也會麻。。。
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE,
0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4,
0xA2, 0xAF,0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7,
0xCC, 0x34, 0xA5, 0xE5, 0xF1,0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 0x23, 0xC3,
0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,0xEB, 0x27, 0xB2, 0x75, 0x09,
0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3,0x29,
0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A,
0xCB, 0xBE, 0x39,0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB, 0x43,
0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F,0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3,
0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21,0x10, 0xFF,
0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7,
0x7E, 0x3D,0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A,
0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14,0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A,
0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62,0x91, 0x95, 0xE4,
0x79, 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4,
0xEA,0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4,
0xC6, 0xE8, 0xDD, 0x74, 0x1F,0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5,
0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9,0x86, 0xC1, 0x1D,
0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87,
0xE9,0xCE, 0x55, 0x28, 0xDF, 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42,
0x68, 0x41, 0x99, 0x2D, 0x0F,0xB0, 0x54, 0xBB, 0x16
難點部分
這裏呢,強調一下v4+v2
。這裏v4
是一個偏移,v2
是我們輸入字符的起始地址,然後這個地址大小是 一個字節,(signed int)*
後面這一字節的地址值又被強制轉換成有符號型的數據,即-128~127,根據前面所知,這裏依然是一個地址偏移,
所以直接0~127(即我們輸入的值),又因爲此時不知道,所以我們只能通過循環找出
提示一下,這裏是byte_4021A0[16 * (((signed int)*(_BYTE *)(v4 + v2) >> 4) % 16)]
相當於a[i],但是前面還有一個&
,此時又被變成一個地址值,然後加後面的 (16 * *(_BYTE *)(v4 + v2) >> 4) % 16)
,道理同前面一樣。
實現代碼
#include <iostream>
using namespace std;
int main()
{
int a[] = {
0x32,0x61, 0x34, 0x39, 0x66, 0x36, 0x39, 0x63, 0x33, 0x38, 0x33,
0x39,0x35, 0x63, 0x64, 0x65, 0x39, 0x36, 0x64, 0x36, 0x64, 0x65, 0x39, 0x36, 0x64, 0x36, 0x66,
0x34,0x65, 0x30, 0x32, 0x35, 0x34, 0x38, 0x34, 0x39, 0x35, 0x34, 0x64, 0x36, 0x31, 0x39, 0x35,
0x34,0x34, 0x38,0x64, 0x65, 0x66, 0x36, 0x65, 0x32, 0x64, 0x61, 0x64, 0x36, 0x37, 0x37, 0x38,
0x36,0x65, 0x32, 0x31, 0x64, 0x35, 0x61, 0x64, 0x61, 0x65, 0x36, 0x00 };
int b[] = {
0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B,
0xFE, 0xD7, 0xAB, 0x76, 0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF,
0x9C, 0xA4, 0x72, 0xC0, 0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1,
0x71, 0xD8, 0x31, 0x15, 0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2,
0xEB, 0x27, 0xB2, 0x75, 0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3,
0x29, 0xE3, 0x2F, 0x84, 0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39,
0x4A, 0x4C, 0x58, 0xCF, 0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F,
0x50, 0x3C, 0x9F, 0xA8, 0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21,
0x10, 0xFF, 0xF3, 0xD2, 0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D,
0x64, 0x5D, 0x19, 0x73, 0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14,
0xDE, 0x5E, 0x0B, 0xDB, 0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62,
0x91, 0x95, 0xE4, 0x79, 0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA,
0x65, 0x7A, 0xAE, 0x08, 0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F,
0x4B, 0xBD, 0x8B, 0x8A, 0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9,
0x86, 0xC1, 0x1D, 0x9E, 0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9,
0xCE, 0x55, 0x28, 0xDF, 0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F,
0xB0, 0x54, 0xBB, 0x16 };
char flag[35];
int v6, v9, v8;
int i = 0;
int k = 0;
int a1;
while (1) {
if (a[2 * i] < 48 || a[2 * i] >57)
v6 = a[2 * i] - 87;
else
v6 = a[2 * i] - 48;
v8 = 16 * v6;
if (a[2 * i + 1] < 48 || a[2 * i + 1] >57)
v9 = a[2 * i + 1] - 87;
else
v9 = a[2 * i + 1] - 48;
for (int j = 0; j<127; j++) {
a1 = (j >> 4) % 16;
if (((v8 + v9) ^ 0x19) == b[16 * a1 + ((16 * j >> 4) % 16)])
{
flag[k] = char(j);
cout << flag[k];
k++;
break;
}
}
i += 1;
if (i >= 35)
break;
}
}
注意
if (((v8 + v9) ^ 0x19) == b[16 * a1 + ((16 * j >> 4) % 16)])
這行代碼絕對不能寫成
if ((v8 + v9) ^ 0x19 == b[16 * a1 + ((16 * j >> 4) % 16)])
這樣,必須用括號把左邊括起來,因爲運算符優先級原因。。
沒加括號的我,一直在這裏if直接一直成立!!!!!!!!輸出了個寂寞!!!折騰了兩個小時,就爲了個括號!!!!!!!!!!!!一生恥辱!!寫出逆向代碼的時間還沒找括號時間一半多。。。。。