深入了解 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}
参考两位大佬博客。