这是一道经典而且简单的vm题目,没有什么太难的点,唯一比较坑的地方是,定义了很多的handler(其实也才几个),但是用到的很少。
    image.png
    image.png
    image.png
    这样一看,解VM必备的参数就齐全了。就是简单运算加对比。

    1. import re
    2. import struct
    3. vm_exec_code = [0xF0, 0x10, 0x66, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x30, 0xF6, 0xC1, 0xF0, 0x10, 0x63, 0x00, 0x00, 0x00,
    4. 0xF8, 0xF2, 0x31, 0xF6, 0xB6, 0xF0, 0x10, 0x6A, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x32, 0xF6, 0xAB, 0xF0,
    5. 0x10, 0x6A, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x33, 0xF6, 0xA0, 0xF0, 0x10, 0x6D, 0x00, 0x00, 0x00, 0xF8,
    6. 0xF2, 0x34, 0xF6, 0x95, 0xF0, 0x10, 0x57, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x35, 0xF6, 0x8A, 0xF0, 0x10,
    7. 0x6D, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x36, 0xF6, 0x7F, 0xF0, 0x10, 0x73, 0x00, 0x00, 0x00, 0xF8, 0xF2,
    8. 0x37, 0xF6, 0x74, 0xF0, 0x10, 0x45, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x38, 0xF6, 0x69, 0xF0, 0x10, 0x6D,
    9. 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x39, 0xF6, 0x5E, 0xF0, 0x10, 0x72, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x3A,
    10. 0xF6, 0x53, 0xF0, 0x10, 0x52, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x3B, 0xF6, 0x48, 0xF0, 0x10, 0x66, 0x00,
    11. 0x00, 0x00, 0xF8, 0xF2, 0x3C, 0xF6, 0x3D, 0xF0, 0x10, 0x63, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x3D, 0xF6,
    12. 0x32, 0xF0, 0x10, 0x44, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x3E, 0xF6, 0x27, 0xF0, 0x10, 0x6A, 0x00, 0x00,
    13. 0x00, 0xF8, 0xF2, 0x3F, 0xF6, 0x1C, 0xF0, 0x10, 0x79, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x40, 0xF6, 0x11,
    14. 0xF0, 0x10, 0x65, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x41, 0xF6, 0x06, 0xF7, 0x01, 0x00, 0x00, 0x00, 0xF3,
    15. 0xF7, 0x00, 0x00, 0x00, 0x00, 0xF3]
    16. for i in range(len(vm_exec_code)):
    17. vm_exec_code[i] = chr(vm_exec_code[i])
    18. vm_exec_code = "".join(vm_exec_code)
    19. def vm_mov2reg(data):
    20. global vm_eip
    21. regx = ord(data[vm_eip + 1]) & 0xf
    22. print "mov reg%d, 0x%x" % (regx + 1, struct.unpack("i", vm_exec_code[vm_eip + 2:vm_eip + 6])[0])
    23. vm_eip += 6
    24. def create_cipher(data):
    25. global vm_eip
    26. print "call create_cipher then store reg1"
    27. vm_eip += 1
    28. def vm_cmp_xxx(data):
    29. global vm_eip
    30. print "cmp reg1, flag_string%d" % (ord(data[vm_eip + 1]) - 0x30)
    31. vm_eip += 2
    32. def vm_jne_offsetx(data):
    33. global vm_eip
    34. print "jne 0x%x" % ord(data[vm_eip + 1])
    35. vm_eip += 2
    36. def vm_mov2reg1(data):
    37. global vm_eip
    38. tmp_data = struct.unpack("i", vm_exec_code[vm_eip + 1:vm_eip + 5])[0]
    39. print "mov reg1, 0x%x" % tmp_data
    40. vm_eip += 5
    41. function_dic = {
    42. 0xf0: vm_mov2reg,
    43. 0xf8: create_cipher,
    44. 0xf2: vm_cmp_xxx,
    45. 0xf6: vm_jne_offsetx,
    46. 0xf7: vm_mov2reg1
    47. }
    48. vm_eip = 0
    49. while True:
    50. vm_opcode = ord(vm_exec_code[vm_eip])
    51. if vm_opcode == 0xf3:
    52. print "END"
    53. break
    54. function_dic[vm_opcode](vm_exec_code)

    然后跑一下就出flag了。

    import os
    
    
    def create_cipher(input_char):
        if 65 <= input_char <= 90:
            return (input_char + 2 - 65) % 26 + 65
        elif 97 <= input_char <= 122:
            return (input_char + 2 - 97) % 26 + 97
        else:
            return input_char
    
    
    all_indexs = []
    all_code = [0xF0, 0x10, 0x66, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x30, 0xF6, 0xC1, 0xF0, 0x10, 0x63, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x31, 0xF6, 0xB6, 0xF0, 0x10, 0x6A, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x32, 0xF6, 0xAB, 0xF0, 0x10, 0x6A, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x33, 0xF6, 0xA0, 0xF0, 0x10, 0x6D, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x34, 0xF6, 0x95, 0xF0, 0x10, 0x57, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x35, 0xF6, 0x8A, 0xF0, 0x10, 0x6D, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x36, 0xF6, 0x7F, 0xF0, 0x10, 0x73, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x37, 0xF6, 0x74, 0xF0, 0x10, 0x45, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x38, 0xF6, 0x69, 0xF0, 0x10, 0x6D, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x39, 0xF6, 0x5E, 0xF0, 0x10, 0x72, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x3A, 0xF6, 0x53, 0xF0, 0x10, 0x52, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x3B, 0xF6, 0x48, 0xF0, 0x10, 0x66, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x3C, 0xF6, 0x3D, 0xF0, 0x10, 0x63, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x3D, 0xF6, 0x32, 0xF0, 0x10, 0x44, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x3E, 0xF6, 0x27, 0xF0, 0x10, 0x6A, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x3F, 0xF6, 0x1C, 0xF0, 0x10, 0x79, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x40, 0xF6, 0x11, 0xF0, 0x10, 0x65, 0x00, 0x00, 0x00, 0xF8, 0xF2, 0x41, 0xF6, 0x06, 0xF7, 0x01, 0x00, 0x00, 0x00, 0xF3, 0xF7, 0x00, 0x00, 0x00, 0x00, 0xF3, 0x5D, 0xC3, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00]
    start_flag = 0
    while 1:
        try:
            tmp_flag = all_code.index(0xF0, start_flag)
            all_indexs.append(tmp_flag)
            start_flag = tmp_flag + 1
        except Exception as e:
            break
    flag = ""
    for i in range(len(all_indexs)):
        flag += chr(create_cipher(all_code[all_indexs[i] + 2]))
    print "DDCTF{%s}" % flag