⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rarvm.cpp

📁 我把unrar的代码整理成vc工程了
💻 CPP
📖 第 1 页 / 共 3 页
字号:
      case VM_PUSH:        R[7]-=4;        SET_VALUE(false,(uint *)&Mem[R[7]&VM_MEMMASK],GET_VALUE(false,Op1));        break;      case VM_POP:        SET_VALUE(false,Op1,GET_VALUE(false,(uint *)&Mem[R[7] & VM_MEMMASK]));        R[7]+=4;        break;      case VM_CALL:        R[7]-=4;        SET_VALUE(false,(uint *)&Mem[R[7]&VM_MEMMASK],Cmd-PreparedCode+1);        SET_IP(GET_VALUE(false,Op1));        continue;      case VM_NOT:        SET_VALUE(Cmd->ByteMode,Op1,~GET_VALUE(Cmd->ByteMode,Op1));        break;      case VM_SHL:        {          uint Value1=GET_VALUE(Cmd->ByteMode,Op1);          uint Value2=GET_VALUE(Cmd->ByteMode,Op2);          uint Result=UINT32(Value1<<Value2);          Flags=(Result==0 ? VM_FZ:(Result&VM_FS))|((Value1<<(Value2-1))&0x80000000 ? VM_FC:0);          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;      case VM_SHR:        {          uint Value1=GET_VALUE(Cmd->ByteMode,Op1);          uint Value2=GET_VALUE(Cmd->ByteMode,Op2);          uint Result=UINT32(Value1>>Value2);          Flags=(Result==0 ? VM_FZ:(Result&VM_FS))|((Value1>>(Value2-1))&VM_FC);          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;      case VM_SAR:        {          uint Value1=GET_VALUE(Cmd->ByteMode,Op1);          uint Value2=GET_VALUE(Cmd->ByteMode,Op2);          uint Result=UINT32(((int)Value1)>>Value2);          Flags=(Result==0 ? VM_FZ:(Result&VM_FS))|((Value1>>(Value2-1))&VM_FC);          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;      case VM_NEG:        {          uint Result=UINT32(-GET_VALUE(Cmd->ByteMode,Op1));          Flags=Result==0 ? VM_FZ:VM_FC|(Result&VM_FS);          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;#ifdef VM_OPTIMIZE      case VM_NEGB:        SET_VALUE(true,Op1,-GET_VALUE(true,Op1));        break;      case VM_NEGD:        SET_VALUE(false,Op1,-GET_VALUE(false,Op1));        break;#endif      case VM_PUSHA:        {          const int RegCount=sizeof(R)/sizeof(R[0]);          for (int I=0,SP=R[7]-4;I<RegCount;I++,SP-=4)            SET_VALUE(false,(uint *)&Mem[SP & VM_MEMMASK],R[I]);          R[7]-=RegCount*4;        }        break;      case VM_POPA:        {          const int RegCount=sizeof(R)/sizeof(R[0]);          for (uint I=0,SP=R[7];I<RegCount;I++,SP+=4)            R[7-I]=GET_VALUE(false,(uint *)&Mem[SP & VM_MEMMASK]);        }        break;      case VM_PUSHF:        R[7]-=4;        SET_VALUE(false,(uint *)&Mem[R[7]&VM_MEMMASK],Flags);        break;      case VM_POPF:        Flags=GET_VALUE(false,(uint *)&Mem[R[7] & VM_MEMMASK]);        R[7]+=4;        break;      case VM_MOVZX:        SET_VALUE(false,Op1,GET_VALUE(true,Op2));        break;      case VM_MOVSX:        SET_VALUE(false,Op1,(signed char)GET_VALUE(true,Op2));        break;      case VM_XCHG:        {          uint Value1=GET_VALUE(Cmd->ByteMode,Op1);          SET_VALUE(Cmd->ByteMode,Op1,GET_VALUE(Cmd->ByteMode,Op2));          SET_VALUE(Cmd->ByteMode,Op2,Value1);        }        break;      case VM_MUL:        {          uint Result=GET_VALUE(Cmd->ByteMode,Op1)*GET_VALUE(Cmd->ByteMode,Op2);          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;      case VM_DIV:        {          uint Divider=GET_VALUE(Cmd->ByteMode,Op2);          if (Divider!=0)          {            uint Result=GET_VALUE(Cmd->ByteMode,Op1)/Divider;            SET_VALUE(Cmd->ByteMode,Op1,Result);          }        }        break;      case VM_ADC:        {          uint Value1=GET_VALUE(Cmd->ByteMode,Op1);          uint FC=(Flags&VM_FC);          uint Result=UINT32(Value1+GET_VALUE(Cmd->ByteMode,Op2)+FC);          if (Cmd->ByteMode)            Result&=0xff;          Flags=(Result<Value1 || Result==Value1 && FC)|(Result==0 ? VM_FZ:(Result&VM_FS));          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;      case VM_SBB:        {          uint Value1=GET_VALUE(Cmd->ByteMode,Op1);          uint FC=(Flags&VM_FC);          uint Result=UINT32(Value1-GET_VALUE(Cmd->ByteMode,Op2)-FC);          if (Cmd->ByteMode)            Result&=0xff;          Flags=(Result>Value1 || Result==Value1 && FC)|(Result==0 ? VM_FZ:(Result&VM_FS));          SET_VALUE(Cmd->ByteMode,Op1,Result);        }        break;#endif  // for #ifndef NORARVM      case VM_RET:        if (R[7]>=VM_MEMSIZE)          return(true);        SET_IP(GET_VALUE(false,(uint *)&Mem[R[7] & VM_MEMMASK]));        R[7]+=4;        continue;#ifdef VM_STANDARDFILTERS      case VM_STANDARD:        ExecuteStandardFilter((VM_StandardFilters)Cmd->Op1.Data);        break;#endif      case VM_PRINT:        break;    }    Cmd++;    --MaxOpCount;  }}void RarVM::Prepare(byte *Code,int CodeSize,VM_PreparedProgram *Prg){  InitBitInput();  memcpy(InBuf,Code,Min(CodeSize,BitInput::MAX_SIZE));  // Calculate the single byte XOR checksum to check validity of VM code.  byte XorSum=0;  for (int I=1;I<CodeSize;I++)    XorSum^=Code[I];  faddbits(8);  Prg->CmdCount=0;  if (XorSum==Code[0]) // VM code is valid if equal.  {#ifdef VM_STANDARDFILTERS    VM_StandardFilters FilterType=IsStandardFilter(Code,CodeSize);    if (FilterType!=VMSF_NONE)    {      // VM code is found among standard filters.      Prg->Cmd.Add(1);      VM_PreparedCommand *CurCmd=&Prg->Cmd[Prg->CmdCount++];      CurCmd->OpCode=VM_STANDARD;      CurCmd->Op1.Data=FilterType;      CurCmd->Op1.Addr=&CurCmd->Op1.Data;      CurCmd->Op2.Addr=&CurCmd->Op2.Data;      CurCmd->Op1.Type=CurCmd->Op2.Type=VM_OPNONE;      CodeSize=0;    }#endif      uint DataFlag=fgetbits();    faddbits(1);    // Read static data contained in DB operators. This data cannot be    // changed, it is a part of VM code, not a filter parameter.    if (DataFlag&0x8000)    {      int DataSize=ReadData(*this)+1;      for (int I=0;InAddr<CodeSize && I<DataSize;I++)      {        Prg->StaticData.Add(1);        Prg->StaticData[I]=fgetbits()>>8;        faddbits(8);      }    }    while (InAddr<CodeSize)    {      Prg->Cmd.Add(1);      VM_PreparedCommand *CurCmd=&Prg->Cmd[Prg->CmdCount];      uint Data=fgetbits();      if ((Data&0x8000)==0)      {        CurCmd->OpCode=(VM_Commands)(Data>>12);        faddbits(4);      }      else      {        CurCmd->OpCode=(VM_Commands)((Data>>10)-24);        faddbits(6);      }      if (VM_CmdFlags[CurCmd->OpCode] & VMCF_BYTEMODE)      {        CurCmd->ByteMode=fgetbits()>>15;        faddbits(1);      }      else        CurCmd->ByteMode=0;      CurCmd->Op1.Type=CurCmd->Op2.Type=VM_OPNONE;      int OpNum=(VM_CmdFlags[CurCmd->OpCode] & VMCF_OPMASK);      CurCmd->Op1.Addr=CurCmd->Op2.Addr=NULL;      if (OpNum>0)      {        DecodeArg(CurCmd->Op1,CurCmd->ByteMode); // reading the first operand        if (OpNum==2)          DecodeArg(CurCmd->Op2,CurCmd->ByteMode); // reading the second operand        else        {          if (CurCmd->Op1.Type==VM_OPINT && (VM_CmdFlags[CurCmd->OpCode]&(VMCF_JUMP|VMCF_PROC)))          {            // Calculating jump distance.            int Distance=CurCmd->Op1.Data;            if (Distance>=256)              Distance-=256;            else            {              if (Distance>=136)                Distance-=264;              else                if (Distance>=16)                  Distance-=8;                else                  if (Distance>=8)                    Distance-=16;              Distance+=Prg->CmdCount;            }            CurCmd->Op1.Data=Distance;          }        }      }      Prg->CmdCount++;    }  }  // Adding RET command at the end of program.  Prg->Cmd.Add(1);  VM_PreparedCommand *CurCmd=&Prg->Cmd[Prg->CmdCount++];  CurCmd->OpCode=VM_RET;  CurCmd->Op1.Addr=&CurCmd->Op1.Data;  CurCmd->Op2.Addr=&CurCmd->Op2.Data;  CurCmd->Op1.Type=CurCmd->Op2.Type=VM_OPNONE;  // If operand 'Addr' field has not been set by DecodeArg calls above,  // let's set it to point to operand 'Data' field. It is necessary for  // VM_OPINT type operands (usual integers) or maybe if something was   // not set properly for other operands. 'Addr' field is required  // for quicker addressing of operand data.  for (int I=0;I<Prg->CmdCount;I++)  {    VM_PreparedCommand *Cmd=&Prg->Cmd[I];    if (Cmd->Op1.Addr==NULL)      Cmd->Op1.Addr=&Cmd->Op1.Data;    if (Cmd->Op2.Addr==NULL)      Cmd->Op2.Addr=&Cmd->Op2.Data;  }#ifdef VM_OPTIMIZE  if (CodeSize!=0)    Optimize(Prg);#endif}void RarVM::DecodeArg(VM_PreparedOperand &Op,bool ByteMode){  uint Data=fgetbits();  if (Data & 0x8000)  {    Op.Type=VM_OPREG;     // Operand is register (R[0]..R[7])    Op.Data=(Data>>12)&7; // Register number    Op.Addr=&R[Op.Data];  // Register address    faddbits(4);          // 1 flag bit and 3 register number bits   }  else    if ((Data & 0xc000)==0)    {      Op.Type=VM_OPINT;   // Operand is integer      if (ByteMode)      {        Op.Data=(Data>>6) & 0xff;  // Byte integer.        faddbits(10);      }      else      {        faddbits(2);        Op.Data=ReadData(*this);   // 32 bit integer.      }    }    else    {      // Operand is data addressed by register data, base address or both.      Op.Type=VM_OPREGMEM;      if ((Data & 0x2000)==0)      {        // Base address is zero, just use the address from register.        Op.Data=(Data>>10)&7;        Op.Addr=&R[Op.Data];        Op.Base=0;        faddbits(6);      }      else      {        if ((Data & 0x1000)==0)        {          // Use both register and base address.          Op.Data=(Data>>9)&7;          Op.Addr=&R[Op.Data];          faddbits(7);        }        else        {          // Use base address only. Access memory by fixed address.          Op.Data=0;          faddbits(4);        }        Op.Base=ReadData(*this); // Read base address.      }    }}uint RarVM::ReadData(BitInput &Inp){  uint Data=Inp.fgetbits();  switch(Data&0xc000)  {    case 0:      Inp.faddbits(6);      return((Data>>10)&0xf);    case 0x4000:      if ((Data&0x3c00)==0)      {        Data=0xffffff00|((Data>>2)&0xff);        Inp.faddbits(14);      }      else      {        Data=(Data>>6)&0xff;        Inp.faddbits(10);      }      return(Data);    case 0x8000:      Inp.faddbits(2);      Data=Inp.fgetbits();      Inp.faddbits(16);      return(Data);    default:      Inp.faddbits(2);      Data=(Inp.fgetbits()<<16);      Inp.faddbits(16);      Data|=Inp.fgetbits();      Inp.faddbits(16);      return(Data);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -