首页
论坛
专栏
课程

[虚拟机保护] 简单的虚拟机伪代码解析

2007-3-13 05:13 14300

[虚拟机保护] 简单的虚拟机伪代码解析

2007-3-13 05:13
14300
【文章标题】: 简单的虚拟机伪代码解析
【文章作者】: BUG
【作者邮箱】: bughoho@hotmail.com
【作者QQ号】: 393277421
【下载地址】: 无
【使用工具】: VC 2003
【操作平台】: XP SP2
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  晚上没事做偷窥了VMProtect一点点代码,结果止不住内心的兴奋,于是写了份关于虚拟机解析的代码(softworm的教程出来的时候没有看懂,于是现在才激动- -!),
  另外我写的仅仅是虚拟机的冰山一角,更多的资料还望大牛们多爆爆料。
  
  向softworm致敬。
  
  感谢LaraCraft
  
  执行虚拟机代码之前都得先声明一个虚拟机环境结构存放数据
  
  //虚拟机环境结构
  struct VMMachine
  {
          DWORD eax;
          DWORD ecx;
          DWORD edx;
          DWORD ebx;
          DWORD* esp;
          DWORD ebp;
          DWORD esi;
          DWORD edi;
          DWORD eip;
          BYTE CF;
          BYTE PF;
          BYTE AF;
          BYTE ZF;
          BYTE SF;
          BYTE OF;
          BYTE DF;
          //********************************
          BYTE p_code;//伪代码
          DWORD lpVMStack[1024*1024*2];//虚拟机堆栈基地址
  };
  
  然后就是关于解析伪代码的JUMP表
  
  //命令JUMP表
  DWORD VMJumpCode[] =
  {
          (DWORD)VReturn,//退出虚拟机
          (DWORD)VNop,   //NOP语句
  
          (DWORD)VPUSHImm,//PUSH操作数
          (DWORD)VPUSHReg,//压入寄存器
          (DWORD)VPUSHMem,//压入内存数
  
          (DWORD)VPOPReg,//弹出到寄存器
          (DWORD)VPOPMem,//弹出到内存
  
          (DWORD)VMovRegReg,//寄存器和寄存器赋值
          (DWORD)VMovRegImm,//寄存器和操作数赋值
          (DWORD)VMovRegMem,//寄存器和内存数赋值
  
          (DWORD)VADDRegReg,//寄存器与寄存器相加
          (DWORD)VADDRegImm,//寄存器与操作数相加
          (DWORD)VADDRegMem,//寄存器与内存数相加
  
          (DWORD)VSUBRegReg,//寄存器与寄存器相减
          (DWORD)VSUBRegImm,//寄存器与操作数相减
          (DWORD)VSUBRegMem,//寄存器与内存数相减
  
          (DWORD)VMulEaxReg,//寄存器与寄存器相乘
  
          (DWORD)VDivEaxReg,//寄存器与寄存器相除
  
          (DWORD)VAndRegReg,//寄存器与寄存器做与操作
          (DWORD)VAndRegImm,//寄存器与操作数做与操作
          (DWORD)VAndRegMem,//寄存器与内存数做与操作
  
          (DWORD)VorRegReg,//寄存器与寄存器做或操作
          (DWORD)VorRegImm,//寄存器与操作数做或操作
          (DWORD)VorRegMem,//寄存器与内存数做或操作
          (DWORD)VJmp      //无条件转移
  };
  
  
  void VMExecuteMachine( DWORD VM_code )
  {
          //初始化标志
          vmmachine.AF = 0;
          vmmachine.ZF = 0;
          vmmachine.SF = 0;
          vmmachine.OF = 0;
          vmmachine.DF = 0;
          //初始化寄存器
          vmmachine.eax = 0;
          vmmachine.ecx = 0;
          vmmachine.edx = 0;
          vmmachine.ebx = 0;
          vmmachine.esp = vmmachine.lpVMStack;
          vmmachine.esi = 0;
          vmmachine.edi = 0;
          vmmachine.eip = VM_code;
          vmmachine.p_code = 0;
          memset( vmmachine.lpVMStack,0,sizeof(vmmachine.lpVMStack) );//初始化堆栈
  
          while(TRUE)
          {
                  vmmachine.p_code = *(BYTE*)vmmachine.eip;//取出伪代码
                  DWORD func = VMJumpCode[vmmachine.p_code];//执行当前语句
                  if( func == (DWORD)VReturn )//不用说了,我知道这里写得很烂
                          return;
                  _asm
                  {
                          call func
                  }
          }
          return;
  }
  void Addcode(BYTE n)//EIP向前走n字节
  {
          //vmmachine.eip += n - 1;
          vmmachine.eip += n;
  }
  //nop;01
  void VNop()//NOP语句
  {
          Addcode(1);
          return;
  }
  //push 2000; 02 00 20 00 00
  void VPUSHImm()//PUSH操作数
  {
          vmmachine.eip++;
          DWORD imm32 = *(DWORD*)vmmachine.eip;
         
          Addcode(4);//跳过这个操作数
         
          vmmachine.esp++;
          *vmmachine.esp = imm32;
  }
  //push ecx; 03 01
  void VPUSHReg()//PUSH寄存器
  {
          vmmachine.eip++;
          BYTE regflag = *(BYTE*)vmmachine.eip;
         
          Addcode(1);//跳过这个操作数
         
          if( regflag < 8 )//除开特殊寄存器EIP
          {
                  DWORD imm32 = ((DWORD*)&vmmachine)[regflag];
                  vmmachine.esp++;//放入堆栈
                  *vmmachine.esp = imm32;
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  //push [401000]; 04 00 10 40 00
  void VPUSHMem()//压入内存中数
  {
          vmmachine.eip++;
          DWORD mem32 = *(DWORD*)vmmachine.eip;
          DWORD imm32 = *(DWORD*)mem32;
         
          Addcode(4);//跳过这个操作数
  
          vmmachine.esp++;//放入堆栈
          *vmmachine.esp = imm32;
  }
  //pop edx; 05 02
  void VPOPReg()//弹出到寄存器
  {
          vmmachine.eip++;
          BYTE regflag = *(BYTE*)vmmachine.eip;
  
          Addcode(1);//跳过这个操作数
  
          if( regflag < 8 )//除开特殊寄存器EIP
          {
                  DWORD imm32 = *vmmachine.esp;
                  vmmachine.esp--;//出栈
                  ((DWORD*)&vmmachine)[regflag] = imm32;//把imm32放到寄存器
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  //pop [401000]; 06 00 10 40 00
  void VPOPMem()//弹出到内存
  {
          DWORD imm32 = *vmmachine.esp;
          vmmachine.esp--;//出栈
  
          DWORD mem32 = *(DWORD*)vmmachine.eip;
  
          Addcode(4);//跳过这个操作数
         
          *(DWORD*)mem32 = imm32;
  }
  //mov eax,ebx; 07 00 03
  void VMovRegReg()//寄存器与寄存器赋值
  {
          vmmachine.eip++;
          BYTE destreg = *(BYTE*)vmmachine.eip;//目的寄存器
          Addcode(1);//跳过这个操作数
          BYTE srcreg = *(BYTE*)vmmachine.eip;//源寄存器
          Addcode(1);//跳过这个操作数
          if( srcreg < 8 && destreg < 8 )
          {
                  ((DWORD*)&vmmachine)[destreg] = ((DWORD*)&vmmachine)[srcreg];//赋值
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  //mov ecx,401000; 08 01 00 10 40 00
  void VMovRegImm()//寄存器和操作数赋值
  {
          vmmachine.eip++;
          BYTE destreg = *(BYTE*)vmmachine.eip;//目的寄存器
          Addcode(1);//跳过这个操作数
          DWORD Imm32 = *(DWORD*)vmmachine.eip;//操作数
          Addcode(4);//跳过这个操作数
          if( destreg < 8 )
          {
                  ((DWORD*)&vmmachine)[destreg] = Imm32;//赋值
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  //mov ecx,[401000]; 09 01 00 10 40 00
  void VMovRegMem()//寄存器和内存数赋值
  {
          vmmachine.eip++;
          BYTE destreg = *(BYTE*)vmmachine.eip;//目的寄存器
          Addcode(1);//跳过这个操作数
          DWORD Mem32 = *(DWORD*)vmmachine.eip;//内存数
          DWORD Imm32 = *(DWORD*)Mem32;
          Addcode(4);//跳过这个操作数
          if( destreg < 8 )
          {
                  ((DWORD*)&vmmachine)[destreg] = Imm32;//赋值
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  //add eax,ebx; 0A 00 03
  void VADDRegReg()//寄存器与寄存器相加
  {
          vmmachine.eip++;
          BYTE destreg = *(BYTE*)vmmachine.eip;//目的寄存器
          Addcode(1);//跳过这个操作数
          BYTE srcreg = *(BYTE*)vmmachine.eip;//源寄存器
          Addcode(1);//跳过这个操作数
          if( srcreg < 8 && destreg < 8 )
          {
                  ((DWORD*)&vmmachine)[destreg] += ((DWORD*)&vmmachine)[srcreg];//相加
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  //add eax,1234; 0B 00 34 12 00 00
  void VADDRegImm()//寄存器与操作数相加
  {
          vmmachine.eip++;
          BYTE destreg = *(BYTE*)vmmachine.eip;//目的寄存器
          Addcode(1);//跳过这个操作数
          DWORD Imm32 = *(DWORD*)vmmachine.eip;//操作数
          Addcode(4);//跳过这个操作数
          if( destreg < 8 )
          {
                  ((DWORD*)&vmmachine)[destreg] += Imm32;//赋值
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  //add eax,[401000]; 0C 00 00 10 40 00
  void VADDRegMem()//寄存器与内存数相加
  {
          vmmachine.eip++;
          BYTE destreg = *(BYTE*)vmmachine.eip;//目的寄存器
          Addcode(1);//跳过这个操作数
          DWORD Mem32 = *(DWORD*)vmmachine.eip;//内存数
          DWORD Imm32 = *(DWORD*)Mem32;
          Addcode(4);//跳过这个操作数
          if( destreg < 8 )
          {
                  ((DWORD*)&vmmachine)[destreg] += Imm32;//赋值
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  //sub eax,ebx; 0D 00 03
  void VSUBRegReg()//寄存器与寄存器相减
  {
          vmmachine.eip++;
          BYTE destreg = *(BYTE*)vmmachine.eip;//目的寄存器
          Addcode(1);//跳过这个操作数
          BYTE srcreg = *(BYTE*)vmmachine.eip;//源寄存器
          Addcode(1);//跳过这个操作数
          if( srcreg < 8 && destreg < 8 )
          {
                  ((DWORD*)&vmmachine)[destreg] -= ((DWORD*)&vmmachine)[srcreg];//相加
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  //sub eax,1234; 0E 00 34 12 00 00
  void VSUBRegImm()//寄存器与操作数相减
  {
          vmmachine.eip++;
          BYTE destreg = *(BYTE*)vmmachine.eip;//目的寄存器
          Addcode(1);//跳过这个操作数
          DWORD Imm32 = *(DWORD*)vmmachine.eip;//操作数
          Addcode(4);//跳过这个操作数
          if( destreg < 8 )
          {
                  ((DWORD*)&vmmachine)[destreg] -= Imm32;//赋值
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  //sub eax,[401000]; 0F 00 00 10 40 00
  void VSUBRegMem()//寄存器与内存数相减
  {
          vmmachine.eip++;
          BYTE destreg = *(BYTE*)vmmachine.eip;//目的寄存器
          Addcode(1);//跳过这个操作数
          DWORD Mem32 = *(DWORD*)vmmachine.eip;//内存数
          DWORD Imm32 = *(DWORD*)Mem32;
          Addcode(4);//跳过这个操作数
          if( destreg < 8 )
          {
                  ((DWORD*)&vmmachine)[destreg] -= Imm32;//赋值
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  
  //mul ebx; 10 03
  void VMulEaxReg()//EAX与寄存器相乘
  {
          vmmachine.eip++;
          BYTE srcreg = *(BYTE*)vmmachine.eip;//源寄存器
          Addcode(1);//跳过这个操作数
          if( srcreg < 8 )
          {
                  vmmachine.eax *= ((DWORD*)&vmmachine)[srcreg];//相乘
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  
  //div ebx; 11 03
  void VDivEaxReg()//寄存器与寄存器相除
  {
          vmmachine.eip++;
          BYTE srcreg = *(BYTE*)vmmachine.eip;//源寄存器
          Addcode(1);//跳过这个操作数
          if( srcreg < 8 )
          {
                  vmmachine.eax /= ((DWORD*)&vmmachine)[srcreg];//相除
                  vmmachine.edx = vmmachine.eax % ((DWORD*)&vmmachine)[srcreg];//余数..
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  //and eax,ecx; 12 00 01
  void VAndRegReg()//寄存器与寄存器做与操作
  {
          vmmachine.eip++;
          BYTE destreg = *(BYTE*)vmmachine.eip;//目的寄存器
          Addcode(1);//跳过这个操作数
          BYTE srcreg = *(BYTE*)vmmachine.eip;//源寄存器
          Addcode(1);//跳过这个操作数
          if( srcreg < 8 && destreg < 8 )
          {
                  ((DWORD*)&vmmachine)[destreg] &= ((DWORD*)&vmmachine)[srcreg];//and
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  //and eax,1234; 13 00 34 12
  void VAndRegImm()//寄存器与操作数做与操作
  {
          vmmachine.eip++;
          BYTE destreg = *(BYTE*)vmmachine.eip;//目的寄存器
          Addcode(1);//跳过这个操作数
          DWORD Imm32 = *(DWORD*)vmmachine.eip;//操作数
          Addcode(4);//跳过这个操作数
          if( destreg < 8 )
          {
                  ((DWORD*)&vmmachine)[destreg] &= Imm32;//赋值
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  //and eax,[401000]; 14 00 00 10 40 00
  void VAndRegMem()//寄存器与内存数做与操作
  {
          vmmachine.eip++;
          BYTE destreg = *(BYTE*)vmmachine.eip;//目的寄存器
          Addcode(1);//跳过这个操作数
          DWORD Mem32 = *(DWORD*)vmmachine.eip;//内存数
          DWORD Imm32 = *(DWORD*)Mem32;
          Addcode(4);//跳过这个操作数
          if( destreg < 8 )
          {
                  ((DWORD*)&vmmachine)[destreg] &= Imm32;//赋值
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  
  //or eax,ecx; 15 00 01
  void VorRegReg()//寄存器与寄存器做或操作
  {
          vmmachine.eip++;
          BYTE destreg = *(BYTE*)vmmachine.eip;//目的寄存器
          Addcode(1);//跳过这个操作数
          BYTE srcreg = *(BYTE*)vmmachine.eip;//源寄存器
          Addcode(1);//跳过这个操作数
          if( srcreg < 8 && destreg < 8 )
          {
                  ((DWORD*)&vmmachine)[destreg] |= ((DWORD*)&vmmachine)[srcreg];//or
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  //or eax,1234; 16 00 34 12
  void VorRegImm()//寄存器与操作数做或操作
  {
          vmmachine.eip++;
          BYTE destreg = *(BYTE*)vmmachine.eip;//目的寄存器
          Addcode(1);//跳过这个操作数
          DWORD Imm32 = *(DWORD*)vmmachine.eip;//操作数
          Addcode(4);//跳过这个操作数
          if( destreg < 8 )
          {
                  ((DWORD*)&vmmachine)[destreg] |= Imm32;//赋值
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  //or eax,[401000]; 17 00 00 10 40 00
  void VorRegMem()//寄存器与内存数做或操作
  {
          vmmachine.eip++;
          BYTE destreg = *(BYTE*)vmmachine.eip;//目的寄存器
          Addcode(1);//跳过这个操作数
          DWORD Imm32 = *(DWORD*)vmmachine.eip;//操作数
          Addcode(4);//跳过这个操作数
          if( destreg < 8 )
          {
                  ((DWORD*)&vmmachine)[destreg] |= Imm32;//赋值
          }
          else
          {
                  MessageBox(0,"超出已知寄存器或未认可寄存器","VM",MB_OK);
          }
  }
  
  //jmp 00401000; 18 00 10 40 00
  void VJmp()//无条件跳转
  {
          vmmachine.eip++;
          DWORD imm32 = *(DWORD*)vmmachine.eip;
  
          vmmachine.eip = imm32;//EIP指向这个地址
  }
  void VReturn()//退出虚拟机.只是一个标记而已
  {
  }
  
  BYTE vm_code[32] =
  {
          0x02,0x00,0x20,0x00,0x00,      //push 2000
          0x03,0x00,                     //push eax
          0x0B,0x00,0x34,0x12,0x00,0x00,  //add eax,1234
          0x0E,0x00,0x10,0x00,0x00,0x00,  //sub eax,10
          0x00                           //exit
  };
  
  int _tmain(int argc, _TCHAR* argv[])
  {
          VMExecuteMachine((DWORD)vm_code);
          return 0;
  }
  
  这一晚上就写了这么多,基本上都是对寄存器和堆栈的操作,还未对标志寄存器做任何操作..不然可以连条件语句也加上去.
  
  另外代码因为我赶着睡觉于是我草草的测试了一遍没问题就发上来了,如有失误还请包涵.
  
--------------------------------------------------------------------------------
【经验总结】
  今晚上算有点收获,对VM有了点认识.
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2007年03月13日 5:06:55

[公告][征集寄语] 看雪20周年年会(12.28上海) | 感恩有你,一路同行

上传的附件:
最新回复 (20)
KuNgBiM 66 2007-3-13 05:56
2
0
sustian

VM 时代到来
girl 1 2007-3-13 08:04
3
0
强人
海风月影 17 2007-3-13 08:51
4
0
vm时代到了
支持一下,应该说只写了一半,还有一半是如何把汇编代码转成vm_code
skylly 4 2007-3-13 09:13
5
0
崇拜,瞻仰中...........

PS:太笨,我不会用
aki 2 2007-3-13 09:34
6
0
代理死神出马
linestyle 2007-3-13 10:00
7
0
softworm一样的好教育家
zhucheba 2007-3-13 10:15
8
0
好文章,很受启发
cyclotron 17 2007-3-13 10:25
9
0
支持vm,写得非常清楚
girl 1 2007-3-13 10:28
10
0
就一张表嘛,指令一一对应,就是没人去动
我是雷锋 2007-3-13 11:45
11
0
努力学习~~~
xzchina 1 2007-3-13 12:02
12
0
冒昧的问一下楼主,如果虚拟机里面还有一个虚拟机,层层相扣,有这种可能嘛?
笨笨雄 14 2007-3-13 12:49
13
0
效率问题

我就说SOFTWORM那文章更象是教人做虚拟机的
Bughoho 8 2007-3-13 12:54
14
0
恩,当然没法和softworm比啦.
云重 1 2007-3-13 13:19
15
0
缺少很多东西.
云重 1 2007-3-13 13:20
16
0
不过还是赞一个
softworm 30 2007-3-13 19:00
17
0
有志者事竞成
Isaiah 10 2007-3-13 19:37
18
0
最初由 xzchina 发布
冒昧的问一下楼主,如果虚拟机里面还有一个虚拟机,层层相扣,有这种可能嘛?


帮答一下:不是可能,是已经有了.

你可以去CrackMes.De去看看
夜凉如水 3 2007-3-13 20:09
19
0
too sustian !!!!
elance 6 2007-3-14 22:26
20
0
呵呵,值得期待的vm时代!!!
qiweixue 19 2007-3-15 12:48
21
0
呵呵.
支持
偶还系壳盲..
貌似shooo也逆出好多疙瘩滴VMP code来...
游客
登录 | 注册 方可回帖
返回