虚拟机
这是一个虚拟机的题目
上图是虚拟机的执行流程,Dispatcher(分发器)读取Opcode(虚拟机操作码)
然后根据操作码进行跳转执行
所以做这道虚拟机的题,我们就要找到操作码
并且明白操作码对应的含义
然后对操作码进行一句一句的解读,还原出整个程序执行流程
下面我们找一下
主函数中有三个函数
操作码和寄存器
0xF1~0xF6是虚拟机操作码,下面的偏移地址是其对应的函数
F1是赋值给寄存器的操作
看别人的博客,可以将E1,E2,E3,E5看做是EAX,EBX,ECX,EDX
F2是xor
F5是获取字符串长度
0xF4是nop操作
0xF7是两数相乘,mul
0xF8是swap
0xF6是一个线性运算
通过操作码还原程序执行流程
从202060地址中取出操作码执行
我们将操作码提取出来,根据分析好的操作码对应的指令,编写脚本将这些操作码转换成汇编语言形式
len(flag)
mov eax flag[0]
xor eax, ebx
mov flag[32] eax
mov eax flag[1]
xor eax, ebx
mov flag[33] eax
mov eax flag[2]
xor eax, ebx
mov flag[34] eax
mov eax flag[3]
xor eax, ebx
mov flag[35] eax
mov eax flag[4]
xor eax, ebx
mov flag[36] eax
mov eax flag[5]
xor eax, ebx
mov flag[37] eax
mov eax flag[6]
xor eax, ebx
mov flag[38] eax
mov eax flag[7]
xor eax, ebx
mov flag[39] eax
mov eax flag[8]
xor eax, ebx
mov flag[40] eax
mov eax flag[9]
xor eax, ebx
mov flag[41] eax
mov eax flag[10]
xor eax, ebx
mov flag[42] eax
mov eax flag[11]
xor eax, ebx
mov flag[43] eax
mov eax flag[12]
xor eax, ebx
mov flag[44] eax
mov eax flag[13]
xor eax, ebx
mov flag[45] eax
mov eax flag[14]
xor eax, ebx
mov flag[46] eax
mov eax flag[15]
xor eax, ebx
mov flag[47] eax
mov eax flag[16]
xor eax, ebx
mov flag[48] eax
mov eax flag[17]
xor eax, ebx
mov flag[49] eax
mov eax flag[18]
xor eax, ebx
mov flag[50] eax
mov eax flag[19]
xor eax, ebx
mov flag[51] eax
nop
len(flag)
mov eax flag[0]
mov ebx flag[1]
xor eax, ebx
mov flag[0] eax
mov eax flag[1]
mov ebx flag[2]
xor eax, ebx
mov flag[1] eax
mov eax flag[2]
mov ebx flag[3]
xor eax, ebx
mov flag[2] eax
mov eax flag[3]
mov ebx flag[4]
xor eax, ebx
mov flag[3] eax
mov eax flag[4]
mov ebx flag[5]
xor eax, ebx
mov flag[4] eax
mov eax flag[5]
mov ebx flag[6]
xor eax, ebx
mov flag[5] eax
mov eax flag[6]
mov ebx flag[7]
mov ecx flag[8]
mov edx flag[12]
eax = ecx + 2 * ebx + 3 * eax
mul eax, edx
mov flag[6] eax
mov eax flag[7]
mov ebx flag[8]
mov ecx flag[9]
mov edx flag[12]
eax = ecx + 2 * ebx + 3 * eax
mul eax, edx
mov flag[7] eax
mov eax flag[8]
mov ebx flag[9]
mov ecx flag[10]
mov edx flag[12]
eax = ecx + 2 * ebx + 3 * eax
mul eax, edx
mov flag[8] eax
mov eax flag[13]
mov ebx flag[19]
swap eax, ebx
mov flag[13] eax
mov flag[19] ebx
mov eax flag[14]
mov ebx flag[18]
swap eax, ebx
mov flag[14] eax
mov flag[18] ebx
mov eax flag[15]
mov ebx flag[17]
swap eax, ebx
mov flag[15] eax
mov flag[17] ebx
nop
以nop为界限,得到了两段程序
先看第一段
ebx是0x12
主函数中第三个函数是加密之后比较,找到密文
for i in 'Fz{aM{aM|}fMt~suM !!':
print(chr(ord(i)^0x12),end='')
This_is_not_flag_233
给了一个tip
还有一个函数
用第二段函数解密之后得到flag
真正的密文
根据第二段代码写出解密脚本
check = [0x69, 0x45, 0x2A, 0x37, 0x09, 0x17, 0xC5, 0x0B, 0x5C, 0x72,
0x33, 0x76, 0x33, 0x21, 0x74, 0x31, 0x5F, 0x33, 0x73, 0x72]
check[13], check[19] = check[19], check[13]
check[14], check[18] = check[18], check[14]
check[15], check[17] = check[17], check[15]
i = 0
while i < 128:
if check[8] == ((i * 3 + check[9] * 2 + check[10]) * check[12]) & 0xff:
check[8] = i
j = 0
while j < 128:
if check[7] == ((j * 3 + check[8] * 2 + check[9]) * check[12]) & 0xff:
check[7] = j
k = 0
while k < 128:
if check[6] == ((k * 3 + check[7] * 2 + check[8]) * check[12]) & 0xff:
check[6] = k
k += 1
j += 1
i += 1
i = 5
while i >= 0:
check[i] ^= check[i + 1]
i -= 1
flag = ''.join(chr(c) for c in check)
print(flag)
Y0u_hav3_r3v3rs3_1t!