2020網鼎杯 青龍組reverse:joker


main函數不能F5,原因堆棧不平衡

 打開ida的general設置

 

 勾選棧指針選項

 

 修改出錯的地方的棧指針偏移,快捷鍵alt+k,值改為0

 

 看綠色部分,棧偏移都是0AC了

 

這下,main函數 F5成功

 但是,在main函數的偽代碼里還有一個encrypt函數不能F5,出現以下提示,“不能轉換成代碼”

-cannot convert to microcode
無法轉換成偽代碼
成因,部分指令無法被反編譯
有未設置成指令的數據字節按c將其設置成指令
或者這里我選擇啟動動態調試,程序運行到代碼段這里會自動問你要不把數據換成代碼,選擇yes

原來的data數據變為匯編代碼

 

(.text代碼段的數據)

 

(上一張圖的數據自動變為匯編代碼)

右鍵原來的encrypt函數,選擇創建函數

 然后F5就可以成功出現偽代碼了

從main函數到encrypt函數,我們已經將所有不能F5的地方修復了。

main函數邏輯,輸入24個字符,對輸入的內容進行wrong函數加密

wrong函數,對輸入的前23個進行加密

比較wrong加密結果和unk_4030C0地址的值是否相同

把unk_4030C0地址的值考出來,反手寫個解密,步驟如下

1.快捷鍵d,把數據類型從db轉為dd

 2.然后用ida導出,啊..我暈,怎么還是db數據類型,沒辦法只有自己處理了

3.很可惜,運行出來是個假flag

'''
s=[102,   0,   0,   0, 107,   0,   0,   0,  99,   0, 
    0,   0, 100,   0,   0,   0, 127,   0,   0,   0, 
   97,   0,   0,   0, 103,   0,   0,   0, 100,   0, 
    0,   0,  59,   0,   0,   0,  86,   0,   0,   0, 
  107,   0,   0,   0,  97,   0,   0,   0, 123,   0, 
    0,   0,  38,   0,   0,   0,  59,   0,   0,   0, 
   80,   0,   0,   0,  99,   0,   0,   0,  95,   0, 
    0,   0,  77,   0,   0,   0,  90,   0,   0,   0, 
  113,   0,   0,   0,  12,   0,   0,   0,  55,   0, 
    0,   0, 102,   0,   0,   0]

out =[]
for i in s:
          if i !=0:
                    out.append(i)
'''

s=[102, 107, 99, 100, 127, 97, 103, 100, 59, 86, 107, 97, 123, 38, 59, 80, 99, 95, 77, 90, 113, 12, 55, 102]

out =[]
for i in range(0,24):
          if i&1:
                    s[i] += i
                    out.append(s[i])
                    
          else:
                    s[i] ^=i
                    out.append(s[i])

flag=''                 
for i in out:
          flag += chr(i)
print(flag)

wrong函數,不行不是真flag往后看吧,encrpt和wrong函數差不多

一樣的,找到unk_403040地址的值,把值考出來,用以寫解密

 出了flag的前19位

'''
s=[   14,   0,   0,   0,  13,   0,   0,   0,   9,   0, 
    0,   0,   6,   0,   0,   0,  19,   0,   0,   0, 
    5,   0,   0,   0,  88,   0,   0,   0,  86,   0, 
    0,   0,  62,   0,   0,   0,   6,   0,   0,   0, 
   12,   0,   0,   0,  60,   0,   0,   0,  31,   0, 
    0,   0,  87,   0,   0,   0,  20,   0,   0,   0, 
  107,   0,   0,   0,  87,   0,   0,   0,  89,   0, 
    0,   0,  13,]

out =[]
for i in s:
          if i !=0:
                    out.append(i)
'''

s=[14, 13, 9, 6, 19, 5, 88, 86, 62, 6, 12, 60, 31, 87, 20, 107, 87, 89, 13]
haha='hahahaha_do_you_find_me?'

out =[]
for i in range(0,len(s)):
          out.append(s[i]^ord(haha[i]))

flag=''                 
for i in out:
          flag += chr(i)
print(flag)

剩下的5位在finall函數里,但是....代碼邏輯很迷惑,不懂

 來到匯編處,看出是因為把匯編代碼存成了data數據,所以偽代碼才那么迷惑

動態調試到finally

 

 create function查看偽代碼

偽代碼(37 != *a1) == v9這里很迷看不出來什么意思,轉到匯編可以看出比較的al、dl是數組元素,var_15是0x25

比較完了,al的值清空保存到eax里

 隨着var_10的增加dl和al取的數組值也在相應發生變化,當var_10增加到4時,退出finally函數

邏輯很明顯了,就是以下五個數字和傳入的參數al相比,剛才算出了flag的前19位,傳入的參數自然是flag的后五位。

.text:004015A0 mov     [ebp+var_15], 25h
.text:004015A4 mov     [ebp+var_14], 74h
.text:004015A8 mov     [ebp+var_13], 70h
.text:004015AC mov     [ebp+var_12], 26h
.text:004015B0 mov     [ebp+var_11], 3Ah

最后eax和前面的rand()隨機生成的數字做比較,如果不等則退出

 

 

 不知是我匯編水平太差沒看出來,還是里面壓根沒有寫輸入和flag有何關系,只講明了輸入和那五個數字應該相等

25h,74h,70h,26h,3Ah

通過猜測,最后一位應該是},再猜0x3A和}之間是異或關系,得到的值為71,再將之前的四個值都和71異或

 s=[0x25,0x74,0x70,0x26,0x3a]
 for i in s:
    print(chr(i^71),end='')

 加起來便是,flag{d07abccf8a410cb37a}

什么腦洞啊......服了

 


免責聲明!

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



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