【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]))

猜你喜欢

转载自blog.csdn.net/github_36788573/article/details/103171110
re