【Re】 HomuraVM

南郵Homura師傅出的一個虛擬機的題目。
比較關鍵的函數。
在這裏插入圖片描述這裏根據程序內部的指令序列,進行dispatch,每個字符對應一個代碼片段,這邊我是看彙編分析的,將每個片段的功能分析了一下,把反調試patch後,稍微動態調一下,還是比較簡單就能分析出來。

h: ptr+4 (指向輸入的下一個字符)
o: ptr- 4 (指向前一個字符)
u: input[ptr]-1
m:input[ptr]+1
r: [register1]+1
a: [register1]-1
G:[register2]-1
v:[register2]=register1
M:[register2]=[register1]+input[ptr]
C:[register2]=[register2]-([register1]&input[ptr])*2
[ ]: 判斷input[ptr]是否爲0,不爲0則循環執行括號內部指令
{ }:判斷[register2]是否爲0,不爲0則循環執行括號內部指令

開始想的是將這些操作都逆一下,但是發現有困難,兩個寄存器的值比較難獲取。後來還是分析了一下程序中的指令序列,發現了規律。

h[ur]ovMCh{mG}
hv{aG}[ur]ovaaaMCh{mG}
hv{aG}[ur]ovrrMCh{mG}
hv{aG}[ur]ovrararaMCh{mG}
hv{aG}[ur]ovrararrrMCh{mG}
hv{aG}[ur]ovararaaMCh{mG}
hv{aG}[ur]ovrararraraMCh{mG}
hv{aG}[ur]ovrrrarrrMCh{mG}
hv{aG}[ur]ovaarrarrMCh{mG}
hv{aG}[ur]ovaaarrarMCh{mG}
hv{aG}[ur]ovrrrarrMCh{mG}
hv{aG}[ur]ovaarrraaMCh{mG}
hv{aG}[ur]ovarraarMCh{mG}
hv{aG}[ur]ovrrraaarrMCh{mG}
hv{aG}[ur]ovaaarrrrarrMCh{mG}
hv{aG}[ur]ovrrrraarrarrMCh{mG}
hv{aG}[ur]ovrrarraMCh{mG}
hv{aG}[ur]ovaaraarMCh{mG}
hv{aG}[ur]ovrrarraMCh{mG}
hv{aG}[ur]ovaarrrarMCh{mG}
hv{aG}[ur]ovrraarraMCh{mG}
hv{aG}[ur]ovrrarMCh{mG}
hv{aG}[ur]ovaarrarMCh{mG}
hv{aG}[ur]ovrrraarMCh{mG}
hv{aG}[ur]ovrrrraaMCh{mG}
hv{aG}[ur]ovrrarraMCh{mG}
hv{aG}[ur]ovrrrrrrMCh{mG}
hv{aG}[ur]ovaaaarMCh{mG}
hv{aG}[ur]ovrraaaMCh{mG}
hv{aG}[ur]ovaarraMCh{mG}
hv{aG}[ur]ovrrarMCh{mG}
hv{aG}[ur]ovaarraaMCh{mG}
hv{aG}[ur]ovaarraraMCh{mG}
hv{aG}[ur]ovaarrararMCh{mG}

比較一下這些原子操作組成的每一行都只有a,r不同。然後分析一下相同部分。

h: ptr=n
v{aG} 效果等價於 [reg1]=[reg2]=0
[ur] 等價於 [reg1]=input[n],input[n]=0
o: ptr=n-1
v: [reg2]=[reg1] 這個操作好像是廢的
然後是a,r對[reg1]加加減減
Mc: [register2]=[reg1]+input[ptr]-([reg1]&input[n-1])*2
對邏輯運算熟悉一點會發現這個是異或操作,可簡化爲[reg2]=[reg1]^input[n-1]
h: ptr=n
{mG} input[n]=[reg2]

綜上,每行實際上的操作就是c[i]=(c[i]+k) ^ c[i-1]。結合最後進行比較的值,我們就可以計算出初始flag的值,(c[i] ^ c[i-1])-k。腳本如下:

import re 
c=[0x1b,0x72,0x11,0x76,8,0x4a,0x7e,0x5,0x37,0x7c,0x1f,88,104,7,112,7,49,108,4,47,4,105,54,77,127,8,80,12,109,28,127,80,29,96]

with open('opstr.txt','r')as f:
    op=f.read().split('\n')

flag=[]
for i in range(len(op)):
    s=re.findall('ov[a|r]+',op[i])
    if s:
        cnt=s[0].count('r')-s[0].count('a')
        flag.append((c[i-1]^c[i])-cnt)
    else:
        flag.append(c[-1]^c[-2]^c[0])

print(''.join([chr(i) for i in flag]))

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章