re | [安洵杯 2019]game


這是一道x64的elf逆向題。

先進入主函數,定位到輸入輸出和一個叫sudoku的全局變量數組:

sudoku的意思是數獨,所以定位到sudoku數組的位置,將其提出來:

這里我犯了一個錯誤,這些數據在內存中存儲的時候是小端序的int,我提出來以后為了簡潔只寫了兩位,導致我后面分析的時候一直把它當成了char,最后才反應過來問題所在【真的憨憨】

不管那么多了,再通過主函數依次跟進分析一下那些函數的作用:

 

trace和check就跳過了,功能很明顯能猜測出來。

進入check1:

這里用了一個叫做ollvm的操作來混淆代碼,以前也遇到過很多次,不過今天才知道原來叫這個名字。

反正一步一步跟就完事兒了,推出來3個加密過程:

1先交換前后順序【0】---【20】,【1】---【21】。。。。

2兩個一組兩兩交換

3最后做位運算:a1[v12] = (a1[v12] & 0xF3 | ~a1[v12] & 0xC) - 20

*注:以上是程序對我們輸入的字符串進行的反向操作。

再跟進check3:

關鍵點在於check2函數來判斷是否正確,所以再跟進check2【又是混淆加密過得,所以這里只放關鍵點了】:

2的作用是將v16(已經將我們字符串插入的數組)放入dog3數組;

1的作用是將dog3與sudoku對比。

真正的關鍵點在下面:

這里v16是int數組,用yourinput - 48的目的是轉化為數字,【呼應前文】我一開始把最終的對比以為成char型的對比('1','2'..這樣),所以困住了好一會兒。

反正全部分析完了,思路就很明確了:

1.填數獨:

這里我上網找了個工具幫我算,然后把填的空弄了出來:

4693641762894685722843556137219876255986

2.數字+48轉字符

3.重復一次位運算【這里原因不清楚的話自己推一下就知道了】

4.兩兩交換

5.前后倒置

上代碼:

 1 void main(){
 2     char a[] = "4693641762894685722843556137219876255986";
 3     int len = strlen(a);
 4     char tmp;
 5     for (int i = 0; i < len; i ++){
 6         //這一步我一開始沒注意數據類型的轉化。。。
 7         a[i] = (a[i]-'0') + 48;
 8         //正向-》a[i] = (a[i] & 0xF3 | ~a[i] & 0xC) - 20;
 9         //反向操作
10         tmp = a[i] + 20;
11         tmp = ((tmp & 0xF3) | (~tmp & 0xC)) ;  //再次取反倒回去
12         a[i] = tmp;
13     }
14     for (i = 0; i < len; i += 2){
15         tmp = a[i];
16         a[i] = a[i+1];
17         a[i+1] = tmp;
18     }
19     printf("%s \n", a);
20     return;
21 }

得出的字符串前后手動倒置一下,就可以了。

感覺這題還是挺有意思的,混淆挺惡心的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM