2023 羊城杯 vm_wo
这是一道Vm的题,第一次做这种题总结下,
VM框架
大概就是VM框架中会模拟正常的CPU去读指令 然后执行指令。
然后会有1个全局变量
然后会有一个dispatcher的程序 模拟CPU读取指令,然后去执行函数,就可以做到和真实的程序一样
writeUP
这道题的整体逻辑还是挺简单的
进入 myoperate函数 ,这里是用两段大整数合成一段opcode,第一个数的最后一个字节被第二个数的第一字节覆盖,然后把input和Vm_body[0]插到opcode中,经过interpretBytecode后,就生成了新的input,所以第一步,先把这个opcode提取出来,按照这个程序的逻辑去生成,input随便弄一个字符
def get_opcode(v1, v2, x):
l = list(v1.to_bytes(8, 'little'))
l = l[:-1] + list(v2.to_bytes(8, 'little'))
l[2] = x
return l
opcode = get_opcode(0x20D01011903001A, 0x300010201180702, 0xFF)
opcode += get_opcode(0x20D02011903001A, 0x400010201180602, 0xFF)
opcode += get_opcode(0x20D03011903001A, 0x500010201180502, 0xFF)
opcode += get_opcode(0x20D04011903001A, 0x600010201180402, 0xFF)
print(opcode)
#[26, 0, 255, 25, 1, 1, 13, 2, 7, 24, 1, 2, 1, 0, 3, 26, 0, 255, 25, 1, 2, 13, 2, 6, 24, 1, 2, 1, 0, 4, 26, 0, 255, 25, 1, 3, 13, 2, 5, 24, 1, 2, 1, 0, 5, 26, 0, 255, 25, 1, 4, 13, 2, 4, 24, 1, 2, 1, 0, 6]
然后进入interpretBytecode函数,这里有26个case处理,这里需要手动将其还原成对应的汇编语句,这里对之前的opcode进行一次去重得到[0, 1, 2, 3, 4, 5, 6, 7, 13, 24, 25, 26, 255] 所以只还原这几句就行
case0:
swap arr[{0}], arr[{1}]
case1:
xor arr[{0}], arr[{1}]
case 2:
add arr[] opcode2
case3:
add arr[] arr
case4:
sub arr arr
case 5:
sub arr arr
case 6:
mul arr opcode2
case 7:
mul arr arr
case 13:
shl arr[opcode1] arr[0] opcode2
case 24:
or arr[0] arr[1], arr[2]
case 25:
arr[opcode1]=arr[0]>>opcode2
case 26:
mov arr[opcode1]=opcode2
大概还原到自己可以看懂,主要是参数的个数不能弄混 会影响后面的还原
opcode=[26, 0, 255, 25, 1, 1, 13, 2, 7, 24, 1, 2, 1, 0, 3, 26, 0, 255, 25, 1, 2, 13, 2, 6, 24, 1, 2, 1, 0, 4, 26, 0, 255, 25, 1, 3, 13, 2, 5, 24, 1, 2, 1, 0, 5, 26, 0, 255, 25, 1, 4, 13, 2, 4, 24, 1, 2, 1, 0, 6]
ins_set = { 0: [3, 2, "swap arr[{0}], arr[{1}]"],
1: [3, 2, "xor arr[{0}], arr[{1}]"],
2: [3, 2, "add arr[{0}], 0x{1:0>2X}"],
3: [3, 2, "add arr[{0}], arr[{1}]"],
4: [3, 2, "sub arr[{0}], 0x{1:0>2X}"],
5: [3, 2, "sub arr[{0}], arr[{1}]"],
6: [3, 2, "mul arr[{0}], 0x{1:0>2X}"],
7: [3, 2, "mul arr[{0}], arr[{1}]"],
8: [3, 2, "div arr[{0}], 0x{1:0>2X}"],
9: [3, 2, "div arr[{0}], arr[{1}]"],
10: [3, 2, "mod arr[{0}], 0x{1:0>2X}"],
11: [3, 2, "mod arr[{0}], arr[{1}]"],
12: [3, 2, "shl arr[{0}], 0x{1:0>2X}"],
13: [3, 2, "shl arr[{0}], arr[0], 0x{1:0>2X}"],
14: [3, 1, "push arr[{0}]"],
15: [3, 1, "print arr[{0}]"],
16: [3, 0, "print [rsp]"],
17: [3, 2, "if !arr[{0}]: jmp 0x{1:0>2X}"],
18: [3, 2, "if arr[{0}]: jmp 0x{1:0>2X}"],
19: [3, 1, "jmp 0x{0:0>2X}"],
20: [3, 1, "push r[arr[{0}]]"],
21: [3, 0, "pop arr[0]"],
22: [3, 1, "push 0x{0:0>2X}"],
23: [3, 0, "exit"],
24: [3, 0, "or arr[0], arr[1], arr[2]"],
25: [3, 2, "shr arr[{0}], arr[0], 0x{1:0>2X}"],
26: [3, 2, "mov arr[{0}], 0x{1:0>2X}"]}
pc = 0
output = open('assembly.txt', 'w')
output.write("Addr Code\n")
addrfmt = "{0:0>3} "
func_start = [0]
lstFunc = 0
while pc < len(opcode):
i = pc
pc += ins_set[opcode[