之前文章講過的技巧和知識,就不再詳細描述了,如果有不明白的地方建議按照做題題目順序查看。
這道題無疑是入門題里最難的,程序運行內容和題目提示的‘迷宮’沒有關系

找到關鍵代碼,發現v5有四種情況O o . 0,每種情況對應一個函數,執行完函數后goto_LABEL_14。

輸入O,因為(*a1) - 1,所以位置往前移動1位

輸入o,因為*(a1+ 1),所以位置往后移動8位

輸入 . ,因為(*a1)-1 ,所以位置往前移動1位

輸入0,因為*(a1+1),所以位置往后移動8位

這里的移動后來知道是錯誤分析。。因為后面做不出來了,反編譯代碼看的頭大也不知道是不是反編譯錯了這里,看下匯編吧
可以看出sub_400650、sub_400660、sub_400670、sub_400680將改變的內容放回[rdi]
追蹤xref
sub_400650、sub_400660的[rdi]來自於r15
sub_400670、sub_400680的[rdi]來自於r14


追蹤xref找到r14和r15的地址來自於堆棧,普通放數據的地方,和題目沒有多大關系
r14、r15是堆棧的上下兩行所指向的數據

回到四個函數,繼續往下分析運算差別一個是lea ecx, [rax-1]一個是inc eax
inc eax不用說eax加1
lea ecx, [rax-1]追蹤看看rax-1是什么

進入sub_400690函數,rax是棧頂+28h+var_28+4,rdi是ASCII字符串,edx是棧頂+28g+var_28。
20h是‘ ’,23h是‘#’,把rax+rcx*8加到eax里,而eax又是rax的32位,所以rax是個循環里變化的值
ok,和[rax-1]沒有關系,sub_400650、sub_400660的匯編一樣都是r15,所以他們對位置的改動是一樣的距離跨度為1,sub_400670、sub_400680的匯編一樣都是r14所以他們對位置的改動是一樣的距離跨度為8。
既然知道了四個函數的距離跨度,總結一下:
O是前移1位(左),o是后移1位(右),.是前移8位(上),0是后移8位(下)

通過流程圖可以看出四個函數與r14、r15有關

將移動的位置傳入ASCII碼中,查看當前位置的ASCII碼是什么符號
如果改變的值在ASCII碼“ ******* * **** * **** * *** *# *** *** *** *********”里等於‘ ’或‘#’那么return真,如果不是等於這么多就繼續按照輸入的下一個字符串是什么移動位置
(注意8LL*a3是將r14地址所指向的值*8)

如果是真往下判斷,是‘#’,那么輸入的為正確的flag,前提是輸入24個字符串,前五個為‘nctf{’,后一個為‘}’

提供的ASCII字符串共有64位,我們8個換一行排版得到如下圖案

不能碰到*,因為只允許移動到‘ ’和‘#’程序才不會break
所以此題迷宮的意思就是讓你在圖案空白里走18步,走到‘#’
不用寫代碼,算了一下一步步往‘#’走剛好18步
所以對應的順序應該是o0oo00O000oooo..OO
