private bool addVMCode(int firstByte, List<byte> vmCode, int length) { BitInput Inp = new BitInput(); Inp.InitBitInput(); // memcpy(Inp.InBuf,Code,Min(BitInput::MAX_SIZE,CodeSize)); for (int i = 0; i < Math.Min(BitInput.MAX_SIZE, vmCode.Count); i++) { Inp.InBuf[i] = vmCode[i]; } rarVM.init(); int FiltPos; if ((firstByte & 0x80) != 0) { FiltPos = RarVM.ReadData(Inp); if (FiltPos == 0) { initFilters(); } else { FiltPos--; } } else FiltPos = lastFilter; // use the same filter as last time if (FiltPos > filters.Count || FiltPos > oldFilterLengths.Count) { return (false); } lastFilter = FiltPos; bool NewFilter = (FiltPos == filters.Count); UnpackFilter StackFilter = new UnpackFilter(); // new filter for // PrgStack UnpackFilter Filter; if (NewFilter) // new filter code, never used before since VM reset { // too many different filters, corrupt archive if (FiltPos > 1024) { return (false); } // Filters[Filters.Size()-1]=Filter=new UnpackFilter; Filter = new UnpackFilter(); filters.Add(Filter); StackFilter.ParentFilter = filters.Count - 1; oldFilterLengths.Add(0); Filter.ExecCount = 0; } // filter was used in the past else { Filter = filters[FiltPos]; StackFilter.ParentFilter = FiltPos; Filter.ExecCount = Filter.ExecCount + 1; // ->ExecCount++; } prgStack.Add(StackFilter); StackFilter.ExecCount = Filter.ExecCount; // ->ExecCount; int BlockStart = RarVM.ReadData(Inp); if ((firstByte & 0x40) != 0) { BlockStart += 258; } StackFilter.BlockStart = ((BlockStart + unpPtr) & Compress.MAXWINMASK); if ((firstByte & 0x20) != 0) { StackFilter.BlockLength = RarVM.ReadData(Inp); } else { StackFilter.BlockLength = FiltPos < oldFilterLengths.Count ? oldFilterLengths[FiltPos] : 0; } StackFilter.NextWindow = (wrPtr != unpPtr) && ((wrPtr - unpPtr) & Compress.MAXWINMASK) <= BlockStart; // DebugLog("\nNextWindow: UnpPtr=%08x WrPtr=%08x // BlockStart=%08x",UnpPtr,WrPtr,BlockStart); oldFilterLengths[FiltPos] = StackFilter.BlockLength; // memset(StackFilter->Prg.InitR,0,sizeof(StackFilter->Prg.InitR)); Utility.Fill(StackFilter.Program.InitR, 0); StackFilter.Program.InitR[3] = RarVM.VM_GLOBALMEMADDR; // StackFilter->Prg.InitR[3]=VM_GLOBALMEMADDR; StackFilter.Program.InitR[4] = StackFilter.BlockLength; // StackFilter->Prg.InitR[4]=StackFilter->BlockLength; StackFilter.Program.InitR[5] = StackFilter.ExecCount; // StackFilter->Prg.InitR[5]=StackFilter->ExecCount; if ((firstByte & 0x10) != 0) // set registers to optional parameters // if any { int InitMask = Utility.URShift(Inp.GetBits(), 9); Inp.AddBits(7); for (int I = 0; I < 7; I++) { if ((InitMask & (1 << I)) != 0) { // StackFilter->Prg.InitR[I]=RarVM::ReadData(Inp); StackFilter.Program.InitR[I] = RarVM.ReadData(Inp); } } } if (NewFilter) { int VMCodeSize = RarVM.ReadData(Inp); if (VMCodeSize >= 0x10000 || VMCodeSize == 0) { return (false); } byte[] VMCode = new byte[VMCodeSize]; for (int I = 0; I < VMCodeSize; I++) { if (Inp.Overflow(3)) { return (false); } VMCode[I] = (byte)(Inp.GetBits() >> 8); Inp.AddBits(8); } // VM.Prepare(&VMCode[0],VMCodeSize,&Filter->Prg); rarVM.prepare(VMCode, VMCodeSize, Filter.Program); } StackFilter.Program.AltCommands = Filter.Program.Commands; // StackFilter->Prg.AltCmd=&Filter->Prg.Cmd[0]; StackFilter.Program.CommandCount = Filter.Program.CommandCount; // StackFilter->Prg.CmdCount=Filter->Prg.CmdCount; int StaticDataSize = Filter.Program.StaticData.Count; if (StaticDataSize > 0 && StaticDataSize < RarVM.VM_GLOBALMEMSIZE) { // read statically defined data contained in DB commands // StackFilter->Prg.StaticData.Add(StaticDataSize); StackFilter.Program.StaticData = Filter.Program.StaticData; // memcpy(&StackFilter->Prg.StaticData[0],&Filter->Prg.StaticData[0],StaticDataSize); } if (StackFilter.Program.GlobalData.Count < RarVM.VM_FIXEDGLOBALSIZE) { // StackFilter->Prg.GlobalData.Reset(); // StackFilter->Prg.GlobalData.Add(VM_FIXEDGLOBALSIZE); StackFilter.Program.GlobalData.Clear(); StackFilter.Program.GlobalData.SetSize(RarVM.VM_FIXEDGLOBALSIZE); } // byte *GlobalData=&StackFilter->Prg.GlobalData[0]; List<byte> globalData = StackFilter.Program.GlobalData; for (int I = 0; I < 7; I++) { rarVM.SetLowEndianValue(globalData, I * 4, StackFilter.Program.InitR[I]); } // VM.SetLowEndianValue((uint // *)&GlobalData[0x1c],StackFilter->BlockLength); rarVM.SetLowEndianValue(globalData, 0x1c, StackFilter.BlockLength); // VM.SetLowEndianValue((uint *)&GlobalData[0x20],0); rarVM.SetLowEndianValue(globalData, 0x20, 0); rarVM.SetLowEndianValue(globalData, 0x24, 0); rarVM.SetLowEndianValue(globalData, 0x28, 0); // VM.SetLowEndianValue((uint // *)&GlobalData[0x2c],StackFilter->ExecCount); rarVM.SetLowEndianValue(globalData, 0x2c, StackFilter.ExecCount); // memset(&GlobalData[0x30],0,16); for (int i = 0; i < 16; i++) { globalData[0x30 + i] = 0x0; } if ((firstByte & 8) != 0) // put data block passed as parameter if any { if (Inp.Overflow(3)) { return (false); } int DataSize = RarVM.ReadData(Inp); if (DataSize > RarVM.VM_GLOBALMEMSIZE - RarVM.VM_FIXEDGLOBALSIZE) { return (false); } int CurSize = StackFilter.Program.GlobalData.Count; if (CurSize < DataSize + RarVM.VM_FIXEDGLOBALSIZE) { // StackFilter->Prg.GlobalData.Add(DataSize+VM_FIXEDGLOBALSIZE-CurSize); StackFilter.Program.GlobalData.SetSize(DataSize + RarVM.VM_FIXEDGLOBALSIZE - CurSize); } int offset = RarVM.VM_FIXEDGLOBALSIZE; globalData = StackFilter.Program.GlobalData; for (int I = 0; I < DataSize; I++) { if (Inp.Overflow(3)) { return (false); } globalData[offset + I] = (byte)(Utility.URShift(Inp.GetBits(), 8)); Inp.AddBits(8); } } return (true); }
internal static int ReadData(BitInput rarVM) { int data = rarVM.GetBits(); switch (data & 0xc000) { case 0: rarVM.AddBits(6); return ((data >> 10) & 0xf); case 0x4000: if ((data & 0x3c00) == 0) { data = unchecked((int)0xffffff00) | ((data >> 2) & 0xff); rarVM.AddBits(14); } else { data = (data >> 6) & 0xff; rarVM.AddBits(10); } return (data); case 0x8000: rarVM.AddBits(2); data = rarVM.GetBits(); rarVM.AddBits(16); return (data); default: rarVM.AddBits(2); data = (rarVM.GetBits() << 16); rarVM.AddBits(16); data |= rarVM.GetBits(); rarVM.AddBits(16); return (data); } }
internal static int decodeNumber(/*this*/ BitInput input, Decode dec) { int bits; long bitField = input.GetBits() & 0xfffe; // if (bitField < dec.getDecodeLen()[8]) { // if (bitField < dec.getDecodeLen()[4]) { // if (bitField < dec.getDecodeLen()[2]) { // if (bitField < dec.getDecodeLen()[1]) { // bits = 1; // } else { // bits = 2; // } // } else { // if (bitField < dec.getDecodeLen()[3]) { // bits = 3; // } else { // bits = 4; // } // } // } else { // if (bitField < dec.getDecodeLen()[6]) { // if (bitField < dec.getDecodeLen()[5]) // bits = 5; // else // bits = 6; // } else { // if (bitField < dec.getDecodeLen()[7]) { // bits = 7; // } else { // bits = 8; // } // } // } // } else { // if (bitField < dec.getDecodeLen()[12]) { // if (bitField < dec.getDecodeLen()[10]) // if (bitField < dec.getDecodeLen()[9]) // bits = 9; // else // bits = 10; // else if (bitField < dec.getDecodeLen()[11]) // bits = 11; // else // bits = 12; // } else { // if (bitField < dec.getDecodeLen()[14]) { // if (bitField < dec.getDecodeLen()[13]) { // bits = 13; // } else { // bits = 14; // } // } else { // bits = 15; // } // } // } // addbits(bits); // int N = dec.getDecodePos()[bits] // + (((int) bitField - dec.getDecodeLen()[bits - 1]) >>> (16 - bits)); // if (N >= dec.getMaxNum()) { // N = 0; // } // return (dec.getDecodeNum()[N]); int[] decodeLen = dec.DecodeLen; if (bitField < decodeLen[8]) { if (bitField < decodeLen[4]) { if (bitField < decodeLen[2]) { if (bitField < decodeLen[1]) { bits = 1; } else { bits = 2; } } else { if (bitField < decodeLen[3]) { bits = 3; } else { bits = 4; } } } else { if (bitField < decodeLen[6]) { if (bitField < decodeLen[5]) bits = 5; else bits = 6; } else { if (bitField < decodeLen[7]) { bits = 7; } else { bits = 8; } } } } else { if (bitField < decodeLen[12]) { if (bitField < decodeLen[10]) if (bitField < decodeLen[9]) bits = 9; else bits = 10; else if (bitField < decodeLen[11]) bits = 11; else bits = 12; } else { if (bitField < decodeLen[14]) { if (bitField < decodeLen[13]) { bits = 13; } else { bits = 14; } } else { bits = 15; } } } input.AddBits(bits); int N = dec.DecodePos[bits] + (Utility.URShift(((int) bitField - decodeLen[bits - 1]), (16 - bits))); if (N >= dec.MaxNum) { N = 0; } return (dec.DecodeNum[N]); }
private bool addVMCode(int firstByte, List<byte> vmCode, int length) { int num; int lastFilter; UnpackFilter filter2; int num5; BitInput rarVM = new BitInput(); rarVM.InitBitInput(); for (num = 0; num < Math.Min(0x8000, vmCode.Count); num++) { rarVM.InBuf[num] = vmCode[num]; } this.rarVM.init(); if ((firstByte & 0x80) != 0) { lastFilter = RarVM.ReadData(rarVM); if (lastFilter == 0) { this.initFilters(); } else { lastFilter--; } } else { lastFilter = this.lastFilter; } if ((lastFilter > this.filters.Count) || (lastFilter > this.oldFilterLengths.Count)) { return false; } this.lastFilter = lastFilter; bool flag = lastFilter == this.filters.Count; UnpackFilter item = new UnpackFilter(); if (flag) { if (lastFilter > 0x400) { return false; } filter2 = new UnpackFilter(); this.filters.Add(filter2); item.ParentFilter = this.filters.Count - 1; this.oldFilterLengths.Add(0); filter2.ExecCount = 0; } else { filter2 = this.filters[lastFilter]; item.ParentFilter = lastFilter; filter2.ExecCount++; } this.prgStack.Add(item); item.ExecCount = filter2.ExecCount; int num3 = RarVM.ReadData(rarVM); if ((firstByte & 0x40) != 0) { num3 += 0x102; } item.BlockStart = (num3 + base.unpPtr) & Compress.MAXWINMASK; if ((firstByte & 0x20) != 0) { item.BlockLength = RarVM.ReadData(rarVM); } else { item.BlockLength = (lastFilter < this.oldFilterLengths.Count) ? this.oldFilterLengths[lastFilter] : 0; } item.NextWindow = (base.wrPtr != base.unpPtr) && (((base.wrPtr - base.unpPtr) & Compress.MAXWINMASK) <= num3); this.oldFilterLengths[lastFilter] = item.BlockLength; Utility.Fill<int>(item.Program.InitR, 0); item.Program.InitR[3] = 0x3c000; item.Program.InitR[4] = item.BlockLength; item.Program.InitR[5] = item.ExecCount; if ((firstByte & 0x10) != 0) { int num4 = Utility.URShift(rarVM.GetBits(), 9); rarVM.AddBits(7); for (num5 = 0; num5 < 7; num5++) { if ((num4 & (((int) 1) << num5)) != 0) { item.Program.InitR[num5] = RarVM.ReadData(rarVM); } } } if (flag) { int codeSize = RarVM.ReadData(rarVM); if ((codeSize >= 0x10000) || (codeSize == 0)) { return false; } byte[] code = new byte[codeSize]; for (num5 = 0; num5 < codeSize; num5++) { if (rarVM.Overflow(3)) { return false; } code[num5] = (byte) (rarVM.GetBits() >> 8); rarVM.AddBits(8); } this.rarVM.prepare(code, codeSize, filter2.Program); } item.Program.AltCommands = filter2.Program.Commands; item.Program.CommandCount = filter2.Program.CommandCount; int count = filter2.Program.StaticData.Count; if ((count > 0) && (count < 0x2000)) { item.Program.StaticData = filter2.Program.StaticData; } if (item.Program.GlobalData.Count < 0x40) { item.Program.GlobalData.Clear(); Utility.SetSize(item.Program.GlobalData, 0x40); } List<byte> globalData = item.Program.GlobalData; for (num5 = 0; num5 < 7; num5++) { this.rarVM.SetLowEndianValue(globalData, num5 * 4, item.Program.InitR[num5]); } this.rarVM.SetLowEndianValue(globalData, 0x1c, item.BlockLength); this.rarVM.SetLowEndianValue(globalData, 0x20, 0); this.rarVM.SetLowEndianValue(globalData, 0x24, 0); this.rarVM.SetLowEndianValue(globalData, 40, 0); this.rarVM.SetLowEndianValue(globalData, 0x2c, item.ExecCount); for (num = 0; num < 0x10; num++) { globalData[0x30 + num] = 0; } if ((firstByte & 8) != 0) { if (rarVM.Overflow(3)) { return false; } int num8 = RarVM.ReadData(rarVM); if (num8 > 0x1fc0) { return false; } int num9 = item.Program.GlobalData.Count; if (num9 < (num8 + 0x40)) { Utility.SetSize(item.Program.GlobalData, (num8 + 0x40) - num9); } int num10 = 0x40; globalData = item.Program.GlobalData; for (num5 = 0; num5 < num8; num5++) { if (rarVM.Overflow(3)) { return false; } globalData[num10 + num5] = (byte) Utility.URShift(rarVM.GetBits(), 8); rarVM.AddBits(8); } } return true; }
internal static int decodeNumber(BitInput input, Decode dec) { int num; long num2 = input.GetBits() & 0xfffe; int[] decodeLen = dec.DecodeLen; if (num2 < decodeLen[8]) { if (num2 < decodeLen[4]) { if (num2 < decodeLen[2]) { if (num2 < decodeLen[1]) { num = 1; } else { num = 2; } } else if (num2 < decodeLen[3]) { num = 3; } else { num = 4; } } else if (num2 < decodeLen[6]) { if (num2 < decodeLen[5]) { num = 5; } else { num = 6; } } else if (num2 < decodeLen[7]) { num = 7; } else { num = 8; } } else if (num2 < decodeLen[12]) { if (num2 < decodeLen[10]) { if (num2 < decodeLen[9]) { num = 9; } else { num = 10; } } else if (num2 < decodeLen[11]) { num = 11; } else { num = 12; } } else if (num2 < decodeLen[14]) { if (num2 < decodeLen[13]) { num = 13; } else { num = 14; } } else { num = 15; } input.AddBits(num); int index = dec.DecodePos[num] + Utility.URShift((int) (((int) num2) - decodeLen[num - 1]), (int) (0x10 - num)); if (index >= dec.MaxNum) { index = 0; } return dec.DecodeNum[index]; }
internal static int ReadData(BitInput rarVM) { int bits = rarVM.GetBits(); switch ((bits & 0xc000)) { case 0: rarVM.AddBits(6); return ((bits >> 10) & 15); case 0x4000: if ((bits & 0x3c00) == 0) { bits = -256 | ((bits >> 2) & 0xff); rarVM.AddBits(14); return bits; } bits = (bits >> 6) & 0xff; rarVM.AddBits(10); return bits; case 0x8000: rarVM.AddBits(2); bits = rarVM.GetBits(); rarVM.AddBits(0x10); return bits; } rarVM.AddBits(2); bits = rarVM.GetBits() << 0x10; rarVM.AddBits(0x10); bits |= rarVM.GetBits(); rarVM.AddBits(0x10); return bits; }