Пример #1
0
        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);
        }
Пример #2
0
        private void UnpWriteBuf()
        {
            int WrittenBorder = wrPtr;
            int WriteSize     = (unpPtr - WrittenBorder) & Compress.MAXWINMASK;

            for (int I = 0; I < prgStack.Count; I++)
            {
                UnpackFilter flt = prgStack[I];
                if (flt == null)
                {
                    continue;
                }
                if (flt.NextWindow)
                {
                    flt.NextWindow = false; // ->NextWindow=false;
                    continue;
                }
                int BlockStart  = flt.BlockStart;  // ->BlockStart;
                int BlockLength = flt.BlockLength; // ->BlockLength;
                if (((BlockStart - WrittenBorder) & Compress.MAXWINMASK) < WriteSize)
                {
                    if (WrittenBorder != BlockStart)
                    {
                        UnpWriteArea(WrittenBorder, BlockStart);
                        WrittenBorder = BlockStart;
                        WriteSize     = (unpPtr - WrittenBorder) & Compress.MAXWINMASK;
                    }
                    if (BlockLength <= WriteSize)
                    {
                        int BlockEnd = (BlockStart + BlockLength) & Compress.MAXWINMASK;
                        if (BlockStart < BlockEnd || BlockEnd == 0)
                        {
                            // VM.SetMemory(0,Window+BlockStart,BlockLength);
                            rarVM.setMemory(0, window, BlockStart, BlockLength);
                        }
                        else
                        {
                            int FirstPartLength = Compress.MAXWINSIZE - BlockStart;
                            // VM.SetMemory(0,Window+BlockStart,FirstPartLength);
                            rarVM.setMemory(0, window, BlockStart, FirstPartLength);
                            // VM.SetMemory(FirstPartLength,Window,BlockEnd);
                            rarVM.setMemory(FirstPartLength, window, 0, BlockEnd);
                        }

                        VMPreparedProgram ParentPrg = filters[flt.ParentFilter].Program;
                        VMPreparedProgram Prg       = flt.Program;

                        if (ParentPrg.GlobalData.Count > RarVM.VM_FIXEDGLOBALSIZE)
                        {
                            // copy global data from previous script execution if
                            // any
                            // Prg->GlobalData.Alloc(ParentPrg->GlobalData.Size());
                            // memcpy(&Prg->GlobalData[VM_FIXEDGLOBALSIZE],&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],ParentPrg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);
                            Prg.GlobalData.Clear();
                            for (int i = 0; i < ParentPrg.GlobalData.Count - RarVM.VM_FIXEDGLOBALSIZE; i++)
                            {
                                Prg.GlobalData[RarVM.VM_FIXEDGLOBALSIZE + i] = ParentPrg.GlobalData[RarVM.VM_FIXEDGLOBALSIZE + i];
                            }
                        }

                        ExecuteCode(Prg);

                        if (Prg.GlobalData.Count > RarVM.VM_FIXEDGLOBALSIZE)
                        {
                            // save global data for next script execution
                            if (ParentPrg.GlobalData.Count < Prg.GlobalData.Count)
                            {
                                //ParentPrg.GlobalData.Clear(); // ->GlobalData.Alloc(Prg->GlobalData.Size());
                                ParentPrg.GlobalData.SetSize(Prg.GlobalData.Count);
                            }
                            // memcpy(&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],&Prg->GlobalData[VM_FIXEDGLOBALSIZE],Prg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);
                            for (int i = 0; i < Prg.GlobalData.Count - RarVM.VM_FIXEDGLOBALSIZE; i++)
                            {
                                ParentPrg.GlobalData[RarVM.VM_FIXEDGLOBALSIZE + i] = Prg.GlobalData[RarVM.VM_FIXEDGLOBALSIZE + i];
                            }
                        }
                        else
                        {
                            ParentPrg.GlobalData.Clear();
                        }

                        int    FilteredDataOffset = Prg.FilteredDataOffset;
                        int    FilteredDataSize   = Prg.FilteredDataSize;
                        byte[] FilteredData       = new byte[FilteredDataSize];

                        for (int i = 0; i < FilteredDataSize; i++)
                        {
                            FilteredData[i] = rarVM.Mem[FilteredDataOffset + i]; // Prg.GlobalData.get(FilteredDataOffset
                            // +
                            // i);
                        }

                        prgStack[I] = null;
                        while (I + 1 < prgStack.Count)
                        {
                            UnpackFilter NextFilter = prgStack[I + 1];
                            if (NextFilter == null || NextFilter.BlockStart != BlockStart || NextFilter.BlockLength != FilteredDataSize || NextFilter.NextWindow)
                            {
                                break;
                            }
                            // apply several filters to same data block

                            rarVM.setMemory(0, FilteredData, 0, FilteredDataSize); // .SetMemory(0,FilteredData,FilteredDataSize);

                            VMPreparedProgram pPrg    = filters[NextFilter.ParentFilter].Program;
                            VMPreparedProgram NextPrg = NextFilter.Program;

                            if (pPrg.GlobalData.Count > RarVM.VM_FIXEDGLOBALSIZE)
                            {
                                // copy global data from previous script execution
                                // if any
                                // NextPrg->GlobalData.Alloc(ParentPrg->GlobalData.Size());
                                NextPrg.GlobalData.SetSize(pPrg.GlobalData.Count);
                                // memcpy(&NextPrg->GlobalData[VM_FIXEDGLOBALSIZE],&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],ParentPrg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);
                                for (int i = 0; i < pPrg.GlobalData.Count - RarVM.VM_FIXEDGLOBALSIZE; i++)
                                {
                                    NextPrg.GlobalData[RarVM.VM_FIXEDGLOBALSIZE + i] = pPrg.GlobalData[RarVM.VM_FIXEDGLOBALSIZE + i];
                                }
                            }

                            ExecuteCode(NextPrg);

                            if (NextPrg.GlobalData.Count > RarVM.VM_FIXEDGLOBALSIZE)
                            {
                                // save global data for next script execution
                                if (pPrg.GlobalData.Count < NextPrg.GlobalData.Count)
                                {
                                    pPrg.GlobalData.SetSize(NextPrg.GlobalData.Count);
                                }
                                // memcpy(&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],&NextPrg->GlobalData[VM_FIXEDGLOBALSIZE],NextPrg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);
                                for (int i = 0; i < NextPrg.GlobalData.Count - RarVM.VM_FIXEDGLOBALSIZE; i++)
                                {
                                    pPrg.GlobalData[RarVM.VM_FIXEDGLOBALSIZE + i] = NextPrg.GlobalData[RarVM.VM_FIXEDGLOBALSIZE + i];
                                }
                            }
                            else
                            {
                                pPrg.GlobalData.Clear();
                            }
                            FilteredDataOffset = NextPrg.FilteredDataOffset;
                            FilteredDataSize   = NextPrg.FilteredDataSize;

                            FilteredData = new byte[FilteredDataSize];
                            for (int i = 0; i < FilteredDataSize; i++)
                            {
                                FilteredData[i] = NextPrg.GlobalData[FilteredDataOffset + i];
                            }

                            I++;
                            prgStack[I] = null;
                        }
                        writeStream.Write(FilteredData, 0, FilteredDataSize);
                        unpSomeRead      = true;
                        writtenFileSize += FilteredDataSize;
                        destUnpSize     -= FilteredDataSize;
                        WrittenBorder    = BlockEnd;
                        WriteSize        = (unpPtr - WrittenBorder) & Compress.MAXWINMASK;
                    }
                    else
                    {
                        for (int J = I; J < prgStack.Count; J++)
                        {
                            UnpackFilter filt = prgStack[J];
                            if (filt != null && filt.NextWindow)
                            {
                                filt.NextWindow = false;
                            }
                        }
                        wrPtr = WrittenBorder;
                        return;
                    }
                }
            }

            UnpWriteArea(WrittenBorder, unpPtr);
            wrPtr = unpPtr;
        }
Пример #3
0
        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);
        }
Пример #4
0
 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;
 }
Пример #5
0
        private void UnpWriteBuf()
        {
            int wrPtr = base.wrPtr;
            int num2  = (base.unpPtr - wrPtr) & Compress.MAXWINMASK;

            for (int i = 0; i < this.prgStack.Count; i++)
            {
                UnpackFilter filter = this.prgStack[i];
                if (filter != null)
                {
                    if (filter.NextWindow)
                    {
                        filter.NextWindow = false;
                        continue;
                    }
                    int blockStart  = filter.BlockStart;
                    int blockLength = filter.BlockLength;
                    if (((blockStart - wrPtr) & Compress.MAXWINMASK) < num2)
                    {
                        if (wrPtr != blockStart)
                        {
                            this.UnpWriteArea(wrPtr, blockStart);
                            wrPtr = blockStart;
                            num2  = (base.unpPtr - wrPtr) & Compress.MAXWINMASK;
                        }
                        if (blockLength <= num2)
                        {
                            int num8;
                            int dataSize = (blockStart + blockLength) & Compress.MAXWINMASK;
                            if ((blockStart < dataSize) || (dataSize == 0))
                            {
                                this.rarVM.setMemory(0, base.window, blockStart, blockLength);
                            }
                            else
                            {
                                int num7 = 0x400000 - blockStart;
                                this.rarVM.setMemory(0, base.window, blockStart, num7);
                                this.rarVM.setMemory(num7, base.window, 0, dataSize);
                            }
                            VMPreparedProgram program = this.filters[filter.ParentFilter].Program;
                            VMPreparedProgram prg     = filter.Program;
                            if (program.GlobalData.Count > 0x40)
                            {
                                prg.GlobalData.Clear();
                                num8 = 0;
                                while (num8 < (program.GlobalData.Count - 0x40))
                                {
                                    prg.GlobalData[0x40 + num8] = program.GlobalData[0x40 + num8];
                                    num8++;
                                }
                            }
                            this.ExecuteCode(prg);
                            if (prg.GlobalData.Count > 0x40)
                            {
                                if (program.GlobalData.Count < prg.GlobalData.Count)
                                {
                                    Utility.SetSize(program.GlobalData, prg.GlobalData.Count);
                                }
                                num8 = 0;
                                while (num8 < (prg.GlobalData.Count - 0x40))
                                {
                                    program.GlobalData[0x40 + num8] = prg.GlobalData[0x40 + num8];
                                    num8++;
                                }
                            }
                            else
                            {
                                program.GlobalData.Clear();
                            }
                            int    filteredDataOffset = prg.FilteredDataOffset;
                            int    filteredDataSize   = prg.FilteredDataSize;
                            byte[] data = new byte[filteredDataSize];
                            num8 = 0;
                            while (num8 < filteredDataSize)
                            {
                                data[num8] = this.rarVM.Mem[filteredDataOffset + num8];
                                num8++;
                            }
                            this.prgStack[i] = null;
                            while ((i + 1) < this.prgStack.Count)
                            {
                                UnpackFilter filter2 = this.prgStack[i + 1];
                                if ((((filter2 == null) || (filter2.BlockStart != blockStart)) || (filter2.BlockLength != filteredDataSize)) || filter2.NextWindow)
                                {
                                    break;
                                }
                                this.rarVM.setMemory(0, data, 0, filteredDataSize);
                                VMPreparedProgram program3 = this.filters[filter2.ParentFilter].Program;
                                VMPreparedProgram program4 = filter2.Program;
                                if (program3.GlobalData.Count > 0x40)
                                {
                                    Utility.SetSize(program4.GlobalData, program3.GlobalData.Count);
                                    num8 = 0;
                                    while (num8 < (program3.GlobalData.Count - 0x40))
                                    {
                                        program4.GlobalData[0x40 + num8] = program3.GlobalData[0x40 + num8];
                                        num8++;
                                    }
                                }
                                this.ExecuteCode(program4);
                                if (program4.GlobalData.Count > 0x40)
                                {
                                    if (program3.GlobalData.Count < program4.GlobalData.Count)
                                    {
                                        Utility.SetSize(program3.GlobalData, program4.GlobalData.Count);
                                    }
                                    num8 = 0;
                                    while (num8 < (program4.GlobalData.Count - 0x40))
                                    {
                                        program3.GlobalData[0x40 + num8] = program4.GlobalData[0x40 + num8];
                                        num8++;
                                    }
                                }
                                else
                                {
                                    program3.GlobalData.Clear();
                                }
                                filteredDataOffset = program4.FilteredDataOffset;
                                filteredDataSize   = program4.FilteredDataSize;
                                data = new byte[filteredDataSize];
                                for (num8 = 0; num8 < filteredDataSize; num8++)
                                {
                                    data[num8] = program4.GlobalData[filteredDataOffset + num8];
                                }
                                i++;
                                this.prgStack[i] = null;
                            }
                            base.writeStream.Write(data, 0, filteredDataSize);
                            base.unpSomeRead      = true;
                            this.writtenFileSize += filteredDataSize;
                            base.destUnpSize     -= filteredDataSize;
                            wrPtr = dataSize;
                            num2  = (base.unpPtr - wrPtr) & Compress.MAXWINMASK;
                            continue;
                        }
                        for (int j = i; j < this.prgStack.Count; j++)
                        {
                            UnpackFilter filter3 = this.prgStack[j];
                            if ((filter3 != null) && filter3.NextWindow)
                            {
                                filter3.NextWindow = false;
                            }
                        }
                        base.wrPtr = wrPtr;
                        return;
                    }
                }
            }
            this.UnpWriteArea(wrPtr, base.unpPtr);
            base.wrPtr = base.unpPtr;
        }
Пример #6
0
        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);
        }