FILE
查殼后顯示無殼,拖進IDA:
運行程序時傳遞的第一個參數為一個文件名,並打開該文件。下面點進去encode函數分析一下:

for循環中每三個為一組,進行Base64的操作,接下來兩個if分別判斷Base64后的尾部是加一個“=”還是兩個“=”還是不加“=”。具體Base64編碼方式可以參考我的這篇博客:https://www.cnblogs.com/reddest/p/9554948.html。所以encode()是對傳入的字符串進行Base64編碼。回到主函數看看encode()被用在哪里了:

圈出來的部分就是判斷輸入的數據是否是正確的KEY了,並且可以發現並沒有用到encode()的返回值v11和v12,所以encode()就是個擺在那里打擾分析思路的。老夫40米巨劍何在。
根據異或的可逆性,v14[k] = k ^ flllag[k] ^ v13[k]。現在我們只缺v13數組中是哪些元素了,分析sub_400EB9():

sub_400EB9()的返回值根據sub_400E6A()來定,跟進分析sub_400E6A():

這里把傳入的某個元素判斷是否符合某個區間,然后分別返回不同的值。該函數傳進來的是sttr_home[]字符串中的元素,主函數中雙擊該字符串:

獲取了sttr_home的元素后寫個腳本跑出v13[],腳本如下:
1 #include <cstdio>
2 char str[110] = "664e06226625425d562e766e042d422c072c45692d125c7e6552606954646643";
3 int jdg(int id){
4 if(str[id] >= '0' && str[id] <= '9')
5 return str[id] - '0';
6 if(str[id] >= 'A' && str[id] <= 'F')
7 return str[id] - '7';
8 if(str[id] < 'a' && str[id] > 'f')
9 return 0xFFFFFFFFLL;
10 return str[id] - 'W';
11 }
12 int calc(int x, int y){
13 return 16 * jdg(x) + jdg(y);
14 }
15 int main(){
16 for(int i = 0;i < 64;i += 2){
17 printf("%d, ", calc(i, i + 1));
18 }
19 return 0;
20 }
接着寫出根據v14[k] = k ^ flllag[k] ^ v13[k]寫出相應腳本跑出KEY,並把KEY存到文件中,代碼如下:

接着用gcc編譯並運行后,把a.txt作為參數傳給file運行:

把a.txt的MD5在線計算一下:

把MD5加上flag{}就OKK啦!