文章目录

  • 查壳
  • 拖进ida
  • vm函数代码
  • 逐步分析vm函数
    • push[input]
    • print vm_stack[vm_sp]
    • eip++
    • push `*(_BYTE *)(code + vm_eip + 1)`
    • push vm_reg[opcode+1]
    • vm_reg[opcode+1]=vm_stack[vm_sp-1]
    • push vm_var_arr[opcode+1]
    • vm_var[opcode+1]=vm_stack[vm_sp-1]
    • 加法
    • 减法(分析同上)
    • 乘法(分析同上)
    • 除法(分析同上)
    • 求余核心(分析同上)
    • 异或核心
    • 按位与核心
    • 按位或核心
    • 取地址单元值核心
    • 取反核心
    • vm_stack[vm_sp-1] != vm_stack[vm_sp-2]
    • vm_stack[vm_sp-1] == vm_stack[vm_sp-2]
    • vm_stack[vm_sp-2] <= vm_stack[vm_sp-1]
    • vm_stack[vm_sp-2] < vm_stack[vm_sp-1]
    • vm_stack[vm_sp-2] >=vm_stack[vm_sp-1]
    • vm_stack[vm_sp-2] >vm_stack[vm_sp-1]
    • vm_stack[vm_sp-1] = vm_arr[vm_stack[vm_sp-1]]
    • vm_arr[vm_stack[vm_sp-1]] = vm_stack[vm_sp-2]
    • vm_stack[vm_sp-1]=vm_reg[vm_stack[vm_sp-1]]
    • vm_block[vm_stack[vm_sp-1]] = vm_stack[vm_sp-2]
    • opcode >0x1D

查壳

拖进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; // rcxunsigned int *v2; // rbx__int64 result; // rax__int64 v4; // rdxunsigned int v5; // eax__int64 v6; // rcx_BYTE *v7; // rdxint v8; // eaxchar v9; // alunsigned int v10; // edx__int64 v11; // rsi_BYTE *v12; // rax__int64 v13; // rcxchar v14; // clint v15; // er8signed int v16; // edx__int64 v17; // rdiint v18; // esiint v19; // er8signed int v20; // edx__int64 v21; // rdiint v22; // esiint v23; // er8signed int v24; // edx__int64 v25; // rdiint v26; // esisigned int v27; // edx__int64 v28; // rdiint v29; // esiint v30; // er8signed int v31; // edx__int64 v32; // rdiint v33; // esiint v34; // edisigned int v35; // edx__int64 v36; // r8int v37; // esiint v38; // ecx_BYTE *v39; // rax__int64 v40; // rdxsigned int v41; // eaxint v42; // esichar v43; // clchar v44; // clsigned int v45; // eaxint v46; // esichar v47; // clchar v48; // clsigned int v49; // eaxint v50; // esichar v51; // clchar v52; // clsigned int v53; // eax__int64 v54; // rdxint v55; // esiunsigned __int8 v56; // cl_BYTE *v57; // rdxsigned int v58; // eax__int64 v59; // rdxint v60; // ecxunsigned __int8 v61; // sisigned int v62; // edx__int64 v63; // rcxint v64; // esichar v65; // alsigned int v66; // eaxchar v67; // sisigned int v68; // eaxint v69; // esichar v70; // clchar v71; // cl_BYTE *v72; // rdx__int64 v73; // rcxint v74; // eax__int64 v75; // rax__int64 v76; // rdxchar v77; // cl__int64 v78; // rax__int64 v79; // rdx__int64 v80; // rdx_IO_FILE *v81; // rsiint v82; // eaxchar v83; // al__int64 v84; // rdx__int64 v85; // rcxv1 = *((_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. 2021 SangFor(羊城杯)-Reverse(逆向) Ez_Android Write up

    0x00 日常查壳? 安卓逆向,我用JADX 0x01 值得注意的文件 只有在这里文件里所注册的活动页 才会被手机用户观察 0x02 分析主函数 于是直接分析MainActivity 关于这些R.st ...

  2. [re]符号执行一把梭:2020网鼎杯青龙组re_signal_wp

    [re]符号执行一把梭:2020网鼎杯青龙组re_signal_wp 这道题是2020网鼎杯青龙组的一道逆向提signal,一道虚拟机逆向题目,题目本身不难,可以直接分析也可以符号执行秒掉. 题目分析 ...

  3. 深入理解 Java 虚拟机(第一弹) - Java 内存区域透彻分析

    来自:好好学java 这篇文章主要介绍Java内存区域,也是作为Java虚拟机的一些最基本的知识,理解了这些知识之后,才能更好的进行Jvm调优或者更加深入的学习,本来这些知识是晦涩难懂的,所以希望能够 ...

  4. 深入理解Java虚拟机-Java内存区域透彻分析

    Java虚拟机深入理解系列全部文章更新中- 深入理解Java虚拟机-Java内存区域透彻分析 深入理解Java虚拟机-常用vm参数分析 深入理解Java虚拟机-JVM内存分配与回收策略原理,从此告别J ...

  5. java虚拟机的内存管理

    目录 一.JVM整体架构 二.JVM运行时内存 2.1 PC 程序计数器 2.2 虚拟机栈 2.3 本地方法栈 2.4 堆 2.4.1 Java堆概念 2.4.2 年轻代和老年代 2.4.3 对象分配 ...

  6. Java虚拟机组成部分及作用

    感谢周志明所著的<深入理解Java虚拟机>一书.下面附上了一些我自己的理解. java虚拟机(JVM) 当我们讨论到它的组成部分的时候,有人可能很多都会说是以栈和堆,但是实际上远远不止这两 ...

  7. 安洵杯-game-wp

    game 安洵杯2019逆向 链接:https://pan.baidu.com/s/1vICnEqYfSezXUiTJU6C9TA 提取码:d9m7 题目的文件和idb分析文件和写出的python文件 ...

  8. 站在巨人的肩膀上学习ctf vm

    0x00 前言 本文提到的vm是ctf里的vm,最近vm还是很热门的,最近的虎符,de1ctf,再到网鼎杯都有vm的身影,但是vm的知识在网上挺散的(我只找到了绿盟那篇比较系统),vm的wp也相对比较 ...

  9. 战力爆表|21支明星战队等你围观!

    ​​大浪淘沙始见金,风卷残云剩为王 21支高校明星CTF战队初露王者之相 晋级XCTF高校网络安全专题挑战赛总决赛 2021年10月29日-10月30日东莞·华为松山湖园区 集结再出发,踏上新征途! ...

最新文章

  1. mysql sqlstate 28000_mysql ERROR 1045 (28000): 错误解决办法
  2. 江西教育考试院2021年高考成绩查询入口,2021年江西高考网上志愿填报入口:江西省教育考试院...
  3. linux scp密码参数,使用scp命令安全地传输带有参数的文件
  4. C# 操作List集合报错:集合被修改,枚举操作可能不会执行(Collection was modified, enumeration operation may not execute)
  5. 多线程同步工具——volatile变量
  6. 【路径规划】基于matlab果蝇优化算法机器人路径规划【含Matlab源码 677期】
  7. Java类和对象(重点详解)
  8. python办公自动化——提取pdf中的文字和表格
  9. Android支付宝刷步数,蚂蚁森林刷步数小技巧(一键修改支付宝步数)
  10. python 网站 批量 投票_python requests 简单实现易班自动登录,批量_文章发布,投票发布,评论,点赞,v2.0...
  11. java web play_玩转 Java Web 应用开发:Play 框架
  12. 如何搭建Hadoop分布式环境?我来教你怎么做![内含测试小案例]
  13. 如何用css实现彩带样式,CSS3 彩色丝带
  14. CAN总线通信学习笔记
  15. 【Element-ui】el-table大数据量渲染卡顿问题
  16. vue项目中使用Echarts 动态更改图表数据 , Vue 折线图、柱状图等图表动态刷新 ,
  17. 第12章 项目沟通管理和干系人管理
  18. kubernetes学习(4)---Nginx搭建简单的文件服务器
  19. maven 导出所有依赖jar到指定路径
  20. 他成绩一般,大二却破解世界难题,三院士致信中央,22岁破格成教授

热门文章

  1. java csrf_java使用jsp servlet来防止csrf 攻击的实现方法
  2. Python语言学习:Python常用自带库(imageio、pickle)简介、使用方法之详细攻略
  3. MSSQL 从备份文件还原数据库脚本
  4. react中component存在性能问题
  5. 实验三:xen环境下的第一个虚拟机的安装
  6. python thrift demo
  7. node.js学习笔记
  8. P1586 四方定理
  9. JavaScript常用数组方法
  10. jquery操作iframe