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

📄 rarvm.cpp

📁 我把unrar的代码整理成vc工程了
💻 CPP
📖 第 1 页 / 共 3 页
字号:
  }}void RarVM::SetMemory(unsigned int Pos,byte *Data,unsigned int DataSize){  if (Pos<VM_MEMSIZE && Data!=Mem+Pos)    memmove(Mem+Pos,Data,Min(DataSize,VM_MEMSIZE-Pos));}#ifdef VM_OPTIMIZEvoid RarVM::Optimize(VM_PreparedProgram *Prg){  VM_PreparedCommand *Code=&Prg->Cmd[0];  int CodeSize=Prg->CmdCount;  for (int I=0;I<CodeSize;I++)  {    VM_PreparedCommand *Cmd=Code+I;    // Replace universal opcodes with faster byte or word only processing    // opcodes.    switch(Cmd->OpCode)    {      case VM_MOV:        Cmd->OpCode=Cmd->ByteMode ? VM_MOVB:VM_MOVD;        continue;      case VM_CMP:        Cmd->OpCode=Cmd->ByteMode ? VM_CMPB:VM_CMPD;        continue;    }    if ((VM_CmdFlags[Cmd->OpCode] & VMCF_CHFLAGS)==0)      continue;    // If we do not have jump commands between the current operation    // and next command which will modify processor flags, we can replace    // the current command with faster version which does not need to    // modify flags.    bool FlagsRequired=false;    for (int J=I+1;J<CodeSize;J++)    {      int Flags=VM_CmdFlags[Code[J].OpCode];      if (Flags & (VMCF_JUMP|VMCF_PROC|VMCF_USEFLAGS))      {        FlagsRequired=true;        break;      }      if (Flags & VMCF_CHFLAGS)        break;    }    // Below we'll replace universal opcodes with faster byte or word only     // processing opcodes, which also do not modify processor flags to    // provide better performance.    if (FlagsRequired)      continue;    switch(Cmd->OpCode)    {      case VM_ADD:        Cmd->OpCode=Cmd->ByteMode ? VM_ADDB:VM_ADDD;        continue;      case VM_SUB:        Cmd->OpCode=Cmd->ByteMode ? VM_SUBB:VM_SUBD;        continue;      case VM_INC:        Cmd->OpCode=Cmd->ByteMode ? VM_INCB:VM_INCD;        continue;      case VM_DEC:        Cmd->OpCode=Cmd->ByteMode ? VM_DECB:VM_DECD;        continue;      case VM_NEG:        Cmd->OpCode=Cmd->ByteMode ? VM_NEGB:VM_NEGD;        continue;    }  }}#endif#ifdef VM_STANDARDFILTERSVM_StandardFilters RarVM::IsStandardFilter(byte *Code,int CodeSize){  struct StandardFilterSignature  {    int Length;    uint CRC;    VM_StandardFilters Type;  } static StdList[]={    53, 0xad576887, VMSF_E8,    57, 0x3cd7e57e, VMSF_E8E9,   120, 0x3769893f, VMSF_ITANIUM,    29, 0x0e06077d, VMSF_DELTA,   149, 0x1c2c5dc8, VMSF_RGB,   216, 0xbc85e701, VMSF_AUDIO,    40, 0x46b9c560, VMSF_UPCASE  };  uint CodeCRC=CRC(0xffffffff,Code,CodeSize)^0xffffffff;  for (int I=0;I<sizeof(StdList)/sizeof(StdList[0]);I++)    if (StdList[I].CRC==CodeCRC && StdList[I].Length==CodeSize)      return(StdList[I].Type);  return(VMSF_NONE);}void RarVM::ExecuteStandardFilter(VM_StandardFilters FilterType){  switch(FilterType)  {    case VMSF_E8:    case VMSF_E8E9:      {        byte *Data=Mem;        int DataSize=R[4];        uint FileOffset=R[6];        if (DataSize>=VM_GLOBALMEMADDR || DataSize<4)          break;        const int FileSize=0x1000000;        byte CmpByte2=FilterType==VMSF_E8E9 ? 0xe9:0xe8;        for (int CurPos=0;CurPos<DataSize-4;)        {          byte CurByte=*(Data++);          CurPos++;          if (CurByte==0xe8 || CurByte==CmpByte2)          {#ifdef PRESENT_INT32            sint32 Offset=CurPos+FileOffset;            sint32 Addr=GET_VALUE(false,Data);            if (Addr<0)            {              if (Addr+Offset>=0)                SET_VALUE(false,Data,Addr+FileSize);            }            else              if (Addr<FileSize)                SET_VALUE(false,Data,Addr-Offset);#else            long Offset=CurPos+FileOffset;            long Addr=GET_VALUE(false,Data);            if ((Addr & 0x80000000)!=0)            {              if (((Addr+Offset) & 0x80000000)==0)                SET_VALUE(false,Data,Addr+FileSize);            }            else               if (((Addr-FileSize) & 0x80000000)!=0)                SET_VALUE(false,Data,Addr-Offset);#endif            Data+=4;            CurPos+=4;          }        }      }      break;    case VMSF_ITANIUM:      {        byte *Data=Mem;        int DataSize=R[4];        uint FileOffset=R[6];        if (DataSize>=VM_GLOBALMEMADDR || DataSize<21)          break;        int CurPos=0;        FileOffset>>=4;        while (CurPos<DataSize-21)        {          int Byte=(Data[0]&0x1f)-0x10;          if (Byte>=0)          {            static byte Masks[16]={4,4,6,6,0,0,7,7,4,4,0,0,4,4,0,0};            byte CmdMask=Masks[Byte];            if (CmdMask!=0)              for (int I=0;I<=2;I++)                if (CmdMask & (1<<I))                {                  int StartPos=I*41+5;                  int OpType=FilterItanium_GetBits(Data,StartPos+37,4);                  if (OpType==5)                  {                    int Offset=FilterItanium_GetBits(Data,StartPos+13,20);                    FilterItanium_SetBits(Data,(Offset-FileOffset)&0xfffff,StartPos+13,20);                  }                }          }          Data+=16;          CurPos+=16;          FileOffset++;        }      }      break;    case VMSF_DELTA:      {        int DataSize=R[4],Channels=R[0],SrcPos=0,Border=DataSize*2;        SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize);        if (DataSize>=VM_GLOBALMEMADDR/2)          break;        // Bytes from same channels are grouped to continual data blocks,        // so we need to place them back to their interleaving positions.        for (int CurChannel=0;CurChannel<Channels;CurChannel++)        {          byte PrevByte=0;          for (int DestPos=DataSize+CurChannel;DestPos<Border;DestPos+=Channels)            Mem[DestPos]=(PrevByte-=Mem[SrcPos++]);        }      }      break;    case VMSF_RGB:      {        int DataSize=R[4],Width=R[0]-3,PosR=R[1];        byte *SrcData=Mem,*DestData=SrcData+DataSize;        const int Channels=3;        SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize);        if (DataSize>=VM_GLOBALMEMADDR/2 || PosR<0)          break;        for (int CurChannel=0;CurChannel<Channels;CurChannel++)        {          unsigned int PrevByte=0;          for (int I=CurChannel;I<DataSize;I+=Channels)          {            unsigned int Predicted;            int UpperPos=I-Width;            if (UpperPos>=3)            {              byte *UpperData=DestData+UpperPos;              unsigned int UpperByte=*UpperData;              unsigned int UpperLeftByte=*(UpperData-3);              Predicted=PrevByte+UpperByte-UpperLeftByte;              int pa=abs((int)(Predicted-PrevByte));              int pb=abs((int)(Predicted-UpperByte));              int pc=abs((int)(Predicted-UpperLeftByte));              if (pa<=pb && pa<=pc)                Predicted=PrevByte;              else                if (pb<=pc)                  Predicted=UpperByte;                else                  Predicted=UpperLeftByte;            }            else              Predicted=PrevByte;            DestData[I]=PrevByte=(byte)(Predicted-*(SrcData++));          }        }        for (int I=PosR,Border=DataSize-2;I<Border;I+=3)        {          byte G=DestData[I+1];          DestData[I]+=G;          DestData[I+2]+=G;        }      }      break;    case VMSF_AUDIO:      {        int DataSize=R[4],Channels=R[0];        byte *SrcData=Mem,*DestData=SrcData+DataSize;        SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize);        if (DataSize>=VM_GLOBALMEMADDR/2)          break;        for (int CurChannel=0;CurChannel<Channels;CurChannel++)        {          unsigned int PrevByte=0,PrevDelta=0,Dif[7];          int D1=0,D2=0,D3;          int K1=0,K2=0,K3=0;          memset(Dif,0,sizeof(Dif));          for (int I=CurChannel,ByteCount=0;I<DataSize;I+=Channels,ByteCount++)          {            D3=D2;            D2=PrevDelta-D1;            D1=PrevDelta;            unsigned int Predicted=8*PrevByte+K1*D1+K2*D2+K3*D3;            Predicted=(Predicted>>3) & 0xff;            unsigned int CurByte=*(SrcData++);            Predicted-=CurByte;            DestData[I]=Predicted;            PrevDelta=(signed char)(Predicted-PrevByte);            PrevByte=Predicted;            int D=((signed char)CurByte)<<3;            Dif[0]+=abs(D);            Dif[1]+=abs(D-D1);            Dif[2]+=abs(D+D1);            Dif[3]+=abs(D-D2);            Dif[4]+=abs(D+D2);            Dif[5]+=abs(D-D3);            Dif[6]+=abs(D+D3);            if ((ByteCount & 0x1f)==0)            {              unsigned int MinDif=Dif[0],NumMinDif=0;              Dif[0]=0;              for (int J=1;J<sizeof(Dif)/sizeof(Dif[0]);J++)              {                if (Dif[J]<MinDif)                {                  MinDif=Dif[J];                  NumMinDif=J;                }                Dif[J]=0;              }              switch(NumMinDif)              {                case 1: if (K1>=-16) K1--; break;                case 2: if (K1 < 16) K1++; break;                case 3: if (K2>=-16) K2--; break;                case 4: if (K2 < 16) K2++; break;                case 5: if (K3>=-16) K3--; break;                case 6: if (K3 < 16) K3++; break;              }            }          }        }      }      break;    case VMSF_UPCASE:      {        int DataSize=R[4],SrcPos=0,DestPos=DataSize;        if (DataSize>=VM_GLOBALMEMADDR/2)          break;        while (SrcPos<DataSize)        {          byte CurByte=Mem[SrcPos++];          if (CurByte==2 && (CurByte=Mem[SrcPos++])!=2)            CurByte-=32;          Mem[DestPos++]=CurByte;        }        SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x1c],DestPos-DataSize);        SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize);      }      break;  }}unsigned int RarVM::FilterItanium_GetBits(byte *Data,int BitPos,int BitCount){  int InAddr=BitPos/8;  int InBit=BitPos&7;  unsigned int BitField=(uint)Data[InAddr++];  BitField|=(uint)Data[InAddr++] << 8;  BitField|=(uint)Data[InAddr++] << 16;  BitField|=(uint)Data[InAddr] << 24;  BitField >>= InBit;  return(BitField & (0xffffffff>>(32-BitCount)));}void RarVM::FilterItanium_SetBits(byte *Data,unsigned int BitField,int BitPos,                                  int BitCount){  int InAddr=BitPos/8;  int InBit=BitPos&7;  unsigned int AndMask=0xffffffff>>(32-BitCount);  AndMask=~(AndMask<<InBit);  BitField<<=InBit;  for (int I=0;I<4;I++)  {    Data[InAddr+I]&=AndMask;    Data[InAddr+I]|=BitField;    AndMask=(AndMask>>8)|0xff000000;    BitField>>=8;  }}#endif

⌨️ 快捷键说明

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