虎符杯——虚拟机逆向

本文详细分析了一个虚拟机的执行过程,包括输入参数的获取、栈顶元素的打印、指令计数器的递增、变量的压栈与赋值等操作。通过对不同指令的解析,展示了如何处理加法、减法、乘法、除法、比较操作等,并解释了如何更新虚拟机栈和寄存器状态。

查壳

在这里插入图片描述

拖进ida

在这里插入图片描述
在这里插入图片描述

有一个输入参数,记得调试时加上参数。即运行时要指定参数./vm , ida调试要在debugger -> process options -> parameters写上参数code
在这里插入图片描述

bss_data{
	Dword vm_eip;
	Dword vm_sp;
	Qword code; // *(bss_data+1)
	Qword vm_stack;  // *(bss_data+2)
	Qword vm_var_arr;  //*(bss_data+3)
	Qword vm_reg;   // *(bss_data+4)
}

核心也就是最后一个分析虚拟机函数这里

vm函数代码

__int64 __fastcall sub_400A50(unsigned int *a1)
{
  __int64 v1; // rcx
  unsigned int *v2; // rbx
  __int64 result; // rax
  __int64 v4; // rdx
  unsigned int v5; // eax
  __int64 v6; // rcx
  _BYTE *v7; // rdx
  int v8; // eax
  char v9; // al
  unsigned int v10; // edx
  __int64 v11; // rsi
  _BYTE *v12; // rax
  __int64 v13; // rcx
  char v14; // cl
  int v15; // er8
  signed int v16; // edx
  __int64 v17; // rdi
  int v18; // esi
  int v19; // er8
  signed int v20; // edx
  __int64 v21; // rdi
  int v22; // esi
  int v23; // er8
  signed int v24; // edx
  __int64 v25; // rdi
  int v26; // esi
  signed int v27; // edx
  __int64 v28; // rdi
  int v29; // esi
  int v30; // er8
  signed int v31; // edx
  __int64 v32; // rdi
  int v33; // esi
  int v34; // edi
  signed int v35; // edx
  __int64 v36; // r8
  int v37; // esi
  int v38; // ecx
  _BYTE *v39; // rax
  __int64 v40; // rdx
  signed int v41; // eax
  int v42; // esi
  char v43; // cl
  char v44; // cl
  signed int v45; // eax
  int v46; // esi
  char v47; // cl
  char v48; // cl
  signed int v49; // eax
  int v50; // esi
  char v51; // cl
  char v52; // cl
  signed int v53; // eax
  __int64 v54; // rdx
  int v55; // esi
  unsigned __int8 v56; // cl
  _BYTE *v57; // rdx
  signed int v58; // eax
  __int64 v59; // rdx
  int v60; // ecx
  unsigned __int8 v61; // si
  signed int v62; // edx
  __int64 v63; // rcx
  int v64; // esi
  char v65; // al
  signed int v66; // eax
  char v67; // si
  signed int v68; // eax
  int v69; // esi
  char v70; // cl
  char v71; // cl
  _BYTE *v72; // rdx
  __int64 v73; // rcx
  int v74; // eax
  __int64 v75; // rax
  __int64 v76; // rdx
  char v77; // cl
  __int64 v78; // rax
  __int64 v79; // rdx
  __int64 v80; // rdx
  _IO_FILE *v81; // rsi
  int v82; // eax
  char v83; // al
  __int64 v84; // rdx
  __int64 v85; // rcx

  v1 = *((_QWORD *)a1 + 1);
  v2 = a1;
  result = *a1;
LABEL_2:
  v4 = (signed int)result;
  while ( 1 )
  {
    switch ( *(_BYTE *)(v1 + v4) )
    {
      case 1:
        v83 = _IO_getc(stdin);
        v84 = (signed int)v2[1];
        v85 = *((_QWORD *)v2 + 2);
        v2[1] = v84 + 1;
        *(_BYTE *)(v85 + v84) = v83;
        v1 = *((_QWORD *)v2 + 1);
        result = *v2 + 1;
        *v2 = result;
        goto LABEL_2;
      case 2:
        v80 = *((_QWORD *)v2 + 2);
        v81 = stdout;
        v82 = v2[1] - 1;
        v2[1] = v82;
        _IO_putc(*(unsigned __int8 *)(v80 + v82), v81);
        v1 = *((_QWORD *)v2 + 1);
        result = *v2 + 1;
        *v2 = result;
        goto LABEL_2;
      case 3:
        result = (unsigned int)(result + 1);
        *v2 = result;
        goto LABEL_2;
      case 4:
        v77 = *(_BYTE *)(v1 + v4 + 1);
        goto LABEL_44;
      case 5:
        v75 = *(unsigned __int8 *)(v1 + v4 + 1);
        v76 = *((_QWORD *)v2 + 4);
        goto LABEL_43;
      case 6:
        v72 = (_BYTE *)(*((_QWORD *)v2 + 4) + *(unsigned __int8 *)(v1 + v4 + 1));
        goto LABEL_41;
      case 7:
        v75 = *(unsigned __int8 *)(v1 + v4 + 1);
        v76 = *((_QWORD *)v2 + 3);
LABEL_43:
        v77 = *(_BYTE *)(v76 + v75);
LABEL_44:
        v78 = (signed int)v2[1];
        v79 = *((_QWORD *)v2 + 2);
        v2[1] = v78 + 1;
        *(_BYTE *)(v79 + v78) = v77;
        v1 = *((_QWORD *)v2 + 1);
        result = *v2 + 2;
        *v2 = result;
        goto LABEL_2;
      case 8:
        v72 = (_BYTE *)(*((_QWORD *)v2 + 3) + *(unsigned __int8 *)(v1 + v4 + 1));
LABEL_41:
        v73 = *((_QWORD *)v2 + 2);
        v74 = v2[1] - 1;
        v2[1] = v74;
        *v72 = *(_BYTE *)(v73 + v74);
        v1 = *((_QWORD *)v2 + 1);
        result = *v2 + 2;
        *v2 = result;
        goto LABEL_2;
      case 9:
        v68 = v2[1];
        v40 = *((_QWORD *)v2 + 2);
        v69 = v68 - 1;
        v68 -= 2;
        v2[1] = v69;
        v70 = *(_BYTE *)(v40 + v69);
        v2[1] = v68;
        v39 = (_BYTE *)(v40 + v68);
        v71 = *v39 + v70;
        v2[1] = v69;
        LOBYTE(v40) = v71;
        goto LABEL_28;
      case 0xA:
        v66 = v2[1];
        v40 = *((_QWORD *)v2 + 2);
        v38 = v66 - 1;
        v66 -= 2;
        v2[1] = v38;
        v67 = *(_BYTE *)(v40 + v38);
        v2[1] = v66;
        v39 = (_BYTE *)(v40 + v66);
        LOBYTE(v40) = *v39 - v67;
        goto LABEL_27;
      case 0xB:
        v62 = v2[1];
        v63 = *((_QWORD *)v2 + 2);
        v64 = v62 - 1;
        v62 -= 2;
        v2[1] = v64;
        v65 = *(_BYTE *)(v63 + v64);
        v2[1] = v62;
        v7 = (_BYTE *)(v63 + v62);
        v9 = *v7 * v65;
        v2[1] = v64;
        goto LABEL_8;
      case 0xC:
        v58 = v2[1];
        v59 = *((_QWORD *)v2 + 2);
        v60 = v58 - 1;
        v58 -= 2;
        v2[1] = v60;
        v61 = *(_BYTE *)(v59 + v60);
        v2[1] = v58;
        v7 = (_BYTE *)(v58 + v59);
        result = (unsigned __int8)*v7;
        if ( !v61 )
          return result;
        v2[1] = v60;
        v9 = (unsigned __int16)result / v61;
        goto LABEL_8;
      case 0xD:
        v53 = v2[1];
        v54 = *((_QWORD *)v2 + 2);
        v55 = v53 - 1;
        v53 -= 2;
        v2[1] = v55;
        v56 = *(_BYTE *)(v54 + v55);
        v2[1] = v53;
        v57 = (_BYTE *)(v53 + v54);
        LOWORD(v53) = (unsigned __int8)*v57;
        v2[1] = v55;
        result = (unsigned __int8)((unsigned __int16)v53 % v56);
        *v57 = result;
        if ( !v56 )
          return result;
        goto LABEL_9;
      case 0xE:
        v49 = v2[1];
        v40 = *((_QWORD *)v2 + 2);
        v50 = v49 - 1;
        v49 -= 2;
        v2[1] = v50;
        v51 = *(_BYTE *)(v40 + v50);
        v2[1] = v49;
        v39 = (_BYTE *)(v40 + v49);
        v52 = *v39 ^ v51;
        v2[1] = v50;
        LOBYTE(v40) = v52;
        goto LABEL_28;
      case 0xF:
        v45 = v2[1];
        v40 = *((_QWORD *)v2 + 2);
        v46 = v45 - 1;
        v45 -= 2;
        v2[1] = v46;
        v47 = *(_BYTE *)(v40 + v46);
        v2[1] = v45;
        v39 = (_BYTE *)(v40 + v45);
        v48 = *v39 & v47;
        v2[1] = v46;
        LOBYTE(v40) = v48;
        goto LABEL_28;
      case 0x10:
        v41 = v2[1];
        v40 = *((_QWORD *)v2 + 2);
        v42 = v41 - 1;
        v41 -= 2;
        v2[1] = v42;
        v43 = *(_BYTE *)(v40 + v42);
        v2[1] = v41;
        v39 = (_BYTE *)(v40 + v41);
        v44 = *v39 | v43;
        v2[1] = v42;
        LOBYTE(v40) = v44;
        goto LABEL_28;
      case 0x11:
        v38 = v2[1];
        v2[1] = v38 - 1;
        v39 = (_BYTE *)(*((_QWORD *)v2 + 2) + v38 - 1);
        LODWORD(v40) = -(unsigned __int8)*v39;
        goto LABEL_27;
      case 0x12:
        v38 = v2[1];
        v2[1] = v38 - 1;
        v39 = (_BYTE *)(*((_QWORD *)v2 + 2) + v38 - 1);
        LOBYTE(v40) = ~*v39;
LABEL_27:
        v2[1] = v38;
LABEL_28:
        *v39 = v40;
        v1 = *((_QWORD *)v2 + 1);
        result = *v2 + 1;
        *v2 = result;
        goto LABEL_2;
      case 0x13:
        v15 = *(unsigned __int8 *)(v1 + v4 + 1);
        v27 = v2[1];
        v28 = *((_QWORD *)v2 + 2);
        v29 = v27 - 1;
        v27 -= 2;
        v2[1] = v29;
        LOBYTE(v29) = *(_BYTE *)(v28 + v29);
        v2[1] = v27;
        if ( *(_BYTE *)(v28 + v27) != (_BYTE)v29 )
          goto LABEL_21;
        goto LABEL_15;
      case 0x14:
        v34 = *(char *)(v1 + v4 + 1);
        v35 = v2[1];
        v36 = *((_QWORD *)v2 + 2);
        v37 = v35 - 1;
        v35 -= 2;
        v2[1] = v37;
        LOBYTE(v37) = *(_BYTE *)(v36 + v37);
        v2[1] = v35;
        if ( *(_BYTE *)(v36 + v35) == (_BYTE)v37 )
          goto LABEL_21;
        result = (unsigned int)(v34 + result);
        *v2 = result;
        goto LABEL_2;
      case 0x15:
        v30 = *(char *)(v1 + v4 + 1);
        v31 = v2[1];
        v32 = *((_QWORD *)v2 + 2);
        v33 = v31 - 1;
        v31 -= 2;
        v2[1] = v33;
        LOBYTE(v33) = *(_BYTE *)(v32 + v33);
        v2[1] = v31;
        if ( *(_BYTE *)(v32 + v31) <= (unsigned __int8)v33 )
          goto LABEL_21;
        result = (unsigned int)(v30 + result);
        *v2 = result;
        goto LABEL_2;
      case 0x16:
        v23 = *(char *)(v1 + v4 + 1);
        v24 = v2[1];
        v25 = *((_QWORD *)v2 + 2);
        v26 = v24 - 1;
        v24 -= 2;
        v2[1] = v26;
        LOBYTE(v26) = *(_BYTE *)(v25 + v26);
        v2[1] = v24;
        if ( *(_BYTE *)(v25 + v24) < (unsigned __int8)v26 )
          goto LABEL_21;
        result = (unsigned int)(v23 + result);
        *v2 = result;
        goto LABEL_2;
      case 0x17:
        v19 = *(char *)(v1 + v4 + 1);
        v20 = v2[1];
        v21 = *((_QWORD *)v2 + 2);
        v22 = v20 - 1;
        v20 -= 2;
        v2[1] = v22;
        LOBYTE(v22) = *(_BYTE *)(v21 + v22);
        v2[1] = v20;
        if ( *(_BYTE *)(v21 + v20) >= (unsigned __int8)v22 )
          goto LABEL_21;
        result = (unsigned int)(v19 + result);
        *v2 = result;
        goto LABEL_2;
      case 0x18:
        v15 = *(char *)(v1 + v4 + 1);
        v16 = v2[1];
        v17 = *((_QWORD *)v2 + 2);
        v18 = v16 - 1;
        v16 -= 2;
        v2[1] = v18;
        LOBYTE(v18) = *(_BYTE *)(v17 + v18);
        v2[1] = v16;
        if ( *(_BYTE *)(v17 + v16) > (unsigned __int8)v18 )
        {
LABEL_21:
          result = (unsigned int)(result + 2);
          *v2 = result;
        }
        else
        {
LABEL_15:
          result = (unsigned int)(v15 + result);
          *v2 = result;
        }
        goto LABEL_2;
      case 0x19:
        v10 = v2[1];
        v11 = *((_QWORD *)v2 + 3);
        v2[1] = v10 - 1;
        v12 = (_BYTE *)(*((_QWORD *)v2 + 2) + (signed int)(v10 - 1));
        v13 = (unsigned __int8)*v12;
        goto LABEL_11;
      case 0x1A:
        v5 = v2[1];
        v6 = *((_QWORD *)v2 + 2);
        v2[1] = v5 - 1;
        v7 = (_BYTE *)(*((_QWORD *)v2 + 3) + *(unsigned __int8 *)(v6 + (signed int)(v5 - 1)));
        goto LABEL_7;
      case 0x1B:
        v10 = v2[1];
        v11 = *((_QWORD *)v2 + 4);
        v2[1] = v10 - 1;
        v12 = (_BYTE *)(*((_QWORD *)v2 + 2) + (signed int)(v10 - 1));
        v13 = (unsigned __int8)*v12;
LABEL_11:
        v14 = *(_BYTE *)(v11 + v13);
        v2[1] = v10;
        *v12 = v14;
        v1 = *((_QWORD *)v2 + 1);
        result = *v2 + 1;
        *v2 = result;
        goto LABEL_2;
      case 0x1C:
        v5 = v2[1];
        v6 = *((_QWORD *)v2 + 2);
        v2[1] = v5 - 1;
        v7 = (_BYTE *)(*((_QWORD *)v2 + 4) + *(unsigned __int8 *)(v6 + (signed int)(v5 - 1)));
LABEL_7:
        v8 = v5 - 2;
        v2[1] = v8;
        v9 = *(_BYTE *)(v6 + v8);
LABEL_8:
        *v7 = v9;
LABEL_9:
        v1 = *((_QWORD *)v2 + 1);
        result = *v2 + 1;
        *v2 = result;
        goto LABEL_2;
      case 0x1D:
        result = (unsigned int)(*(char *)(v1 + v4 + 1) + (_DWORD)result);
        v4 = (signed int)result;
        *v2 = result;
        if ( *(_BYTE *)(v1 + (signed int)result) > 0x1Du )
          return result;
        break;
      default:
        return result;
    }
  }
}

逐步分析vm函数

push[input]

 case 1:                                 
        v83 = _IO_getc(stdin);
        v84 = (signed int)bss_data[1];
        v85 = *((_QWORD *)bss_data + 2);
        bss_data[1] = v84 + 1;
        *(_BYTE *)(v85 + v84) = v83;
        code = *((_QWORD *)bss_data + 1);
        vm_eip2 = *bss_data + 1;
        *bss_data = vm_eip2;
        goto next;

v84是vm_sp,v85是vm_stackv84+v85也就代表到了虚拟机栈顶,然后把输入参数v83赋值给它,这就是虚拟机的输入。(在赋值之前把结构体的vm_sp加了1,也就代表压入了参数后,栈顶指针需要抬高)赋值之后需要把eip(控制程序执行流程)往下挪动,放入vm_eip中,接下来就是取出bss_data中的code,然后准备下一个执行命令的opcode = *(&code + vm_eip)

print vm_stack[vm_sp]

case 2:                                  
        v80 = *((_QWORD *)bss_data + 2);
        v81 = stdout;
        v82 = bss_data[1] - 1;
        bss_data[1] = v82;
        _IO_putc(*(unsigned __int8 *)(v80 + v82), v81);
        code = *((_QWORD *)bss_data + 1);
        vm_eip2 = *bss_data + 1;
        *bss_data = vm_eip2;
        goto next;

v80vm_stackv81是输出参数,v82vm_sp-1,然后把结构体中的栈顶指针编程vm_sp-1,紧接调用函数,然后传入 vm_sp+vm_stack ,和输出参数v81,调用函数_IO_putc,接下来就是取出bss_data中的code,然后准备下一个执行命令的opcode = *(&code + vm_eip)

eip++

 case 3:
        vm_eip2 = (unsigned int)(vm_eip2 + 1);
        *bss_data = vm_eip2;
        goto next;

push *(_BYTE *)(code + vm_eip + 1)

case 4:                                   
        v77 = *(_BYTE *)(code + vm_eip + 1);
        goto ;

:
        v78 = (signed int)bss_data[1];
        v79 = *((_QWORD *)bss_data + 2);
        bss_data[1] = v78 + 1;
        *(_BYTE *)(v79 + v78) = v77;
        code = *((_QWORD *)bss_data + 1);
        vm_eip2 = *bss_data + 2;
        *bss_data = vm_eip2;
        goto next;

*(&code + vm_eip)这个是opcode,然后把*(_BYTE *)(code + vm_eip + 1)压入栈顶(这个盲猜是一个变量),和上面一样,压入vm_sp+vm_stack的位置,然后改变code和vm_eip,也就是opcode,紧接着下一步的操作

push vm_reg[opcode+1]

case 5:
        v75 = *(unsigned __int8 *)(code + vm_eip + 1);
        v76 = *((_QWORD *)bss_data + 4);
        goto push;

push:
        v77 = *(_BYTE *)(v76 + v75);
:
        v78 = (signed int)bss_data[1];
        v79 = *((_QWORD *)bss_data + 2);
        bss_data[1] = v78 + 1;
        *(_BYTE *)(v79 + v78) = v77;
        code = *((_QWORD *)bss_data + 1);
        vm_eip2 = *bss_data + 2;
        *bss_data = vm_eip2;
        goto next;

code + vm_eip+1 赋给 v75vm_reg赋给v76,然后vm_reg+opcode然后取内存值(这里我觉得这个vm_reg就是一个数组,然后opcode+1是一个索引),也就是取了一个vm_reg[opcode+1],然后把这个值push到了虚拟机栈顶

vm_reg[opcode+1]=vm_stack[vm_sp-1]

case 6:                                 
        v72 = (_BYTE *)(*((_QWORD *)bss_data + 4) + *(unsigned __int8 *)(code + vm_eip + 1));
        goto LABEL_41;
 LABEL_41:
        v73 = *((_QWORD *)bss_data + 2);      
        v74 = bss_data[1] - 1;                 
        bss_data[1] = v74;
        *v72 = *(_BYTE *)(v73 + v74);         
        code = *((_QWORD *)bss_data + 1);
        vm_eip2 = *bss_data + 2;               
        *bss_data = vm_eip2;
        goto next;

opcode+vm_reg的地址值赋值给v72vm_stack赋给v73vm_sp-1赋给v74,然后放入bss_data中,紧接着把栈中的值赋给opcode+vm_reg的地址单元(v72 = (_BYTE *)(v73 + v74);),总结如下:vm_reg[opcode]=vm_stack[vm_sp]

push vm_var_arr[opcode+1]

      case 7:
        v75 = *(unsigned __int8 *)(code + vm_eip + 1);
        v76 = *((_QWORD *)bss_data + 3);
push:
        v77 = *(_BYTE *)(v76 + v75);
:
        v78 = (signed int)bss_data[1];
        v79 = *((_QWORD *)bss_data + 2);
        bss_data[1] = v78 + 1;
        *(_BYTE *)(v79 + v78) = v77;
        code = *((_QWORD *)bss_data + 1);
        vm_eip2 = *bss_data + 2;
        *bss_data = vm_eip2;
        goto next;

v75也就是opcode+1,v76也就是vm_var_arr,v77也就是一个以arr为起始地址,以opcode+1为索引的数组值,然后把这个值放在栈顶,也就是push进去

vm_var[opcode+1]=vm_stack[vm_sp-1]

      case 8:                                  
        v72 = (_BYTE *)(*((_QWORD *)bss_data + 3) + *(unsigned __int8 *)(code + vm_eip + 1));
LABEL_41:
        v73 = *((_QWORD *)bss_data + 2);      
        v74 = bss_data[1] - 1;                
        bss_data[1] = v74;
        *v72 = *(_BYTE *)(v73 + v74);         
        code = *((_QWORD *)bss_data + 1);
        vm_eip2 = *bss_data + 2;               
        *bss_data = vm_eip2;
        goto next;

opcode+1+vm_var的地址赋给v72,也就是以vm_var为起始地址,然后以opcode+1的索引值,也就到了相应数组元素的地址,紧接着把vm_stack[vm_sp-1]赋给vm_var[opcode+1]

加法

      case 9:                                 
        v68 = bss_data[1];                             
        v40 = *((_QWORD *)bss_data + 2);       
        v69 = v68 - 1;                         
        v68 -= 2;                             
        bss_data[1] = v69;
        v70 = *(_BYTE *)(v40 + v69);
        bss_data[1] = v68;
        v39 = (_BYTE *)(v40 + v68);
        v71 = *v39 + v70;                      
        bss_data[1] = v69;
        LOBYTE(v40) = v71;
        goto LABEL_28;
LABEL_28:
        *v39 = v40;
        code = *((_QWORD *)bss_data + 1);
        vm_eip2 = *bss_data + 1;
        *bss_data = vm_eip2;
        goto next;

vm_sp赋给v68vm_stack赋给v40vm_sp-1+v40vm_sp-2+v40分别取出两个变量,然后把它俩的和赋给v71,最后再放在v39地址单元中。

减法(分析同上)

      case 0xA:                               
        v66 = bss_data[1];
        v40 = *((_QWORD *)bss_data + 2);
        v38 = v66 - 1;
        v66 -= 2;
        bss_data[1] = v38;
        v67 = *(_BYTE *)(v40 + v38);
        bss_data[1] = v66;
        v39 = (_BYTE *)(v40 + v66);
        LOBYTE(v40) = *v39 - v67;               
        goto LABEL_27;
 LABEL_27:
        bss_data[1] = v38;
LABEL_28:
        *v39 = v40;
        code = *((_QWORD *)bss_data + 1);
        vm_eip2 = *bss_data + 1;
        *bss_data = vm_eip2;
        goto next;       

vm_sp赋给v66vm_stack赋给v40vm_sp-1+v40vm_sp-2+v40分别取出两个变量,然后把它俩的差赋给v40,最后再放在v39地址单元中。

乘法(分析同上)

      case 0xB:                               
        v62 = bss_data[1];
        v63 = *((_QWORD *)bss_data + 2);
        v64 = v62 - 1;
        v62 -= 2;
        bss_data[1] = v64;
        v65 = *(_BYTE *)(v63 + v64);
        bss_data[1] = v62;
        v7 = (_BYTE *)(v63 + v62);
        v9 = *v7 * v65;                         
        bss_data[1] = v64;
 		goto LABEL_8;
LABEL_8:
        *v7 = v9;
LABEL_9:
        code = *((_QWORD *)bss_data + 1);
        vm_eip2 = *bss_data + 1;
        *bss_data = vm_eip2;
        goto next;

除法(分析同上)

      case 0xC:
        v58 = bss_data[1];
        v59 = *((_QWORD *)bss_data + 2);
        v60 = v58 - 1;
        v58 -= 2;
        bss_data[1] = v60;
        v61 = *(_BYTE *)(v59 + v60);
        bss_data[1] = v58;
        v7 = (_BYTE *)(v58 + v59);
        vm_eip2 = (unsigned __int8)*v7;
        if ( !v61 )
          return vm_eip2;
        bss_data[1] = v60;
        v9 = (unsigned __int16)vm_eip2 / v61;  
        goto LABEL_8;
 LABEL_8:
        *v7 = v9;
LABEL_9:
        code = *((_QWORD *)bss_data + 1);
        vm_eip2 = *bss_data + 1;
        *bss_data = vm_eip2;
        goto next;

求余核心(分析同上)

case 0xD:                              
        v53 = bss_data[1];
        v54 = *((_QWORD *)bss_data + 2);
        v55 = v53 - 1;
        v53 -= 2;
        bss_data[1] = v55;
        v56 = *(_BYTE *)(v54 + v55);
        bss_data[1] = v53;
        v57 = (_BYTE *)(v53 + v54);
        LOWORD(v53) = (unsigned __int8)*v57;
        bss_data[1] = v55;
        vm_eip2 = (unsigned __int8)((unsigned __int16)v53 % v56);
        *v57 = vm_eip2;
        if ( !v56 )
          return vm_eip2;
        goto LABEL_9;
LABEL_9:
        code = *((_QWORD *)bss_data + 1);
        vm_eip2 = *bss_data + 1;
        *bss_data = vm_eip2;
        goto next;

异或核心

 case 0xE:
        v49 = bss_data[1];
        v40 = *((_QWORD *)bss_data + 2);
        v50 = v49 - 1;
        v49 -= 2;
        bss_data[1] = v50;
        v51 = *(_BYTE *)(v40 + v50);
        bss_data[1] = v49;
        v39 = (_BYTE *)(v40 + v49);
        v52 = *v39 ^ v51;                      
        bss_data[1] = v50;
        LOBYTE(v40) = v52;
        goto LABEL_28;

按位与核心

      case 0xF:                                
        v45 = bss_data[1];
        v40 = *((_QWORD *)bss_data + 2);
        v46 = v45 - 1;
        v45 -= 2;
        bss_data[1] = v46;
        v47 = *(_BYTE *)(v40 + v46);
        bss_data[1] = v45;
        v39 = (_BYTE *)(v40 + v45);
        v48 = *v39 & v47;                    
        bss_data[1] = v46;
        LOBYTE(v40) = v48;
        goto LABEL_28;

按位或核心

      case 0x10:                            
        v41 = bss_data[1];
        v40 = *((_QWORD *)bss_data + 2);
        v42 = v41 - 1;
        v41 -= 2;
        bss_data[1] = v42;
        v43 = *(_BYTE *)(v40 + v42);
        bss_data[1] = v41;
        v39 = (_BYTE *)(v40 + v41);
        v44 = *v39 | v43;                      
        bss_data[1] = v42;
        LOBYTE(v40) = v44;
        goto LABEL_28;

取地址单元值核心

      case 0x11:
        v38 = bss_data[1];
        bss_data[1] = v38 - 1;
        v39 = (_BYTE *)(*((_QWORD *)bss_data + 2) + v38 - 1);
        LODWORD(v40) = -(unsigned __int8)*v39; 
        goto LABEL_27;
LABEL_27:
        bss_data[1] = v38;
LABEL_28:
        *v39 = v40;
        code = *((_QWORD *)bss_data + 1);
        vm_eip2 = *bss_data + 1;
        *bss_data = vm_eip2;
        goto next;

取反核心

case 0x12:                              
        v38 = bss_data[1];
        bss_data[1] = v38 - 1;
        v39 = (_BYTE *)(*((_QWORD *)bss_data + 2) + v38 - 1);
        LOBYTE(v40) = ~*v39;                    
LABEL_27:
        bss_data[1] = v38;
LABEL_28:
        *v39 = v40;
        code = *((_QWORD *)bss_data + 1);
        vm_eip2 = *bss_data + 1;
        *bss_data = vm_eip2;
        goto next;

vm_stack[vm_sp-1] != vm_stack[vm_sp-2]

 case 0x13:
        v15 = *(unsigned __int8 *)(code + vm_eip + 1);
        v27 = bss_data[1];
        v28 = *((_QWORD *)bss_data + 2);
        v29 = v27 - 1;
        v27 -= 2;
        bss_data[1] = v29;
        LOBYTE(v29) = *(_BYTE *)(v28 + v29);
        bss_data[1] = v27;
        if ( *(_BYTE *)(v28 + v27) != (_BYTE)v29 )
          goto LABEL_21;
        goto LABEL_15;

vm_stack[vm_sp-1] == vm_stack[vm_sp-2]

      case 0x14:                               
        v34 = *(char *)(code + vm_eip + 1);
        v35 = bss_data[1];
        v36 = *((_QWORD *)bss_data + 2);
        v37 = v35 - 1;
        v35 -= 2;
        bss_data[1] = v37;
        LOBYTE(v37) = *(_BYTE *)(v36 + v37);
        bss_data[1] = v35;
        if ( *(_BYTE *)(v36 + v35) == (_BYTE)v37 )
          goto LABEL_21;
        vm_eip2 = (unsigned int)(v34 + vm_eip2);
        *bss_data = vm_eip2;
        goto next;

vm_stack[vm_sp-2] <= vm_stack[vm_sp-1]

      case 0x15:
        v30 = *(char *)(code + vm_eip + 1);
        v31 = bss_data[1];
        v32 = *((_QWORD *)bss_data + 2);
        v33 = v31 - 1;
        v31 -= 2;
        bss_data[1] = v33;
        LOBYTE(v33) = *(_BYTE *)(v32 + v33);
        bss_data[1] = v31;
        if ( *(_BYTE *)(v32 + v31) <= (unsigned __int8)v33 )
          goto LABEL_21;
        vm_eip2 = (unsigned int)(v30 + vm_eip2);
        *bss_data = vm_eip2;
        goto next;

vm_stack[vm_sp-2] < vm_stack[vm_sp-1]

      case 0x16:                              
        v23 = *(char *)(code + vm_eip + 1);
        v24 = bss_data[1];
        v25 = *((_QWORD *)bss_data + 2);
        v26 = v24 - 1;
        v24 -= 2;
        bss_data[1] = v26;
        LOBYTE(v26) = *(_BYTE *)(v25 + v26);
        bss_data[1] = v24;
        if ( *(_BYTE *)(v25 + v24) < (unsigned __int8)v26 )
          goto LABEL_21;
        vm_eip2 = (unsigned int)(v23 + vm_eip2);
        *bss_data = vm_eip2;
        goto next;

vm_stack[vm_sp-2] >=vm_stack[vm_sp-1]

      case 0x17:
        v19 = *(char *)(code + vm_eip + 1);
        v20 = bss_data[1];
        v21 = *((_QWORD *)bss_data + 2);
        v22 = v20 - 1;
        v20 -= 2;
        bss_data[1] = v22;
        LOBYTE(v22) = *(_BYTE *)(v21 + v22);
        bss_data[1] = v20;
        if ( *(_BYTE *)(v21 + v20) >= (unsigned __int8)v22 )
          goto LABEL_21;
        vm_eip2 = (unsigned int)(v19 + vm_eip2);
        *bss_data = vm_eip2;
        goto next;

vm_stack[vm_sp-2] >vm_stack[vm_sp-1]

 case 0x18:                             
        v15 = *(char *)(code + vm_eip + 1);
        v16 = bss_data[1];
        v17 = *((_QWORD *)bss_data + 2);
        v18 = v16 - 1;
        v16 -= 2;
        bss_data[1] = v18;
        LOBYTE(v18) = *(_BYTE *)(v17 + v18);
        bss_data[1] = v16;
        if ( *(_BYTE *)(v17 + v16) > (unsigned __int8)v18 )
        {
LABEL_21:
          vm_eip2 = (unsigned int)(vm_eip2 + 2);
          *bss_data = vm_eip2;
        }
        else
        {
LABEL_15:
          vm_eip2 = (unsigned int)(v15 + vm_eip2);
          *bss_data = vm_eip2;
        }
        goto next;

vm_stack[vm_sp-1] = vm_arr[vm_stack[vm_sp-1]]

      case 0x19:                             
        v10 = bss_data[1];
        v11 = *((_QWORD *)bss_data + 3);
        bss_data[1] = v10 - 1;
        v12 = (_BYTE *)(*((_QWORD *)bss_data + 2) + (signed int)(v10 - 1));
        v13 = (unsigned __int8)*v12;
        goto LABEL_11;
  LABEL_11:
        v14 = *(_BYTE *)(v11 + v13);
        bss_data[1] = v10;
        *v12 = v14;
        code = *((_QWORD *)bss_data + 1);
        vm_eip2 = *bss_data + 1;
        *bss_data = vm_eip2;
        goto next;

vm_arr[vm_stack[vm_sp-1]] = vm_stack[vm_sp-2]

      case 0x1A:                      
        v5 = bss_data[1];
        v6 = *((_QWORD *)bss_data + 2);
        bss_data[1] = v5 - 1;
        v7 = (_BYTE *)(*((_QWORD *)bss_data + 3) + *(unsigned __int8 *)(v6 + (signed int)(v5 - 1)));
        goto LABEL_7;
  LABEL_7:
        v8 = v5 - 2;
        bss_data[1] = v8;
        v9 = *(_BYTE *)(v6 + v8);
LABEL_8:
        *v7 = v9;
LABEL_9:
        code = *((_QWORD *)bss_data + 1);
        vm_eip2 = *bss_data + 1;
        *bss_data = vm_eip2;
        goto next;

vm_stack[vm_sp-1]=vm_reg[vm_stack[vm_sp-1]]

     case 0x1B:
        v10 = bss_data[1];
        v11 = *((_QWORD *)bss_data + 4);
        bss_data[1] = v10 - 1;
        v12 = (_BYTE *)(*((_QWORD *)bss_data + 2) + (signed int)(v10 - 1));
        v13 = (unsigned __int8)*v12;
LABEL_11:
        v14 = *(_BYTE *)(v11 + v13);
        bss_data[1] = v10;
        *v12 = v14;
        code = *((_QWORD *)bss_data + 1);
        vm_eip2 = *bss_data + 1;
        *bss_data = vm_eip2;
        goto next;

vm_block[vm_stack[vm_sp-1]] = vm_stack[vm_sp-2]

     case 0x1C:                            
        v5 = bss_data[1];
        v6 = *((_QWORD *)bss_data + 2);
        bss_data[1] = v5 - 1;
        v7 = (_BYTE *)(*((_QWORD *)bss_data + 4) + *(unsigned __int8 *)(v6 + (signed int)(v5 - 1)));
LABEL_7:
        v8 = v5 - 2;
        bss_data[1] = v8;
        v9 = *(_BYTE *)(v6 + v8);
LABEL_8:
        *v7 = v9;
LABEL_9:
        code = *((_QWORD *)bss_data + 1);
        vm_eip2 = *bss_data + 1;
        *bss_data = vm_eip2;
        goto next;

opcode >0x1D

      case 0x1D:                              
        vm_eip2 = (unsigned int)(*(char *)(code + vm_eip + 1) + (_DWORD)vm_eip2);
        vm_eip = (signed int)vm_eip2;
        *bss_data = vm_eip2;
        if ( *(_BYTE *)(code + (signed int)vm_eip2) > 0x1Du )
          return vm_eip2;
        break;
      default:
        return vm_eip2;
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

寻梦&之璐

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值