[GWCTF 2019]babyvm.zip

程序是一个 vm 逆向的题。

程序存在两端 vmcode 分析每个 指令的功能 和作用

根据 红色 指令匹配到 对应的idx 从而选择 对应的 方法。

静态分析 加 动态调试发现程序走的 是 第一段 vmcode 但是解密发现

a 数组 解密出来不是正确 flag 换第二段解密

第一段
		0xF5, # read
    0xF1, 0xE1, 0x00, 0x00, 0x00, 0x00, # a1 = input[0]
    0xF2, # a1 ^= 18
    0xF1, 0xE4, 0x20, 0x00, 0x00, 0x00, # arr[0] = input[0]^18

    0xF1, 0xE1, 0x01, 0x00, 0x00, 0x00, # a1 = input[1]
    0xF2, 
    0xF1, 0xE4, 0x21, 0x00, 0x00, 0x00, 
    
    0xF1, 0xE1, 0x02, 0x00, 0x00, 0x00, 
    0xF2, 
    0xF1, 0xE4, 0x22, 0x00, 0x00, 0x00, 

    0xF1, 0xE1, 0x03, 0x00, 0x00, 0x00, 
    0xF2, 
    0xF1, 0xE4, 0x23, 0x00, 0x00, 0x00, 

    0xF1, 0xE1, 0x04, 0x00, 0x00, 0x00, 
    0xF2, 
    0xF1, 0xE4, 0x24, 0x00, 0x00, 0x00, 

    0xF1, 0xE1, 0x05, 0x00, 0x00, 0x00, 
    0xF2, 
    0xF1, 0xE4, 0x25, 0x00, 0x00, 0x00, 

    0xF1, 0xE1, 0x06, 0x00, 0x00, 0x00, 
    0xF2, 
    0xF1, 0xE4, 0x26, 0x00, 0x00, 0x00, 

    0xF1, 0xE1, 0x07, 0x00, 0x00, 0x00, 
    0xF2,
    0xF1, 0xE4, 0x27, 0x00, 0x00, 0x00, 

    0xF1, 0xE1, 0x08, 0x00, 0x00, 0x00, 
    0xF2,
    0xF1, 0xE4, 0x28, 0x00, 0x00, 0x00, 

    0xF1, 0xE1, 0x09, 0x00, 0x00, 0x00, 
    0xF2, 
    0xF1, 0xE4, 0x29, 0x00, 0x00, 0x00,

    0xF1, 0xE1, 0x0A, 0x00, 0x00, 0x00, 
    0xF2,
    0xF1, 0xE4, 0x2A, 0x00, 0x00, 0x00, 

    0xF1, 0xE1, 0x0B, 0x00, 0x00, 0x00, 
    0xF2, 
    0xF1, 0xE4, 0x2B, 0x00, 0x00, 0x00, 

    0xF1, 0xE1, 0x0C, 0x00, 0x00, 0x00, 
    0xF2,
    0xF1, 0xE4, 0x2C, 0x00, 0x00, 0x00, 

    0xF1, 0xE1, 0x0D, 0x00, 0x00, 0x00, 
    0xF2,
    0xF1, 0xE4, 0x2D, 0x00, 0x00, 0x00, 

    0xF1, 0xE1, 0x0E, 0x00, 0x00, 0x00, 
    0xF2, 
    0xF1, 0xE4, 0x2E, 0x00, 0x00, 0x00, 

    0xF1, 0xE1, 0x0F, 0x00, 0x00, 0x00, 
    0xF2, 
    0xF1, 0xE4, 0x2F, 0x00, 0x00, 0x00, 

    0xF1, 0xE1, 0x10, 0x00, 0x00, 0x00, 
    0xF2, 
    0xF1, 0xE4, 0x30, 0x00, 0x00, 0x00, 

    0xF1, 0xE1, 0x11, 0x00, 0x00, 0x00, 
    0xF2, 
    0xF1, 0xE4, 0x31, 0x00, 0x00, 0x00, 

    0xF1, 0xE1, 0x12, 0x00, 0x00, 0x00, 
    0xF2, 
    0xF1, 0xE4, 0x32, 0x00, 0x00, 0x00,

    0xF1, 0xE1, 0x13, 0x00, 0x00, 0x00, 
    0xF2, 
    0xF1, 0xE4, 0x33, 0x00, 0x00, 0x00,

    0xF4, 

第二段
#   func choice mun1  mun2  00    00    
    0xF5, #read
    0xF1, 0xE1, 0x00, 0x00, 0x00, 0x00, # a1 = input[0]
    0xF1, 0xE2, 0x01, 0x00, 0x00, 0x00, # a2 = input[1]
    0xF2,                               # a1 = input[0]^input[1]
    0xF1, 0xE4, 0x00, 0x00, 0x00, 0x00, # input[0] = input[0]^input[1]

    0xF1, 0xE1, 0x01, 0x00, 0x00, 0x00, 
    0xF1, 0xE2, 0x02, 0x00, 0x00, 0x00, 
    0xF2, 
    0xF1, 0xE4, 0x01, 0x00, 0x00, 0x00, # input[1] = input[1]^input[2]

    0xF1, 0xE1, 0x02, 0x00, 0x00, 0x00, 
    0xF1, 0xE2, 0x03, 0x00, 0x00, 0x00, 
    0xF2, 
    0xF1, 0xE4, 0x02, 0x00, 0x00, 0x00, # input[2] = input[2]^input[3]

    0xF1, 0xE1, 0x03, 0x00, 0x00, 0x00, 
    0xF1, 0xE2, 0x04, 0x00, 0x00, 0x00, 
    0xF2, 
    0xF1, 0xE4, 0x03, 0x00, 0x00, 0x00, # input[3] = input[3]^input[4]

    0xF1, 0xE1, 0x04, 0x00, 0x00, 0x00, 
    0xF1, 0xE2, 0x05, 0x00, 0x00, 0x00, 
    0xF2, 
    0xF1, 0xE4, 0x04, 0x00, 0x00, 0x00, # input[4] = input[4]^input[5]

    0xF1, 0xE1, 0x05, 0x00, 0x00, 0x00, 
    0xF1, 0xE2, 0x06, 0x00, 0x00, 0x00, 
    0xF2, 
    0xF1, 0xE4, 0x05, 0x00, 0x00, 0x00, # input[5] = input[5]^input[6]

    0xF1, 0xE1, 0x06, 0x00, 0x00, 0x00, # a = input[6]
    0xF1, 0xE2, 0x07, 0x00, 0x00, 0x00, # a4 = input[7]
    0xF1, 0xE3, 0x08, 0x00, 0x00, 0x00, # a8 = input[8]
    0xF1, 0xE5, 0x0C, 0x00, 0x00, 0x00, # a12 = input[12]
    0xF6,                               # a1=a8+2*a4 +3*a
    0xF7,                               # a1 = a1*a12
    0xF1, 0xE4, 0x06, 0x00, 0x00, 0x00, # input[6] = (3*input[6]+2*input[7]+input[8])*input[12]

    0xF1, 0xE1, 0x07, 0x00, 0x00, 0x00, 
    0xF1, 0xE2, 0x08, 0x00, 0x00, 0x00, 
    0xF1, 0xE3, 0x09, 0x00, 0x00, 0x00, 
    0xF1, 0xE5, 0x0C, 0x00, 0x00, 0x00, 
    0xF6, 
    0xF7, 
    0xF1, 0xE4, 0x07, 0x00, 0x00, 0x00, # input[7] = (3*input[7]+2*input[8]+input[9])*input[12]

    0xF1, 0xE1, 0x08, 0x00, 0x00, 0x00, 
    0xF1, 0xE2, 0x09, 0x00, 0x00, 0x00, 
    0xF1, 0xE3, 0x0A, 0x00, 0x00, 0x00, 
    0xF1, 0xE5, 0x0C, 0x00, 0x00, 0x00, 
    0xF6, 
    0xF7, 
    0xF1, 0xE4, 0x08, 0x00, 0x00, 0x00, # input[8] = (3*input[8]+2*input[9]+input[10])*input[12]

    0xF1, 0xE1, 0x0D, 0x00, 0x00, 0x00, 
    0xF1, 0xE2, 0x13, 0x00, 0x00, 0x00, 
    0xF8, 
    0xF1, 0xE4, 0x0D, 0x00, 0x00, 0x00, # input[13] = input[19]
    0xF1, 0xE7, 0x13, 0x00, 0x00, 0x00, # input[19] = input[13]

    0xF1, 0xE1, 0x0E, 0x00, 0x00, 0x00, 
    0xF1, 0xE2, 0x12, 0x00, 0x00, 0x00, 
    0xF8, 
    0xF1, 0xE4, 0x0E, 0x00, 0x00, 0x00, # input[14] = input[18]
    0xF1, 0xE7, 0x12, 0x00, 0x00, 0x00, # input[18] = input[14]

    0xF1, 0xE1, 0x0F, 0x00, 0x00, 0x00, 
    0xF1, 0xE2, 0x11, 0x00, 0x00, 0x00, 
    0xF8, 
    0xF1, 0xE4, 0x0F, 0x00, 0x00, 0x00, # input[15] = input[17]
    0xF1, 0xE7, 0x11, 0x00, 0x00, 0x00, # input[17] = input[15]

    0xF4

根据第二段解密

cmp_data = [ 0x69, 0x45, 0x2A, 0x37, 0x09, 0x17, 0xC5, 0x0B, 0x5C, 0x72, 
  0x33, 0x76, 0x33, 0x21, 0x74, 0x31, 0x5F, 0x33, 0x73, 0x72]

# a = [  0x46, 0x7A, 0x7B, 0x61, 0x4D, 0x7B, 0x61, 0x4D, 0x7C, 0x7D, 
#   0x66, 0x4D, 0x74, 0x7E, 0x73, 0x75, 0x4D, 0x20, 0x21, 0x21]

# flag = ""
# for i in range(len(a)):
#     flag+=chr(a[i]^18)
# print flag
cmp = [0x5C, 0x0b, 0xc5]
b=[0x33,0x72]
flag = cmp_data
print flag
for j in range(3):
    for i in range(200):
        a = (3*i+2*b[j+1]+b[j])*0x33
        a %=0x100
        if a == cmp[j]:
            b.append(i)
            flag[8-j] = i

flag[13],flag[19] = flag[19],flag[13]
flag[14],flag[18] = flag[18],flag[14]
flag[15],flag[17] = flag[17],flag[15]

for i in range(6):
	flag[6-i-1] ^= flag[6-i]

for i in range(len(flag)):
    flag[i] = chr(flag[i])

print "".join(flag)

# Y0u_hav3_r3v3rs3_1t!