螺丝主站
vm0
先在这里进行了初始化,将opcode跟函数关联起来。
void *vm_init()
{
vm_vpu *cpu;
cpu->r1 = 0;
cpu->r2 = 0;
cpu->r3 = 0;
cpu->eip = (unsigned char *)vm_code;//将eip指向opcode的地址
cpu->op_list[0].opcode = 0xf1;
cpu->op_list[0].handle = (void (*)(void *))mov;//将操作字节码与对应的handle函数关联在一起
cpu->op_list[1].opcode = 0xf2;
cpu->op_list[1].handle = (void (*)(void *))xor;
cpu->op_list[2].opcode = 0xf5;
cpu->op_list[2].handle = (void (*)(void *))read_;
vm_stack = malloc(0x512);
memset(vm_stack,0,0x512);//定义了一个新栈并在malloc上申请了0x512位的空间
之后是入口函数。
void vm_start(vm_cpu *cpu)
{
cpu->eip = (unsigned char*)opcodes;//eip指向要被解释的opcode地址
while((*cpu->eip) != 0xf4)//如果opcode不为RET,就调用vm_dispatcher来解释执行
{
vm_dispatcher(*cpu->eip)
}
再之后就是vm_dispatcher
void vm_dispatcher(vm_cpu *cpu)
{
int j;
for(j=0;j<OPCODE_N;j++)
{
if(*cpu->eip ==cpu->op_list[i].opcode)
{
cpu->op_list[i].handle(cpu);
break;
}
}
}
之后便是具体函数的实现。
现在来具体分析该题:
opcode | 函数 | 功能 |
---|---|---|
0xf1 | sub_564114800B5F | 移动数据到寄存器 |
0xf2 | sub_564114800A64 | r0=r0^r1 |
0xf5 | sub_564114800AC5 | 判断输入长度是否为20 |
0xf4 | sub_564114800956 | 无作用,跳转到下一条指令 |
0xf7 | sub_564114800A08 | r0=r0*r3 |
0xf8 | sub_5641148008F0 | 交换r0和r1数据 |
0xf6 | sub_56411480099C | r0=r2+2*r1+3*r0 |
接下来写一个脚本来模拟一下程序。
脚本如下:
from sympy.strategies.core import switch
mycode = [
0xF5, 0xF1, 0xE1, 0x00, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x20, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x01, 0x00, 0x00,
0x00, 0xF2, 0xF1, 0xE4, 0x21, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x02, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x22, 0x00,
0x00, 0x00, 0xF1, 0xE1, 0x03, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x23, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x04, 0x00,
0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x24, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x05, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x25,
0x00, 0x00, 0x00, 0xF1, 0xE1, 0x06, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x26, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x07,
0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x27, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x08, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4,
0x28, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x09, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x29, 0x00, 0x00, 0x00, 0xF1, 0xE1,
0x0A, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x2A, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x0B, 0x00, 0x00, 0x00, 0xF2, 0xF1,
0xE4, 0x2B, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x0C, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x2C, 0x00, 0x00, 0x00, 0xF1,
0xE1, 0x0D, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x2D, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x0E, 0x00, 0x00, 0x00, 0xF2,
0xF1, 0xE4, 0x2E, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x0F, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x2F, 0x00, 0x00, 0x00,
0xF1, 0xE1, 0x10, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x30, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x11, 0x00, 0x00, 0x00,
0xF2, 0xF1, 0xE4, 0x31, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x12, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x32, 0x00, 0x00,
0x00, 0xF1, 0xE1, 0x13, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, 0x33, 0x00, 0x00, 0x00, 0xF4, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xF5, 0xF1, 0xE1, 0x00, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x01, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4,
0x00, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x01, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x02, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4,
0x01, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x02, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x03, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4,
0x02, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x03, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x04, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4,
0x03, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x04, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x05, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4,
0x04, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x05, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x06, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4,
0x05, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x06, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x07, 0x00, 0x00, 0x00, 0xF1, 0xE3, 0x08,
0x00, 0x00, 0x00, 0xF1, 0xE5, 0x0C, 0x00, 0x00, 0x00, 0xF6, 0xF7, 0xF1, 0xE4, 0x06, 0x00, 0x00, 0x00, 0xF1, 0xE1,
0x07, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x08, 0x00, 0x00, 0x00, 0xF1, 0xE3, 0x09, 0x00, 0x00, 0x00, 0xF1, 0xE5, 0x0C,
0x00, 0x00, 0x00, 0xF6, 0xF7, 0xF1, 0xE4, 0x07, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x08, 0x00, 0x00, 0x00, 0xF1, 0xE2,
0x09, 0x00, 0x00, 0x00, 0xF1, 0xE3, 0x0A, 0x00, 0x00, 0x00, 0xF1, 0xE5, 0x0C, 0x00, 0x00, 0x00, 0xF6, 0xF7, 0xF1,
0xE4, 0x08, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x0D, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x13, 0x00, 0x00, 0x00, 0xF8, 0xF1,
0xE4, 0x0D, 0x00, 0x00, 0x00, 0xF1, 0xE7, 0x13, 0x00, 0x00, 0x00, 0xF1, 0xE1, 0x0E, 0x00, 0x00, 0x00, 0xF1, 0xE2,
0x12, 0x00, 0x00, 0x00, 0xF8, 0xF1, 0xE4, 0x0E, 0x00, 0x00, 0x00, 0xF1, 0xE7, 0x12, 0x00, 0x00, 0x00, 0xF1, 0xE1,
0x0F, 0x00, 0x00, 0x00, 0xF1, 0xE2, 0x11, 0x00, 0x00, 0x00, 0xF8, 0xF1, 0xE4, 0x0F, 0x00, 0x00, 0x00, 0xF1, 0xE7,
0x11, 0x00, 0x00, 0x00, 0xF4
]
for i in range(len(mycode)):
if mycode[i] == 0xF1:
match mycode[i + 1]:
case 0xE1:
print(f"r0=input[{mycode[i + 2]}]")
case 0xE2:
print(f"r1=input[{mycode[i + 2]}]")
case 0xE3:
print(f"r2=input[{mycode[i + 2]}]")
case 0xE4:
print(f"input[{mycode[i + 2]}]=r0")
case 0xE5:
print(f"r3=input[{mycode[i + 2]}]")
case 0xE7:
print(f"input[{mycode[i + 2]}]=r1")
if mycode[i] == 0xF4:
pass
if mycode[i] == 0xF2:
print("r0=r0^r1")
if mycode[i] == 0xF5:
print("判断输入是否为20")
if mycode[i] == 0xF7:
print("r0=r0*r1")
if mycode[i] == 0xF6:
print("r0=r2+2*r1+3*r0")
if mycode[i] == 0xF8:
print("交换r0和r1")
执行结果:
判断输入是否为20
r0=input[0]
r0=r0^r1
input[32]=r0
r0=input[1]
r0=r0^r1
input[33]=r0
r0=input[2]
r0=r0^r1
input[34]=r0
r0=input[3]
r0=r0^r1
input[35]=r0
r0=input[4]
r0=r0^r1
input[36]=r0
r0=input[5]
r0=r0^r1
input[37]=r0
r0=input[6]
r0=r0^r1
input[38]=r0
r0=input[7]
r0=r0^r1
input[39]=r0
r0=input[8]
r0=r0^r1
input[40]=r0
r0=input[9]
r0=r0^r1
input[41]=r0
r0=input[10]
r0=r0^r1
input[42]=r0
r0=input[11]
r0=r0^r1
input[43]=r0
r0=input[12]
r0=r0^r1
input[44]=r0
r0=input[13]
r0=r0^r1
input[45]=r0
r0=input[14]
r0=r0^r1
input[46]=r0
r0=input[15]
r0=r0^r1
input[47]=r0
r0=input[16]
r0=r0^r1
input[48]=r0
r0=input[17]
r0=r0^r1
input[49]=r0
r0=input[18]
r0=r0^r1
input[50]=r0
r0=input[19]
r0=r0^r1
input[51]=r0
判断输入是否为20
r0=input[0]
r1=input[1]
r0=r0^r1
input[0]=r0
r0=input[1]
r1=input[2]
r0=r0^r1
input[1]=r0
r0=input[2]
r1=input[3]
r0=r0^r1
input[2]=r0
r0=input[3]
r1=input[4]
r0=r0^r1
input[3]=r0
r0=input[4]
r1=input[5]
r0=r0^r1
input[4]=r0
r0=input[5]
r1=input[6]
r0=r0^r1
input[5]=r0
r0=input[6]
r1=input[7]
r2=input[8]
r3=input[12]
r0=r2+2*r1+3*r0
r0=r0*r3
input[6]=r0
r0=input[7]
r1=input[8]
r2=input[9]
r3=input[12]
r0=r2+2*r1+3*r0
r0=r0*r3
input[7]=r0
r0=input[8]
r1=input[9]
r2=input[10]
r3=input[12]
r0=r2+2*r1+3*r0
r0=r0*r3
input[8]=r0
r0=input[13]
r1=input[19]
交换r0和r1
input[13]=r0
input[19]=r1
r0=input[14]
r1=input[18]
交换r0和r1
input[14]=r0
input[18]=r1
r0=input[15]
r1=input[17]
交换r0和r1
input[15]=r0
input[17]=r1
r1初始值为18,第一段对其进行了异或。第一段解密如下:
是错的。
第二段呢。
第二段进行了连续异或,然后进行了数学运算,然后进行了交换。
解密脚本如下:
def swapPositions(list, pos1, pos2):
list[pos1], list[pos2] = list[pos2], list[pos1]
return list
enc_data = [0x69, 0x45, 0x2A, 0x37, 0x09, 0x17, 0xC5, 0x0B, 0x5C, 0x72,
0x33, 0x76, 0x33, 0x21, 0x74, 0x31, 0x5F, 0x33, 0x73, 0x72]
enc_data = swapPositions(enc_data,15,17)
enc_data = swapPositions(enc_data,14,18)
enc_data = swapPositions(enc_data,13,19)
r3 = enc_data[12]
for i in range(30,128):
if enc_data[8]==(r3*(i*3+2*enc_data[9]+enc_data[10]))&0xff:
enc_data[8]=i
break
for i in range(30,128):
if enc_data[7]==(r3*(i*3+2*enc_data[8]+enc_data[9]))&0xff:
enc_data[7]=i
break
for i in range(30,128):
if enc_data[6]==(r3*(i*3+2*enc_data[7]+enc_data[8]))&0xff:
enc_data[6]=i
break
for i in range(5,-1,-1):
enc_data[i]^=enc_data[i+1]
for i in range(len(enc_data)):
print(chr(enc_data[i]),end="")
#Y0u_hav3_r3v3rs3_1t!
即得到最终答案
vm1
开幕就是花指令。
Thanks for reading!