コード例 #1
0
        void UnpWriteBuf30()
        {
            uint WrittenBorder = (uint)WrPtr;
            uint WriteSize     = (uint)((UnpPtr - WrittenBorder) & MaxWinMask);

            for (int I = 0; I < PrgStack.Count; I++)
            {
                // Here we apply filters to data which we need to write.
                // We always copy data to virtual machine memory before processing.
                // We cannot process them just in place in Window buffer, because
                // these data can be used for future string matches, so we must
                // preserve them in original form.

                UnpackFilter30 flt = PrgStack[I];
                if (flt == null)
                {
                    continue;
                }
                if (flt.NextWindow)
                {
                    flt.NextWindow = false;
                    continue;
                }
                uint BlockStart  = flt.BlockStart;
                uint BlockLength = flt.BlockLength;
                if (((BlockStart - WrittenBorder) & MaxWinMask) < WriteSize)
                {
                    if (WrittenBorder != BlockStart)
                    {
                        UnpWriteArea(WrittenBorder, BlockStart);
                        WrittenBorder = BlockStart;
                        WriteSize     = (uint)((UnpPtr - WrittenBorder) & MaxWinMask);
                    }
                    if (BlockLength <= WriteSize)
                    {
                        uint BlockEnd = (BlockStart + BlockLength) & MaxWinMask;
                        if (BlockStart < BlockEnd || BlockEnd == 0)
                        {
                            VM.SetMemory(0, Window + BlockStart, BlockLength);
                        }
                        else
                        {
                            uint FirstPartLength = uint(MaxWinSize - BlockStart);
                            VM.SetMemory(0, Window + BlockStart, FirstPartLength);
                            VM.SetMemory(FirstPartLength, Window, BlockEnd);
                        }

                        VM_PreparedProgram *ParentPrg = &Filters30[flt->ParentFilter]->Prg;
                        VM_PreparedProgram *Prg       = &flt->Prg;

                        ExecuteCode(Prg);

                        byte[] FilteredData     = Prg.FilteredData;
                        uint   FilteredDataSize = Prg.FilteredDataSize;

                        delete PrgStack[I];
コード例 #2
0
        bool AddVMCode(uint FirstByte, byte[] Code, int CodeSize)
        {
            VMCodeInp.InitBitInput();
            //x memcpy(VMCodeInp.InBuf,Code,Min(BitInput.MAX_SIZE,CodeSize));
            Array.Copy(Code, 0, VMCodeInp.InBuf, 0, Math.Min(BitInput.MAX_SIZE, CodeSize));
            VM.Init();

            uint FiltPos;

            if ((FirstByte & 0x80) != 0)
            {
                FiltPos = RarVM.ReadData(VMCodeInp);
                if (FiltPos == 0)
                {
                    InitFilters30(false);
                }
                else
                {
                    FiltPos--;
                }
            }
            else
            {
                FiltPos = (uint)this.LastFilter; // Use the same filter as last time.
            }
            if (FiltPos > Filters30.Count || FiltPos > OldFilterLengths.Count)
            {
                return(false);
            }
            LastFilter = (int)FiltPos;
            bool NewFilter = (FiltPos == Filters30.Count);

            UnpackFilter30 StackFilter = new UnpackFilter30(); // New filter for PrgStack.

            UnpackFilter30 Filter;

            if (NewFilter) // New filter code, never used before since VM reset.
            {
                if (FiltPos > MAX3_UNPACK_FILTERS)
                {
                    // Too many different filters, corrupt archive.
                    //delete StackFilter;
                    return(false);
                }

                Filters30.Add(1);
                Filters30[Filters30.Count - 1] = Filter = new UnpackFilter30();
                StackFilter.ParentFilter       = (uint)(Filters30.Count - 1);

                // Reserve one item to store the data block length of our new filter
                // entry. We'll set it to real block length below, after reading it.
                // But we need to initialize it now, because when processing corrupt
                // data, we can access this item even before we set it to real value.
                OldFilterLengths.Add(0);
            }
            else // Filter was used in the past.
            {
                Filter = Filters30[(int)FiltPos];
                StackFilter.ParentFilter = FiltPos;
            }

            int EmptyCount = 0;

            for (int I = 0; I < PrgStack.Count; I++)
            {
                PrgStack[I - EmptyCount] = PrgStack[I];
                if (PrgStack[I] == null)
                {
                    EmptyCount++;
                }
                if (EmptyCount > 0)
                {
                    PrgStack[I] = null;
                }
            }
            if (EmptyCount == 0)
            {
                if (PrgStack.Count > MAX3_UNPACK_FILTERS)
                {
                    //delete StackFilter;
                    return(false);
                }
                PrgStack.Add(1);
                EmptyCount = 1;
            }
            size_t StackPos = (uint)(this.PrgStack.Count - EmptyCount);

            PrgStack[(int)StackPos] = StackFilter;

            uint BlockStart = RarVM.ReadData(VMCodeInp);

            if ((FirstByte & 0x40) != 0)
            {
                BlockStart += 258;
            }
            StackFilter.BlockStart = (uint)((BlockStart + UnpPtr) & MaxWinMask);
            if ((FirstByte & 0x20) != 0)
            {
                StackFilter.BlockLength = RarVM.ReadData(VMCodeInp);

                // Store the last data block length for current filter.
                OldFilterLengths[(int)FiltPos] = (int)StackFilter.BlockLength;
            }
            else
            {
                // Set the data block size to same value as the previous block size
                // for same filter. It is possible for corrupt data to access a new
                // and not filled yet item of OldFilterLengths array here. This is why
                // we set new OldFilterLengths items to zero above.
                StackFilter.BlockLength = FiltPos < OldFilterLengths.Count ? OldFilterLengths[(int)FiltPos]:0;
            }

            StackFilter.NextWindow = WrPtr != UnpPtr && ((WrPtr - UnpPtr) & MaxWinMask) <= BlockStart;

//  DebugLog("\nNextWindow: UnpPtr=%08x WrPtr=%08x BlockStart=%08x",UnpPtr,WrPtr,BlockStart);

            memset(StackFilter.Prg.InitR, 0, sizeof(StackFilter.Prg.InitR));
            StackFilter.Prg.InitR[4] = StackFilter.BlockLength;

            if ((FirstByte & 0x10) != 0) // Set registers to optional parameters if any.
            {
                uint InitMask = VMCodeInp.fgetbits() >> 9;
                VMCodeInp.faddbits(7);
                for (int I = 0; I < 7; I++)
                {
                    if ((InitMask & (1 << I)) != 0)
                    {
                        StackFilter.Prg.InitR[I] = RarVM.ReadData(VMCodeInp);
                    }
                }
            }

            if (NewFilter)
            {
                uint VMCodeSize = RarVM.ReadData(VMCodeInp);
                if (VMCodeSize >= 0x10000 || VMCodeSize == 0)
                {
                    return(false);
                }
                Array <byte> VMCode(VMCodeSize);

                for (uint I = 0; I < VMCodeSize; I++)
                {
                    if (VMCodeInp.Overflow(3))
                    {
                        return(false);
                    }
                    VMCode[I] = VMCodeInp.fgetbits() >> 8;
                    VMCodeInp.faddbits(8);
                }
                VM.Prepare(&VMCode[0], VMCodeSize, &Filter->Prg);
            }
            StackFilter.Prg.Type = Filter.Prg.Type;

            return(true);
        }