Пример #1
0
        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);

            }
        }
Пример #2
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));
            Utilities.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 = Utilities.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.Prg.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);
            globalData.MemSet(0x30, 16);
            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.Clear();//.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)(Utilities.URShift(Inp.GetBits(), 8));
                    Inp.AddBits(8);
                }
            }
            return (true);
        }