0x16 LCTF easyvm

Author Avatar
张Mini Nov 23, 2018
  • Read this article on other devices

LCTF easyvm

  • 三段数据依次传入解释器sub_4009D2中进行解释
  • 进入这个函数进行查看发现了三个函数sub_401722、sub_401502、sub_4017C2

  • 进入第一个函数。。最开始没看出来这赋值赋的是什么orz。。后来才知道是结构体之间,用一个struct给另一个struct赋值,学习了一下ida创建结构体后改了一下才顺利进行

  • 用于是分三次对字节码进行解释,所以分别分析

  • 第一段

    0x95    reg3 = 0x1c
    key += 16
    0x97    reg1 = input
    key += 8
    0x9B    cmp reg1 reg0
    key += 8
    0x9E    if(reg1 == reg0)    key += 20   0xA1
          else                key += 8    0x94
    0x94    reg3 --
    key += 8
    0x99    input ++
    key += 4
    0xA1    mov 0x97
    

    大概性的分析了一下发现判断是对input的长度进行检查,判断是否为0x1c

  • 第二段

0x92 reg4 = reg0
key += 8
0x9F if(reg4 != 0)  key += 4
     else           key += 8
0xA3
0x95 reg0 = 0x80
key += 16
0x95 reg2 = 0x3F
key += 16
0x95 reg3 = 0x7B
key += 16
0x95 reg4 = 0x1C
key += 16
0x97 reg1 = input
key += 8
0x8D reg1 = reg1 * reg2
key += 8
0x8B reg1 = reg1 + reg3
key += 8
0x8F reg1 = reg1 % reg0
key += 8
0x98 input = reg1
key += 8
0x99 input ++ 
key += 4
0x94 reg4 --
key += 8
0x87 
key += 8
0x92
key += 8
0x9F...

这一段大概就是对input进行加密的过程

加密算法:input[i] = ((input[i]*0x3F)+0x7B)%0x80

  • 第三段
0x92 reg4 = reg0
key += 8
0x9F if(reg4 != 0)  key += 4 0x01
     else key += 8 0xA3
0xA3 
ox86 reg6 = 0x3E
key += 12
            0x1A
            0x56
            0x0D
            0x52
            0x13
            0x58
            0x5A
            0x6E
            0x5C
            0x0F
            0x5A
            0x46
            0x07
            0x09
            0x52
            0x25
            0x5C
            0x4C
            0x0A
            0x0A
            0x56
            0x33
            0x40
            0x15
            0x07
            0x58
            0x0F 
0x95 reg0 = 0
key += 16
0x95 reg3 = 0x1C
key += 16
0x97 reg1 = input
key += 8
0x8A key += 8
0x9B cmp reg1 reg2
key += 8

push进去了一段数据,然后与变换后的input的进行比较

  • 脚本
import string
flag_en = [0x1A,0x56,0x0D,0x52,0x13,0x58,0x5A,0x6E,0x5C,0x0F,0x5A,0x46,0x07,0x09,0x52,0x25,0x5C,0x4C,0x0A,0x0A,0x56,0x33,0x40,0x15,0x07,0x58,0x0F]
st = string.printable
flag=""
for i in range(len(flag_en)):
        for s in st:
                if(((ord(s)*0x3F)+0x7B)%0x80 == flag_en[i]):
                        flag+=s
                        break
print(flag[::-1])