20181020學習筆記——解決的第一個Reverse題目
解決的第一個Reverse題目
題目描述
題目給了一個名為rev1的檔案,沒有後綴。
檔案的下載地址:
結題過程
第一次做Reverse題目,一臉矇蔽,我首先嚐試把字尾改為.exe,結果,不能執行。。。。可能不是Windows系統檔案。
我轉到虛擬機器裡,開啟Linux系統,執行“file rev1”,結果,果然是Linux下的可執行檔案,是ELF檔案。
然後我在終端執行“./rev1”,結果拒絕訪問。
修改許可權,在終端執行“chmod 777 rev1”
再次執行“./rev1”,執行成功了,終端顯示"Please input your flag:",隨便輸入,結果果然是wrong。
好吧,其實,上述步驟和解決這道題沒有半毛錢關係,這是我在完全小白的情況下對此題的摸索,接下來進入正題。
Windows下逆向分析強有力的工具是OD+IDA,我之前的部落格中提供了下載連結。題目提供的是ELF檔案,是無法使用OD的,好在這道題僅僅使用IDA就可以了。
- 把檔案拖入IDA中,執行ctrl+F5,得到程式的虛擬碼。
- 開啟虛擬碼檢視。虛擬碼的核心內容如下:
//這是main函式 __int64 __fastcall main(__int64 a1, char **a2, char **a3) { __int64 result; // [email protected] __int64 v4; //
分析得到,主函式中輸入了一個長度為32的字串,然後呼叫子函式對字串進行處理(子函式返回一個判斷),所以最關鍵的部分就是分析子函式到底幹了啥。
-
我們來分析一下子函式到底幹了啥。子函式的虛擬碼如下:
signed __int64 __fastcall sub_400686(__int64 a1) { signed int i; // [sp+Ch] [bp-Ch]@1 for ( i = 0; i <= 31; ++i ) { if ( (char)(*(_BYTE *)(i + a1) ^ byte_400818[i]) != i ) return 0LL; } return 1LL; }
定義了一個變數i(i用來控制迴圈),然後進入了一個for迴圈。觀察for迴圈中if語句的條件,“^”是異或運算,(i+a1)實際上就是在從傳入的字串變數中一次取值(第1個字元、第2個字元、第3個字元......一直到第31個字元),取出來以後和byte_400818[i](是定義的全域性變數)進行了異或運算,判斷異或運算的結果,滿足條件,則繼續迴圈,不滿足,則返回false。所以,每個字元的值怎麼求呢?其實很簡單,a^b = c,那麼b^c =a,所以(a1+i)=byte_400818[i]^i。
-
最後程式設計求出flag就行了。
#include<stdio.h> int a[]={102,109,99,100,127,60,54,114,87,66,100,59,123,82,124,60,102,84,96,96,39,74,73,127,113,88,82,114,125,117,42,98,0}; void test(){ int i; for(i=0;i<32;i++){ printf("%c",a[i]^i); } printf("\n"); } int main(){ test(); return 0; }
flag{90u_Kn0w_r3vErs3__hiAHiah4}