BUUCTF/RE/刮開有獎!!!!
這題一開始我以為是動調修改彈出框,我以為dialogbox刪掉之後會顯示出其他被擋住的彈窗(所以才說刮開有獎啊!)結果把dialogbox搞掉之後仍然沒有彈出,甚至我都跳轉不到messagebox的地方。。
嗚~思路失敗,潤去看別人題解,發現居然是ida逆向qaq 一開始看見ida那麼多函式而且沒有main函式(嗚我只認識main函式),而且一開始先入為主覺得肯定是動調解決問題,字串也沒仔細看,漏掉了資訊qaq
現在我用OD實在解決不來問題 qaq總之我退讓了,打開了IDA(倒下
在動調的時候我其實發現了messagebox裡放了奇怪的東西:U get it~,正因此我一直以為只要打開了messagebox就能得到flag
IDA的字串裡確實有U g3t 1t,點進去一看發現是一串加密函式。
按照慣例先總覽一下↑:首先給出了很多資料,然後對String這個陣列進行各種賦值變換,最後用if語句進行check
然後分步往下看:
這個a2只有三處引用,聯絡到這個是dialog函式,加上引數名字其實也在暗示a2應該只是跟對話方塊有關的一個數據,具體是什麼不管它,反正為了執行到“U g3t 1T”這裡,肯定不會被return的。
繼續往下看:
memset把String清零,雖然數值很大但沒關係,最後if函式比較的語句也就那麼幾句而已。
下一句是個API,搜了一下用法,常見的用法是讓使用者輸入賬號密碼之類的,感覺類似scanf,那麼input就是這個String了,一般來說我的input就是flag了。
接下來是一個sub_4010F0函式,點進去看看:
這裡我修改了一下變數的名字,在原名後面下劃線加上了傳參的數字。這裡的v7是個陣列,v7[0]=90,我的理解是傳v7的首地址也就是v7[0]上的數值進去了。所以v7在這裡等於90。也正是因為這裡的v7對應著外面v7[0]的地址,所以這個函式必須關注,因為外面checkflag的時候會用到v7[0],也就是說這個函式影響最終check的資料。
下面這段帶迴圈的程式碼,有很多4*某個數,一開始讓我有點懷疑是什麼遊戲。。資料都給了,那就模擬走一遍。
這裡模擬的寫法我搞的太爛了,一開始忘記它有一個對自身的再呼叫(LABEL13)所以模擬直接寫在main函式裡了,把v7直接賦值90,然後修改了很多處關於v7的運算語法(
執行發現結果錯了,才意識到再呼叫沒改,然後又重新寫函式+main函式,嗚改了半天還是有小錯,很多地方含糊不清,潤去看題解了。
看完題解咯~!感覺這題欠缺的不是讀不懂,而是我太軸了,通篇讀完又人腦模擬了半天才意識到可以用電腦模擬。看完題解之後發現了一個問題,就是v7v8等等一大串變數,他們的地址是相鄰的,也就是說*v7[1]+4=v8這樣的。這裡+4是因為int型別佔據四個位元組,或者從記憶體地址上也能看出來,不過我一開始真的沒看出來qaq。其實這樣不同變數卻連續地址的情況,以前也見過一次,但我以為那個是意外呢。。qaq 看來可能是IDA識別的時候會出問題,以後進入IDA還得加上一個新習慣,就是去看看變數的地址,尤其是在這種函式裡對引數取地址再運算的情況,變數的地址絕對有貓膩,我太傻了,嗚…而且要關注地址之間的差值,比如這次差值是4,這樣才能搞懂運算裡的*4是什麼含義。
這次指令碼的寫法也是我第一次見,雖然模糊的想到了怎麼寫,但細節上一直出錯。簡單來說就是把主函式呼叫這塊函式的地方單獨寫出來,然後函式內部基本上照抄即可。也就是儘量模仿IDA給出的虛擬碼進行還原。這樣做的好處是不容易出錯,思路清晰。畢竟這只是讓程式執行起來看看結果。寫到這裡突然意識到或許這裡是真的可以動調,然後直接斷點攔截看看結果的(可惡
看了題解之後還有一個新收穫:
char數組裡如果直接放0-256這些數字,意味著是ascii碼。除非加上引號,否則char是不會認為這是字元的。qaq我的基礎知識不堪一擊。。指令碼在這裡就不放了,因為是看了別人的答案寫出來的qaq直接上答案:
接下來放個小整體:分別把String陣列的某幾位賦值給一個三位陣列v18, 進行兩次運算,得到了v5和v4的值,在後續和兩個字串進行比較。
v4和v5的結果已知,那麼它原先是什麼樣子呢?也就是說,生成v4和v5的那幾個String[]值是多少呢?
v5很好辦,因為通過if的前四條語句,我們可以知道String[0 1 2 3]分別是多少了,把數值代入sub_401000暴力運算即可。但是v4怎麼辦呢?還是得認真分析sub_401000啊~
這函式好複雜qaq但是裡面有一個怪怪資料,也是圖上標黃的地方。點進去:
一般遇見長串“亂碼”都很值得關注一下
41h對應的字元是A,這份資料全是base64認得的那些字元,查一下base64的演算法:(11條訊息) Base64 編解碼的C語言實現_用心看,這個世界好奇妙,程式碼也很奇妙-CSDN部落格_c語言實現base64
然後就很明白啦,這段程式碼具體寫了什麼我不知道,也不在乎,我只知道它先/3,又對3取模,然後進行了位運算,最後從byte_407830裡找出對應的字元。和base64的演算法完全對的上。
那麼直接拿結果去解碼啦:
567對應jMp,234對應WP1
01通過if的check算一下:51+34='U';v10是之前指令碼執行結果第五位J
flag就出來啦,是一句經典的臺詞:u jump,i jump!
flag{UJWP1jMp}