📄 rarvm.cpp
字号:
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); if (OpNum==2) DecodeArg(CurCmd->Op2,CurCmd->ByteMode); else { if (CurCmd->Op1.Type==VM_OPINT && (VM_CmdFlags[CurCmd->OpCode]&(VMCF_JUMP|VMCF_PROC))) { 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++; } } 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; 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; Op.Data=(Data>>12)&7; Op.Addr=&R[Op.Data]; faddbits(4); } else if ((Data & 0xc000)==0) { Op.Type=VM_OPINT; if (ByteMode) { Op.Data=(Data>>6) & 0xff; faddbits(10); } else { faddbits(2); Op.Data=ReadData(*this); } } else { Op.Type=VM_OPREGMEM; if ((Data & 0x2000)==0) { Op.Data=(Data>>10)&7; Op.Addr=&R[Op.Data]; Op.Base=0; faddbits(6); } else { if ((Data & 0x1000)==0) { Op.Data=(Data>>9)&7; Op.Addr=&R[Op.Data]; faddbits(7); } else { Op.Data=0; faddbits(4); } Op.Base=ReadData(*this); } }}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); }}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; 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; 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; } 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; } 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) break; const int FileSize=0x1000000; byte CmpByte2=FilterType==VMSF_E8E9 ? 0xe9:0xe8; for (uint 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) break; uint 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; 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) 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 + -