vnctf——babyvm

深入了解 vm虚拟机逆向

这是一道golang vm题,64位idapro 7.7 对于go反编译进行了优化,可以直接看。

分析主函数,unk_B9D8A0为我们的opcode段

根据部分函数 猜测a7就是虚拟机的寄存器个数,并且为21.

推测栈的大小为0x3e8

struct func
{
  void *call;
  vm *ptr;
};
struct REG
{
  _DWORD R[21];
};
struct vm
{
  REG reg;
  _DWORD Memory[1000];
  _DWORD rip;
  _DWORD index;
  void *data;
  func *func[100];
  _QWORD isExit;
};

shift + F1 ,之后 insert,把写好的 c 语言的结构体复制进去,查看处理后的run函数。

 vm的指令长度为12字节,分为三段。我们dump出opcode段。并且eip在0xff4处

import idautils
adr=0x00B9D8A0
end=0x00Ba0780
op=[]
while(True):
    op.append([idc.get_wide_dword(adr),idc.get_wide_dword(adr+4),idc.get_wide_dword(adr+8)])
    if(adr==end):
        print(op)
        print('yes')
        break
    adr+=12

一共20种函数,我们可以先看一下运用到的函数

op=[[0, 0, 0], [0, 0, 0], [1, 0, 87], [98, 0, 0], [1, 0, 101], [98, 0, 0], [1, 0, 108], [98, 0, 0], [1, 0, 99], [98, 0, 0], [1, 0, 111], [98, 0, 0], [1, 0, 109], [98, 0, 0], [1, 0, 101], [98, 0, 0], [1, 0, 32], [98, 0, 0], [1, 0, 116], [98, 0, 0], [1, 0, 111], [98, 0, 0], [1, 0, 32], [98, 0, 0], [1, 0, 86], [98, 0, 0], [1, 0, 78], [98, 0, 0], [1, 0, 67], [98, 0, 0], [1, 0, 84], [98, 0, 0], [1, 0, 70], [98, 0, 0], [1, 0, 50], [98, 0, 0], [1, 0, 48], [98, 0, 0], [1, 0, 50], [98, 0, 0], [1, 0, 50], [98, 0, 0], [1, 0, 33], [98, 0, 0], [1, 0, 10], [98, 0, 0], [1, 0, 105], [98, 0, 0], [1, 0, 110], [98, 0, 0], [1, 0, 112], [98, 0, 0], [1, 0, 117], [98, 0, 0], [1, 0, 116], [98, 0, 0], [1, 0, 32], [98, 0, 0], [1, 0, 102], [98, 0, 0], [1, 0, 108], [98, 0, 0], [1, 0, 97], [98, 0, 0], [1, 0, 103], [98, 0, 0], [1, 0, 58], [98, 0, 0], [1, 0, 10], [98, 0, 0], [1, 19, 73], [1, 3, 0], [1, 1, 43], [1, 2, 1], [97, 0, 0], [5, 0, 0], [8, 1, 2], [14, 1, 3], [1, 0, 0], [5, 0, 0], [0, 0, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 6, 0], [6, 0, 0], [7, 6, 0], [2, 0, 6], [10, 0, 5], [2, 6, 0], [6, 0, 0], [7, 6, 0], [2, 0, 6], [10, 0, 5], [2, 6, 0], [6, 0, 0], [7, 6, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 7, 0], [6, 0, 0], [7, 7, 0], [2, 0, 7], [10, 0, 5], [2, 7, 0], [6, 0, 0], [7, 7, 0], [2, 0, 7], [10, 0, 5], [2, 7, 0], [6, 0, 0], [7, 7, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 8, 0], [6, 0, 0], [7, 8, 0], [2, 0, 8], [10, 0, 5], [2, 8, 0], [6, 0, 0], [7, 8, 0], [2, 0, 8], [10, 0, 5], [2, 8, 0], [6, 0, 0], [7, 8, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 9, 0], [6, 0, 0], [7, 9, 0], [2, 0, 9], [10, 0, 5], [2, 9, 0], [6, 0, 0], [7, 9, 0], [2, 0, 9], [10, 0, 5], [2, 9, 0], [6, 0, 0], [7, 9, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 10, 0], [6, 0, 0], [7, 10, 0], [2, 0, 10], [10, 0, 5], [2, 10, 0], [6, 0, 0], [7, 10, 0], [2, 0, 10], [10, 0, 5], [2, 10, 0], [6, 0, 0], [7, 10, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 11, 0], [6, 0, 0], [7, 11, 0], [2, 0, 11], [10, 0, 5], [2, 11, 0], [6, 0, 0], [7, 11, 0], [2, 0, 11], [10, 0, 5], [2, 11, 0], [6, 0, 0], [7, 11, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 12, 0], [6, 0, 0], [7, 12, 0], [2, 0, 12], [10, 0, 5], [2, 12, 0], [6, 0, 0], [7, 12, 0], [2, 0, 12], [10, 0, 5], [2, 12, 0], [6, 0, 0], [7, 12, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 13, 0], [6, 0, 0], [7, 13, 0], [2, 0, 13], [10, 0, 5], [2, 13, 0], [6, 0, 0], [7, 13, 0], [2, 0, 13], [10, 0, 5], [2, 13, 0], [6, 0, 0], [7, 13, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 14, 0], [6, 0, 0], [7, 14, 0], [2, 0, 14], [10, 0, 5], [2, 14, 0], [6, 0, 0], [7, 14, 0], [2, 0, 14], [10, 0, 5], [2, 14, 0], [6, 0, 0], [7, 14, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 15, 0], [6, 0, 0], [7, 15, 0], [2, 0, 15], [10, 0, 5], [2, 15, 0], [6, 0, 0], [7, 15, 0], [2, 0, 15], [10, 0, 5], [2, 15, 0], [6, 0, 0], [7, 15, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 16, 0], [6, 0, 0], [7, 16, 0], [2, 0, 16], [10, 0, 5], [2, 16, 0], [6, 0, 0], [7, 16, 0], [2, 0, 16], [10, 0, 5], [2, 16, 0], [6, 0, 0], [7, 16, 0], [0, 0, 0], [5, 6, 0], [5, 7, 0], [5, 8, 0], [5, 9, 0], [5, 10, 0], [5, 11, 0], [5, 12, 0], [5, 13, 0], [5, 14, 0], [5, 15, 0], [5, 16, 0], [6, 1, 0], [6, 2, 0], [1, 20, 284], [1, 0, 340], [12, 0, 0], [1, 0, 3906065887], [1, 19, 387], [1, 20, 339], [14, 1, 0], [1, 0, 4125344020], [14, 2, 0], [6, 1, 0], [6, 2, 0], [1, 20, 295], [1, 0, 340], [12, 0, 0], [1, 0, 579781142], [1, 19, 387], [1, 20, 339], [14, 1, 0], [1, 0, 2312395361], [14, 2, 0], [6, 1, 0], [6, 2, 0], [1, 20, 306], [1, 0, 340], [12, 0, 0], [1, 0, 1700499305], [1, 19, 387], [1, 20, 339], [14, 1, 0], [1, 0, 612671610], [14, 2, 0], [6, 1, 0], [6, 2, 0], [1, 20, 317], [1, 0, 340], [12, 0, 0], [1, 0, 3655723000], [1, 19, 387], [1, 20, 339], [14, 1, 0], [1, 0, 977540402], [14, 2, 0], [6, 1, 0], [6, 2, 0], [1, 20, 328], [1, 0, 340], [12, 0, 0], [1, 0, 2443935368], [1, 19, 387], [1, 20, 339], [14, 1, 0], [1, 0, 1778148540], [14, 2, 0], [6, 1, 0], [1, 0, 8206181], [14, 1, 0], [1, 0, 393], [12, 0, 0], [99, 0, 0], [1, 3, 2654435769], [1, 4, 613452], [1, 5, 34589], [1, 6, 108471], [1, 7, 1230791], [1, 8, 0], [1, 17, 16], [1, 18, 32], [1, 19, 352], [1, 10, 0], [1, 11, 32], [1, 12, 1], [7, 8, 3], [2, 0, 2], [10, 0, 17], [7, 0, 4], [2, 14, 0], [2, 0, 2], [7, 0, 8], [2, 15, 0], [2, 0, 2], [9, 0, 18], [7, 0, 5], [2, 16, 0], [2, 0, 14], [11, 0, 15], [11, 0, 16], [7, 1, 0], [2, 0, 1], [10, 0, 17], [7, 0, 6], [2, 14, 0], [2, 0, 1], [7, 0, 8], [2, 15, 0], [2, 0, 1], [9, 0, 18], [7, 0, 7], [2, 16, 0], [2, 0, 14], [11, 0, 15], [11, 0, 16], [7, 2, 0], [8, 11, 12], [14, 11, 10], [12, 20, 0], [0, 0, 0], [1, 0, 110], [98, 0, 0], [1, 0, 111], [98, 0, 0], [12, 20, 0], [0, 0, 0], [1, 0, 121], [98, 0, 0], [1, 0, 101], [98, 0, 0], [1, 0, 115], [98, 0, 0], [12, 20, 0]]
f=[]
for i in range(0,len(op),1):
   if op[i][0] not in f:
       f.append(op[i][0])
print(f)

 [0, 1, 98, 97, 5, 8, 14, 6, 10, 2, 7, 12, 99, 9, 11]

我们着重分析一下这几个函数。

 

func2  mov r[{Lnum}],{hex(Rnum)}

这里HIDWPORD是取高位的意思,也就是Lnum,func3  mov r[{Lnum}],r[{Rnum}]

 func6 push r[{Lnum}]

func pop  r[{Lnum}]

func13 jmp r[{Lnum}]

func15 cmp R[{num}] R[{right}], jne R[19] dei

op=[[0, 0, 0], [0, 0, 0], [1, 0, 87], [98, 0, 0], [1, 0, 101], [98, 0, 0], [1, 0, 108], [98, 0, 0], [1, 0, 99], [98, 0, 0], [1, 0, 111], [98, 0, 0], [1, 0, 109], [98, 0, 0], [1, 0, 101], [98, 0, 0], [1, 0, 32], [98, 0, 0], [1, 0, 116], [98, 0, 0], [1, 0, 111], [98, 0, 0], [1, 0, 32], [98, 0, 0], [1, 0, 86], [98, 0, 0], [1, 0, 78], [98, 0, 0], [1, 0, 67], [98, 0, 0], [1, 0, 84], [98, 0, 0], [1, 0, 70], [98, 0, 0], [1, 0, 50], [98, 0, 0], [1, 0, 48], [98, 0, 0], [1, 0, 50], [98, 0, 0], [1, 0, 50], [98, 0, 0], [1, 0, 33], [98, 0, 0], [1, 0, 10], [98, 0, 0], [1, 0, 105], [98, 0, 0], [1, 0, 110], [98, 0, 0], [1, 0, 112], [98, 0, 0], [1, 0, 117], [98, 0, 0], [1, 0, 116], [98, 0, 0], [1, 0, 32], [98, 0, 0], [1, 0, 102], [98, 0, 0], [1, 0, 108], [98, 0, 0], [1, 0, 97], [98, 0, 0], [1, 0, 103], [98, 0, 0], [1, 0, 58], [98, 0, 0], [1, 0, 10], [98, 0, 0], [1, 19, 73], [1, 3, 0], [1, 1, 43], [1, 2, 1], [97, 0, 0], [5, 0, 0], [8, 1, 2], [14, 1, 3], [1, 0, 0], [5, 0, 0], [0, 0, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 6, 0], [6, 0, 0], [7, 6, 0], [2, 0, 6], [10, 0, 5], [2, 6, 0], [6, 0, 0], [7, 6, 0], [2, 0, 6], [10, 0, 5], [2, 6, 0], [6, 0, 0], [7, 6, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 7, 0], [6, 0, 0], [7, 7, 0], [2, 0, 7], [10, 0, 5], [2, 7, 0], [6, 0, 0], [7, 7, 0], [2, 0, 7], [10, 0, 5], [2, 7, 0], [6, 0, 0], [7, 7, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 8, 0], [6, 0, 0], [7, 8, 0], [2, 0, 8], [10, 0, 5], [2, 8, 0], [6, 0, 0], [7, 8, 0], [2, 0, 8], [10, 0, 5], [2, 8, 0], [6, 0, 0], [7, 8, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 9, 0], [6, 0, 0], [7, 9, 0], [2, 0, 9], [10, 0, 5], [2, 9, 0], [6, 0, 0], [7, 9, 0], [2, 0, 9], [10, 0, 5], [2, 9, 0], [6, 0, 0], [7, 9, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 10, 0], [6, 0, 0], [7, 10, 0], [2, 0, 10], [10, 0, 5], [2, 10, 0], [6, 0, 0], [7, 10, 0], [2, 0, 10], [10, 0, 5], [2, 10, 0], [6, 0, 0], [7, 10, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 11, 0], [6, 0, 0], [7, 11, 0], [2, 0, 11], [10, 0, 5], [2, 11, 0], [6, 0, 0], [7, 11, 0], [2, 0, 11], [10, 0, 5], [2, 11, 0], [6, 0, 0], [7, 11, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 12, 0], [6, 0, 0], [7, 12, 0], [2, 0, 12], [10, 0, 5], [2, 12, 0], [6, 0, 0], [7, 12, 0], [2, 0, 12], [10, 0, 5], [2, 12, 0], [6, 0, 0], [7, 12, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 13, 0], [6, 0, 0], [7, 13, 0], [2, 0, 13], [10, 0, 5], [2, 13, 0], [6, 0, 0], [7, 13, 0], [2, 0, 13], [10, 0, 5], [2, 13, 0], [6, 0, 0], [7, 13, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 14, 0], [6, 0, 0], [7, 14, 0], [2, 0, 14], [10, 0, 5], [2, 14, 0], [6, 0, 0], [7, 14, 0], [2, 0, 14], [10, 0, 5], [2, 14, 0], [6, 0, 0], [7, 14, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 15, 0], [6, 0, 0], [7, 15, 0], [2, 0, 15], [10, 0, 5], [2, 15, 0], [6, 0, 0], [7, 15, 0], [2, 0, 15], [10, 0, 5], [2, 15, 0], [6, 0, 0], [7, 15, 0], [0, 0, 0], [6, 0, 0], [1, 5, 256], [10, 0, 5], [2, 16, 0], [6, 0, 0], [7, 16, 0], [2, 0, 16], [10, 0, 5], [2, 16, 0], [6, 0, 0], [7, 16, 0], [2, 0, 16], [10, 0, 5], [2, 16, 0], [6, 0, 0], [7, 16, 0], [0, 0, 0], [5, 6, 0], [5, 7, 0], [5, 8, 0], [5, 9, 0], [5, 10, 0], [5, 11, 0], [5, 12, 0], [5, 13, 0], [5, 14, 0], [5, 15, 0], [5, 16, 0], [6, 1, 0], [6, 2, 0], [1, 20, 284], [1, 0, 340], [12, 0, 0], [1, 0, 3906065887], [1, 19, 387], [1, 20, 339], [14, 1, 0], [1, 0, 4125344020], [14, 2, 0], [6, 1, 0], [6, 2, 0], [1, 20, 295], [1, 0, 340], [12, 0, 0], [1, 0, 579781142], [1, 19, 387], [1, 20, 339], [14, 1, 0], [1, 0, 2312395361], [14, 2, 0], [6, 1, 0], [6, 2, 0], [1, 20, 306], [1, 0, 340], [12, 0, 0], [1, 0, 1700499305], [1, 19, 387], [1, 20, 339], [14, 1, 0], [1, 0, 612671610], [14, 2, 0], [6, 1, 0], [6, 2, 0], [1, 20, 317], [1, 0, 340], [12, 0, 0], [1, 0, 3655723000], [1, 19, 387], [1, 20, 339], [14, 1, 0], [1, 0, 977540402], [14, 2, 0], [6, 1, 0], [6, 2, 0], [1, 20, 328], [1, 0, 340], [12, 0, 0], [1, 0, 2443935368], [1, 19, 387], [1, 20, 339], [14, 1, 0], [1, 0, 1778148540], [14, 2, 0], [6, 1, 0], [1, 0, 8206181], [14, 1, 0], [1, 0, 393], [12, 0, 0], [99, 0, 0], [1, 3, 2654435769], [1, 4, 613452], [1, 5, 34589], [1, 6, 108471], [1, 7, 1230791], [1, 8, 0], [1, 17, 16], [1, 18, 32], [1, 19, 352], [1, 10, 0], [1, 11, 32], [1, 12, 1], [7, 8, 3], [2, 0, 2], [10, 0, 17], [7, 0, 4], [2, 14, 0], [2, 0, 2], [7, 0, 8], [2, 15, 0], [2, 0, 2], [9, 0, 18], [7, 0, 5], [2, 16, 0], [2, 0, 14], [11, 0, 15], [11, 0, 16], [7, 1, 0], [2, 0, 1], [10, 0, 17], [7, 0, 6], [2, 14, 0], [2, 0, 1], [7, 0, 8], [2, 15, 0], [2, 0, 1], [9, 0, 18], [7, 0, 7], [2, 16, 0], [2, 0, 14], [11, 0, 15], [11, 0, 16], [7, 2, 0], [8, 11, 12], [14, 11, 10], [12, 20, 0], [0, 0, 0], [1, 0, 110], [98, 0, 0], [1, 0, 111], [98, 0, 0], [12, 20, 0], [0, 0, 0], [1, 0, 121], [98, 0, 0], [1, 0, 101], [98, 0, 0], [1, 0, 115], [98, 0, 0], [12, 20, 0]]
f=[]
for i in range(0,len(op),1):
   if op[i][0] not in f:
       f.append(op[i][0])
print(f)
for i in range(0,len(op)):

    adr=op[i][0]
    Lnum=op[i][1]
    Rnum=op[i][2]
    if adr==0:
        print("%s: "%hex(i)+f"nop")
    elif adr==1:
        print("%s: "%hex(i)+f"mov r[{Lnum}],{hex(Rnum)}")
    elif adr==2:
        print("%s: "%hex(i)+f"mov r[{Lnum}],r[{Rnum}]")
    elif adr==5:
        print("%s: "%hex(i)+f"push r[{Lnum}]")
    elif adr==6:
        print("%s: "%hex(i)+f"pop r[{Lnum}]")
    elif adr==7:
        print("%s: "%hex(i)+f"add r[{Lnum}],r[{Rnum}]")
    elif adr==8:
        print("%s: "%hex(i)+f"sub r[{Lnum}],r[{Rnum}]")
    elif adr==9:
        print("%s: "%hex(i)+f"div r[{Lnum}],r[{Rnum}]")
    elif adr==10:
        print("%s: "%hex(i)+f"mul r[{Lnum}],r[{Rnum}]")
    elif adr==11:
        print("%s: "%hex(i)+f"xor r[{Lnum}],r[{Rnum}]")
    elif adr==12:
        print("%s: "%hex(i)+f"jmp r[{Lnum}]")
    elif adr==14:
        print("%s: "%hex(i)+f"cmp r[{Lnum}],r[{Rnum}] -- jnz r[19]")
    elif adr==0x61:
        print("%s: "%hex(i)+f"getchar(r[{Lnum}])")
    elif adr==0x62:
        print("%s: "%hex(i)+f'putchar(r[{Lnum})]')
    elif adr==0x63:
        print("%s: "%hex(i)+f"exit()")
0x0: nop
0x1: nop
0x2: mov r[0],0x57
0x3: putchar(r[0)]
0x4: mov r[0],0x65
0x5: putchar(r[0)]
0x6: mov r[0],0x6c
0x7: putchar(r[0)]
0x8: mov r[0],0x63
0x9: putchar(r[0)]
0xa: mov r[0],0x6f
0xb: putchar(r[0)]
0xc: mov r[0],0x6d
0xd: putchar(r[0)]
0xe: mov r[0],0x65
0xf: putchar(r[0)]
0x10: mov r[0],0x20
0x11: putchar(r[0)]
0x12: mov r[0],0x74
0x13: putchar(r[0)]
0x14: mov r[0],0x6f
0x15: putchar(r[0)]
0x16: mov r[0],0x20
0x17: putchar(r[0)]
0x18: mov r[0],0x56
0x19: putchar(r[0)]
0x1a: mov r[0],0x4e
0x1b: putchar(r[0)]
0x1c: mov r[0],0x43
0x1d: putchar(r[0)]
0x1e: mov r[0],0x54
0x1f: putchar(r[0)]
0x20: mov r[0],0x46
0x21: putchar(r[0)]
0x22: mov r[0],0x32
0x23: putchar(r[0)]
0x24: mov r[0],0x30
0x25: putchar(r[0)]
0x26: mov r[0],0x32
0x27: putchar(r[0)]
0x28: mov r[0],0x32
0x29: putchar(r[0)]
0x2a: mov r[0],0x21
0x2b: putchar(r[0)]
0x2c: mov r[0],0xa
0x2d: putchar(r[0)]
0x2e: mov r[0],0x69
0x2f: putchar(r[0)]
0x30: mov r[0],0x6e
0x31: putchar(r[0)]
0x32: mov r[0],0x70
0x33: putchar(r[0)]
0x34: mov r[0],0x75
0x35: putchar(r[0)]
0x36: mov r[0],0x74
0x37: putchar(r[0)]
0x38: mov r[0],0x20
0x39: putchar(r[0)]
0x3a: mov r[0],0x66
0x3b: putchar(r[0)]
0x3c: mov r[0],0x6c
0x3d: putchar(r[0)]
0x3e: mov r[0],0x61
0x3f: putchar(r[0)]
0x40: mov r[0],0x67
0x41: putchar(r[0)]
0x42: mov r[0],0x3a
0x43: putchar(r[0)]
0x44: mov r[0],0xa
0x45: putchar(r[0)] //输出欢迎语引导输⼊,接下来是获取输⼊
0x46: mov r[19],0x49 // r19是跳转寄存器
0x47: mov r[3],0x0
0x48: mov r[1],0x2b  //循环43次
0x49: mov r[2],0x1
0x4a: getchar(r[0])
0x4b: push r[0]
0x4c: sub r[1],r[2]  //sub r1 r2 循环递减
0x4d: cmp r[1],r[3] -- jnz r[19]
0x4e: mov r[0],0x0
0x4f: push r[0]  //多push⼀个0,44个byte转成11个int
0x50: nop
0x51: nop                // 校验flag的过程 准备⽤tea算法
0x52: pop r[0]           // 将输⼊从末尾开始取出来
0x53: mov r[5],0x100     // 2的8次⽅,⽤于代替位移运算
0x54: mul r[0],r[5]      // r0=r0*256 -> << 8
0x55: mov r[6],r[0]      // r6=r0
0x56: pop r[0]           // 将输⼊从末尾取出来
0x57: add r[6],r[0]      // 加上之前的
0x58: mov r[0],r[6] 
0x59: mul r[0],r[5] 
0x5a: mov r[6],r[0]      // 再次位移后放到r6
0x5b: pop r[0]
0x5c: add r[6],r[0]
0x5d: mov r[0],r[6]
0x5e: mul r[0],r[5]
0x5f: mov r[6],r[0]
0x60: pop r[0]
0x61: add r[6],r[0]
0x62: nop                ///分隔符 r7以下类推
0x63: pop r[0]
0x64: mov r[5],0x100
0x65: mul r[0],r[5]
0x66: mov r[7],r[0]
0x67: pop r[0]
0x68: add r[7],r[0]
0x69: mov r[0],r[7]
0x6a: mul r[0],r[5]
0x6b: mov r[7],r[0]
0x6c: pop r[0]
0x6d: add r[7],r[0]
0x6e: mov r[0],r[7]
0x6f: mul r[0],r[5]
0x70: mov r[7],r[0]
0x71: pop r[0]
0x72: add r[7],r[0]
0x73: nop
0x74: pop r[0]
0x75: mov r[5],0x100
0x76: mul r[0],r[5]
0x77: mov r[8],r[0]
0x78: pop r[0]
0x79: add r[8],r[0]
0x7a: mov r[0],r[8]
0x7b: mul r[0],r[5]
0x7c: mov r[8],r[0]
0x7d: pop r[0]
0x7e: add r[8],r[0]
0x7f: mov r[0],r[8]
0x80: mul r[0],r[5]
0x81: mov r[8],r[0]
0x82: pop r[0]
0x83: add r[8],r[0]
0x84: nop
0x85: pop r[0]
0x86: mov r[5],0x100
0x87: mul r[0],r[5]
0x88: mov r[9],r[0]
0x89: pop r[0]
0x8a: add r[9],r[0]
0x8b: mov r[0],r[9]
0x8c: mul r[0],r[5]
0x8d: mov r[9],r[0]
0x8e: pop r[0]
0x8f: add r[9],r[0]
0x90: mov r[0],r[9]
0x91: mul r[0],r[5]
0x92: mov r[9],r[0]
0x93: pop r[0]
0x94: add r[9],r[0]
0x95: nop
0x96: pop r[0]
0x97: mov r[5],0x100
0x98: mul r[0],r[5]
0x99: mov r[10],r[0]
0x9a: pop r[0]
0x9b: add r[10],r[0]
0x9c: mov r[0],r[10]
0x9d: mul r[0],r[5]
0x9e: mov r[10],r[0]
0x9f: pop r[0]
0xa0: add r[10],r[0]
0xa1: mov r[0],r[10]
0xa2: mul r[0],r[5]
0xa3: mov r[10],r[0]
0xa4: pop r[0]
0xa5: add r[10],r[0]
0xa6: nop
0xa7: pop r[0]
0xa8: mov r[5],0x100
0xa9: mul r[0],r[5]
0xaa: mov r[11],r[0]
0xab: pop r[0]
0xac: add r[11],r[0]
0xad: mov r[0],r[11]
0xae: mul r[0],r[5]
0xaf: mov r[11],r[0]
0xb0: pop r[0]
0xb1: add r[11],r[0]
0xb2: mov r[0],r[11]
0xb3: mul r[0],r[5]
0xb4: mov r[11],r[0]
0xb5: pop r[0]
0xb6: add r[11],r[0]
0xb7: nop
0xb8: pop r[0]
0xb9: mov r[5],0x100
0xba: mul r[0],r[5]
0xbb: mov r[12],r[0]
0xbc: pop r[0]
0xbd: add r[12],r[0]
0xbe: mov r[0],r[12]
0xbf: mul r[0],r[5]
0xc0: mov r[12],r[0]
0xc1: pop r[0]
0xc2: add r[12],r[0]
0xc3: mov r[0],r[12]
0xc4: mul r[0],r[5]
0xc5: mov r[12],r[0]
0xc6: pop r[0]
0xc7: add r[12],r[0]
0xc8: nop
0xc9: pop r[0]
0xca: mov r[5],0x100
0xcb: mul r[0],r[5]
0xcc: mov r[13],r[0]
0xcd: pop r[0]
0xce: add r[13],r[0]
0xcf: mov r[0],r[13]
0xd0: mul r[0],r[5]
0xd1: mov r[13],r[0]
0xd2: pop r[0]
0xd3: add r[13],r[0]
0xd4: mov r[0],r[13]
0xd5: mul r[0],r[5]
0xd6: mov r[13],r[0]
0xd7: pop r[0]
0xd8: add r[13],r[0]
0xd9: nop
0xda: pop r[0]
0xdb: mov r[5],0x100
0xdc: mul r[0],r[5]
0xdd: mov r[14],r[0]
0xde: pop r[0]
0xdf: add r[14],r[0]
0xe0: mov r[0],r[14]
0xe1: mul r[0],r[5]
0xe2: mov r[14],r[0]
0xe3: pop r[0]
0xe4: add r[14],r[0]
0xe5: mov r[0],r[14]
0xe6: mul r[0],r[5]
0xe7: mov r[14],r[0]
0xe8: pop r[0]
0xe9: add r[14],r[0]
0xea: nop
0xeb: pop r[0]
0xec: mov r[5],0x100
0xed: mul r[0],r[5]
0xee: mov r[15],r[0]
0xef: pop r[0]
0xf0: add r[15],r[0]
0xf1: mov r[0],r[15]
0xf2: mul r[0],r[5]
0xf3: mov r[15],r[0]
0xf4: pop r[0]
0xf5: add r[15],r[0]
0xf6: mov r[0],r[15]
0xf7: mul r[0],r[5]
0xf8: mov r[15],r[0]
0xf9: pop r[0]
0xfa: add r[15],r[0]
0xfb: nop
0xfc: pop r[0]
0xfd: mov r[5],0x100
0xfe: mul r[0],r[5]
0xff: mov r[16],r[0]
0x100: pop r[0]
0x101: add r[16],r[0]
0x102: mov r[0],r[16]
0x103: mul r[0],r[5]
0x104: mov r[16],r[0]
0x105: pop r[0]
0x106: add r[16],r[0]
0x107: mov r[0],r[16]
0x108: mul r[0],r[5]
0x109: mov r[16],r[0]
0x10a: pop r[0]
0x10b: add r[16],r[0]
0x10c: nop
0x10d: push r[6]
0x10e: push r[7]
0x10f: push r[8]
0x110: push r[9]
0x111: push r[10]
0x112: push r[11]
0x113: push r[12]
0x114: push r[13]
0x115: push r[14]
0x116: push r[15]
0x117: push r[16]  ///分隔符 此时全部转化为了uint32 将他们全部压栈
0x118: pop r[1]    -------------------------开始加密和⽐较
0x119: pop r[2]    //以r1,r2为参数调⽤加密
0x11a: mov r[20],0x11c
0x11b: mov r[0],0x154
0x11c: jmp r[0]
0x11d: mov r[0],0xe8d1d5df            // 对⽐结果
0x11e: mov r[19],0x183               //【】 错误输出的地址
0x11f: mov r[20],0x153               // 【】 返回地址,直接结束
0x120: cmp r[1],r[0] -- jnz r[19]  // ⽐较,不同就到错误输出
0x121: mov r[0],0xf5e3c114
0x122: cmp r[2],r[0] -- jnz r[19]  // ⽐较,不同就到错误输出
0x123: pop r[1]    ---------------------------第⼆轮加密和比较以此类推
0x124: pop r[2]
0x125: mov r[20],0x127
0x126: mov r[0],0x154
0x127: jmp r[0]
0x128: mov r[0],0x228ec216
0x129: mov r[19],0x183
0x12a: mov r[20],0x153
0x12b: cmp r[1],r[0] -- jnz r[19]
0x12c: mov r[0],0x89d45a61
0x12d: cmp r[2],r[0] -- jnz r[19]
0x12e: pop r[1]
0x12f: pop r[2]
0x130: mov r[20],0x132
0x131: mov r[0],0x154
0x132: jmp r[0]
0x133: mov r[0],0x655b8f69
0x134: mov r[19],0x183
0x135: mov r[20],0x153
0x136: cmp r[1],r[0] -- jnz r[19]
0x137: mov r[0],0x2484a07a
0x138: cmp r[2],r[0] -- jnz r[19]
0x139: pop r[1]
0x13a: pop r[2]
0x13b: mov r[20],0x13d
0x13c: mov r[0],0x154
0x13d: jmp r[0]
0x13e: mov r[0],0xd9e5e7f8
0x13f: mov r[19],0x183
0x140: mov r[20],0x153
0x141: cmp r[1],r[0] -- jnz r[19]
0x142: mov r[0],0x3a441532
0x143: cmp r[2],r[0] -- jnz r[19]
0x144: pop r[1]
0x145: pop r[2]
0x146: mov r[20],0x148
0x147: mov r[0],0x154
0x148: jmp r[0]
0x149: mov r[0],0x91ab7e88
0x14a: mov r[19],0x183
0x14b: mov r[20],0x153
0x14c: cmp r[1],r[0] -- jnz r[19]
0x14d: mov r[0],0x69fc64bc
0x14e: cmp r[2],r[0] -- jnz r[19]
0x14f: pop r[1]
0x150: mov r[0],0x7d3765
0x151: cmp r[1],r[0] -- jnz r[19]
0x152: mov r[0],0x189
0x153: jmp r[0]
0x154: exit()
0x155: mov r[3],0x9e3779b9    //delta
0x156: mov r[4],0x95c4c       //key1
0x157: mov r[5],0x871d        //key2
0x158: mov r[6],0x1a7b7       //key3
0x159: mov r[7],0x12c7c7      //key4
0x15a: mov r[8],0x0           // sum
0x15b: mov r[17],0x10         // 常量16 ⽤于位移4
0x15c: mov r[18],0x20         // 常量32 ⽤于位移5
0x15d: mov r[19],0x160
0x15e: mov r[10],0x0          //⽤来对⽐次数
0x15f: mov r[11],0x20         //循环次数32次 加密轮数
0x160: mov r[12],0x1          // 跳转回这⾥的下⼀⾏
0x161: add r[8],r[3]          // sum += delta
0x162: mov r[0],r[2]
0x163: mul r[0],r[17]
0x164: add r[0],r[4]
0x165: mov r[14],r[0]
0x166: mov r[0],r[2]
0x167: add r[0],r[8]
0x168: mov r[15],r[0]
0x169: mov r[0],r[2]
0x16a: div r[0],r[18]
0x16b: add r[0],r[5]
0x16c: mov r[16],r[0]
0x16d: mov r[0],r[14]
0x16e: xor r[0],r[15]
0x16f: xor r[0],r[16]
0x170: add r[1],r[0]
0x171: mov r[0],r[1]
0x172: mul r[0],r[17]
0x173: add r[0],r[6]
0x174: mov r[14],r[0]
0x175: mov r[0],r[1]
0x176: add r[0],r[8]
0x177: mov r[15],r[0]
0x178: mov r[0],r[1]
0x179: div r[0],r[18]
0x17a: add r[0],r[7]
0x17b: mov r[16],r[0]
0x17c: mov r[0],r[14]
0x17d: xor r[0],r[15]
0x17e: xor r[0],r[16]
0x17f: add r[2],r[0]
0x180: sub r[11],r[12]
0x181: cmp r[11],r[10] -- jnz r[19]
0x182: jmp r[20]                // jmp r20 函数返回
0x183: nop 
0x184: mov r[0],0x6e
0x185: putchar(r[0)]
0x186: mov r[0],0x6f
0x187: putchar(r[0)]
0x188: jmp r[20]
0x189: nop
0x18a: mov r[0],0x79
0x18b: putchar(r[0)]

长度 44,转为 int 是 11 个,前 10 个两两一组 Tea,最后一个不处理,解密即可。

#include <stdio.h>
#include <stdint.h>
void decrypt (uint32_t* v, uint32_t* k) {
    uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i;  /* set up */
    uint32_t delta=0x9e3779b9;                     /* a key schedule constant */
    uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3];   /* cache key */
    for (i=0; i<32; i++) {                         /* basic cycle start */
        v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
        v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
        sum -= delta;
    }                                              /* end cycle */
    v[0]=v0; v[1]=v1;
}
int main()
{
    uint32_t v[12] = {0xe8d1d5df, 0xf5e3c114, 0x228ec216, 0x89d45a61, 0x655b8f69, 0x2484a07a, 0xd9e5e7f8, 0x3a441532, 0x91ab7e88, 0x69fc64bc, 0x7d3765, 0x00};
    uint32_t k[4] = {0x95c4c, 0x871d, 0x1a7b7, 0x12c7c7};
    for (int i = 0; i < 5; ++i) {
        decrypt(v+i*2, k);
    }
    printf("%s", (char*)v);
}

最后flag

VNCTF{ecd63ae5-8945-4ac4-b5a5-34fc3ade81e7} 

参考两位大佬博客。

VNCTF2022 

VNCTF2022

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值