Example #1
0
        public override RelocationResults Relocate(Program program, Address addrLoad)
		{
			ImageMap imageMap = imgLoadedMap;
			ImageReader rdr = new LeImageReader(exe.RawImage, (uint) exe.e_lfaRelocations);
            var relocations = new RelocationDictionary();
			int i = exe.e_cRelocations;
			while (i != 0)
			{
				uint offset = rdr.ReadLeUInt16();
				ushort segOffset = rdr.ReadLeUInt16();
				offset += segOffset * 0x0010u;

				ushort seg = (ushort) (imgLoaded.ReadLeUInt16(offset) + addrLoad.Selector.Value);
				imgLoaded.WriteLeUInt16(offset, seg);
				relocations.AddSegmentReference(offset, seg);

				imageMap.AddSegment(Address.SegPtr(seg, 0), seg.ToString("X4"), AccessMode.ReadWriteExecute, 0);
				--i;
			}
		
			// Found the start address.

			Address addrStart = Address.SegPtr((ushort)(exe.e_cs + addrLoad.Selector.Value), exe.e_ip);
			imageMap.AddSegment(
                Address.SegPtr(addrStart.Selector.Value, 0),
                addrStart.Selector.Value.ToString("X4"),
                AccessMode.ReadWriteExecute, 0);
            return new RelocationResults(
                new List<EntryPoint> { new EntryPoint(addrStart, arch.CreateProcessorState()) },
                relocations,
                new List<Address>());
		}
Example #2
0
        public ExePackLoader(IServiceProvider services, string filename, byte[] imgRaw)
            : base(services, filename, imgRaw)
        {
            arch = new IntelArchitecture(ProcessorMode.Real);
            platform = new MsdosPlatform(Services, arch);

            var exe = new ExeImageLoader(services, filename, imgRaw);
            this.exeHdrSize = (uint)(exe.e_cparHeader * 0x10U);
            this.hdrOffset = (uint)(exe.e_cparHeader + exe.e_cs) * 0x10U;
            ImageReader rdr = new LeImageReader(RawImage, hdrOffset);
            this.ip = rdr.ReadLeUInt16();
            this.cs = rdr.ReadLeUInt16();
            rdr.ReadLeUInt16();
            this.cbExepackHeader = rdr.ReadLeUInt16();
            this.sp = rdr.ReadLeUInt16();
            this.ss = rdr.ReadLeUInt16();
            this.cpUncompressed = rdr.ReadLeUInt16();

            int offset = ExePackHeaderOffset(exe);
            if (LoadedImage.CompareArrays(imgRaw, offset, signature, signature.Length))
            {
                relocationsOffset = 0x012D;
            }
            else if (LoadedImage.CompareArrays(imgRaw, offset, signature2, signature2.Length))
            {
                relocationsOffset = 0x0125;
            }
            else
                throw new ApplicationException("Not a recognized EXEPACK image.");
        }
Example #3
0
        public ExePackLoader(IServiceProvider services, string filename, byte[] imgRaw)
            : base(services, filename, imgRaw)
        {
            var cfgSvc = services.RequireService<IConfigurationService>();
            arch = cfgSvc.GetArchitecture("x86-real-16");
            platform =cfgSvc.GetEnvironment("ms-dos")
                .Load(Services, arch);

            var exe = new ExeImageLoader(services, filename, imgRaw);
            this.exeHdrSize = (uint)(exe.e_cparHeader * 0x10U);
            this.hdrOffset = (uint)(exe.e_cparHeader + exe.e_cs) * 0x10U;
            ImageReader rdr = new LeImageReader(RawImage, hdrOffset);
            this.ip = rdr.ReadLeUInt16();
            this.cs = rdr.ReadLeUInt16();
            rdr.ReadLeUInt16();
            this.cbExepackHeader = rdr.ReadLeUInt16();
            this.sp = rdr.ReadLeUInt16();
            this.ss = rdr.ReadLeUInt16();
            this.cpUncompressed = rdr.ReadLeUInt16();

            int offset = ExePackHeaderOffset(exe);
            if (MemoryArea.CompareArrays(imgRaw, offset, signature, signature.Length))
            {
                relocationsOffset = 0x012D;
            }
            else if (MemoryArea.CompareArrays(imgRaw, offset, signature2, signature2.Length))
            {
                relocationsOffset = 0x0125;
            }
            else
                throw new ApplicationException("Not a recognized EXEPACK image.");
        }
Example #4
0
 private FileHeader LoadHeader()
 {
     var rdr = new LeImageReader(RawImage, 0);
     var magic = rdr.ReadLeUInt16();
     switch (magic)
     {
     case 0x014C: arch = new IntelArchitecture(ProcessorMode.Protected32); break;
     default: throw new NotSupportedException();
     }
     return  new FileHeader
     {
         f_magic = magic,
         f_nscns = rdr.ReadUInt16(),
         f_timdat = rdr.ReadUInt32(),
         f_symptr = rdr.ReadUInt32(),
         f_nsyms = rdr.ReadUInt32(),
         f_opthdr = rdr.ReadUInt16(),
         f_flags = rdr.ReadUInt16(),
     };
 }
Example #5
0
 private FileHeader LoadHeader()
 {
     var rdr = new LeImageReader(RawImage, 0);
     var magic = rdr.ReadLeUInt16();
     var cfgSvc = Services.RequireService<IConfigurationService>();
     switch (magic)
     {
     case 0x014C: arch = cfgSvc.GetArchitecture("x86-real-16"); break;
     default: throw new NotSupportedException();
     }
     return new FileHeader
     {
         f_magic = magic,
         f_nscns = rdr.ReadUInt16(),
         f_timdat = rdr.ReadUInt32(),
         f_symptr = rdr.ReadUInt32(),
         f_nsyms = rdr.ReadUInt32(),
         f_opthdr = rdr.ReadUInt16(),
         f_flags = rdr.ReadUInt16(),
     };
 }
Example #6
0
		public void ReadCommonExeFields()
		{
			ImageReader rdr = new LeImageReader(RawImage, 0);

			e_magic = rdr.ReadLeUInt16();
			e_cbLastPage = rdr.ReadLeUInt16();
			e_cpImage = rdr.ReadLeUInt16();
			this.e_cRelocations = rdr.ReadLeUInt16();
			e_cparHeader = rdr.ReadLeUInt16();
			e_minalloc = rdr.ReadLeUInt16();
			e_maxalloc = rdr.ReadLeUInt16();
			e_ss = rdr.ReadLeUInt16();
			e_sp = rdr.ReadLeUInt16();
			e_csum = rdr.ReadLeUInt16();
			e_ip = rdr.ReadLeUInt16();
			e_cs = rdr.ReadLeUInt16();
			e_lfaRelocations = rdr.ReadLeUInt16();
			e_ovno = rdr.ReadLeUInt16();
			e_res = new ushort[4];
			for (int i = 0; i != 4; ++i)
			{
				e_res[i] = rdr.ReadLeUInt16();
			}
			e_oemid = rdr.ReadLeUInt16();
			e_oeminfo = rdr.ReadLeUInt16();
			e_res2 = new ushort[10];
			for (int i = 0; i != 10; ++i)
			{
				e_res2[i] = rdr.ReadLeUInt16();
			}
			e_lfanew = rdr.ReadLeUInt32();
		}
Example #7
0
        private NeSegment[] ReadSegmentTable(uint offset, int cSeg)
        {
            var segs = new List<NeSegment>(cSeg);
            var rdr = new LeImageReader(RawImage, offset);
            uint linAddress = 0x2000;
            for (int iSeg = 0; iSeg < cSeg; ++iSeg)
            {
                var seg = new NeSegment
                {
                    DataOffset = rdr.ReadLeUInt16(),
                    DataLength = rdr.ReadLeUInt16(),
                    Flags = rdr.ReadLeUInt16(),
                    Alloc = rdr.ReadLeUInt16()
                };
                uint cbSegmentPage = Math.Max(seg.Alloc, seg.DataLength);
                // We allocate segments on 4 kb boundaries for convenience,
                // but protected mode code must never assume addresses are
                // linear.
                // Align to 4kb boundary.
                cbSegmentPage = (cbSegmentPage + 0xFFFu) & ~0xFFFu;
                seg.LinearAddress = linAddress;
                seg.Address = Address.ProtectedSegPtr((ushort)((linAddress >> 9) | 7), 0);
                segs.Add(seg);
                linAddress += cbSegmentPage;
            }

            // Generate pseudo-segment for imports
            addrImportStubs = Address.ProtectedSegPtr((ushort)((linAddress >> 9) | 7), 0);

            return segs.ToArray();
        }
Example #8
0
 void LoadModuleTable(uint offset, int cModules)
 {
     var rdr = new LeImageReader(RawImage, offset);
     this.moduleNames = new List<string>();
     for (int i = 0; i < cModules; ++i)
     {
         uint nameOffset = rdr.ReadLeUInt16();
         if (nameOffset == 0)
             break;
         nameOffset += lfaNew + this.offImportedNamesTable;
         var rdrName = new LeImageReader(RawImage, nameOffset);
         byte length = rdrName.ReadByte();
         byte[] abModuleName = rdrName.ReadBytes(length);
         var moduleName = Encoding.ASCII.GetString(abModuleName);
         moduleNames.Add(moduleName);
     }
 }
Example #9
0
        public override RelocationResults Relocate(Program program, Address addrLoad)
        {
            ImageReader rdr = new LeImageReader(RawImage, hdrOffset + relocationsOffset);
            ushort segCode = (ushort)(addrLoad.Selector + (ExeImageLoader.CbPsp >> 4));
            ushort dx = 0;
            for (; ; )
            {
                int cx = rdr.ReadLeUInt16();
                if (cx != 0)
                {
                    uint relocBase = ExeImageLoader.CbPsp + dx * 0x10u;
                    do
                    {
                        ushort relocOff = rdr.ReadLeUInt16();
                        ushort seg = imgU.FixupLeUInt16(relocBase + relocOff, segCode);
                        imageMap.AddSegment(Address.SegPtr(seg, 0), seg.ToString("X4"), AccessMode.ReadWriteExecute);
                    } while (--cx != 0);
                }
                if (dx == 0xF000)
                    break;
                dx += (ushort)0x1000U;
            }

            this.cs += segCode;
            imageMap.AddSegment(Address.SegPtr(cs, 0), cs.ToString("X4"), AccessMode.ReadWriteExecute);
            this.ss += segCode;
            var state = arch.CreateProcessorState();
            state.SetRegister(Registers.ds, Constant.Word16(addrLoad.Selector));
            state.SetRegister(Registers.es, Constant.Word16(addrLoad.Selector));
            state.SetRegister(Registers.cs, Constant.Word16(cs));
            state.SetRegister(Registers.ss, Constant.Word16(ss));
            state.SetRegister(Registers.bx, Constant.Word16(0));
            var entryPoints = new List<EntryPoint> 
            {
                new EntryPoint(Address.SegPtr(cs, ip), state)
            };
            return new RelocationResults(entryPoints, new RelocationDictionary());
        }
Example #10
0
        public override RelocationResults Relocate(Program program, Address addrLoad)
		{
			SegmentMap imageMap = segmentMap;
			ImageReader rdr = new LeImageReader(exe.RawImage, (uint) exe.e_lfaRelocations);
            var relocations = imgLoaded.Relocations;
			int i = exe.e_cRelocations;
            var segments = new Dictionary<Address, ushort>();
			while (i != 0)
			{
				uint offset = rdr.ReadLeUInt16();
				ushort segOffset = rdr.ReadLeUInt16();
				offset += segOffset * 0x0010u;

				ushort seg = (ushort) (imgLoaded.ReadLeUInt16(offset) + addrLoad.Selector.Value);
				imgLoaded.WriteLeUInt16(offset, seg);
				relocations.AddSegmentReference(offset, seg);

                var segment = new ImageSegment(
                    seg.ToString("X4"),
                    Address.SegPtr(seg, 0),
                    imgLoaded, 
                    AccessMode.ReadWriteExecute);
                segment = segmentMap.AddSegment(segment);
                segments[segment.Address] = seg;
				--i;
			}
		
            // Create an identifier for each segment.
            foreach (var de in segments)
            {
                var tmp = new TemporaryStorage(
                    string.Format("seg{0:X4}", de.Value),
                    0,
                    PrimitiveType.SegmentSelector);
                segmentMap.Segments[de.Key].Identifier = new Identifier(
                    tmp.Name,
                    PrimitiveType.SegmentSelector,
                    tmp);
            }

			// Found the start address.

			Address addrStart = Address.SegPtr((ushort)(exe.e_cs + addrLoad.Selector.Value), exe.e_ip);
			segmentMap.AddSegment(new ImageSegment(
                addrStart.Selector.Value.ToString("X4"),
                Address.SegPtr(addrStart.Selector.Value, 0),
                imgLoaded,
                AccessMode.ReadWriteExecute));
            DumpSegments(imageMap);

            var ep = new ImageSymbol(addrStart)
            {
                Type = SymbolType.Procedure,
                ProcessorState = arch.CreateProcessorState()
            };
            var sym = platform.FindMainProcedure(program, addrStart);
            var results = new RelocationResults(
                new List<ImageSymbol> { ep },
                new SortedList<Address, ImageSymbol> { { ep.Address, ep } });
            if (sym != null)
            {
                results.Symbols[sym.Address] = sym;
                ep.NoDecompile = true;
            }
            return results;
		}
Example #11
0
        public LoadedImage Unpack(byte [] abC, Address addrLoad)
        {
            // Extract the LZ stuff.

            ImageReader rdr = new LeImageReader(abC, (uint) lzHdrOffset);
            lzIp = rdr.ReadLeUInt16();
            lzCs = rdr.ReadLeUInt16();
            ushort lzSp = rdr.ReadLeUInt16();
            ushort lzSs = rdr.ReadLeUInt16();
            ushort lzcpCompressed = rdr.ReadLeUInt16();
            ushort lzcpDecompressed = rdr.ReadLeUInt16();

            // Find the start of the compressed stream.

            int ifile = lzHdrOffset - (lzcpCompressed << 4);

            // Allocate space for the decompressed goo.

            int cbUncompressed = ((int) lzcpDecompressed + lzcpDecompressed) << 4;
            byte [] abU = new byte[cbUncompressed];

            // Decompress this sorry mess.

            int len;
            int span;
            int p = 0;
            BitStream bits = new BitStream(abC, ifile);
            for (;;)
            {
                if (bits.GetBit() != 0)
                {
                    // 1....
                    abU[p++] = bits.GetByte();
                    continue;
                }

                if (bits.GetBit() == 0)
                {
                    // 00.....
                    len = bits.GetBit() << 1;
                    len |= bits.GetBit();
                    len += 2;
                    span = bits.GetByte() | ~0xFF;
                }
                else
                {
                    // 01.....

                    span = bits.GetByte();
                    len = bits.GetByte();;
                    span |= ((len & ~0x07)<<5) | ~0x1FFF;
                    len = (len & 0x07) + 2;
                    if (len == 2)
                    {
                        len = bits.GetByte();

                        if (len == 0)
                            break;    // end mark of compressed load module

                        if (len == 1)
                            continue; // segment change
                        else
                            ++len;
                    }
                }
                for( ;len > 0; --len, ++p)
                {
                    abU[p] = abU[p+span];
                }
            }

            // Create a new image based on the uncompressed data.

            this.imgLoaded = new LoadedImage(addrLoad, abU);
            this.imageMap = imgLoaded.CreateImageMap();
            return imgLoaded;
        }
Example #12
0
        private List<ImageSectionDescriptor> LoadImageSectionDescriptors(ushort rvaIsds)
        {
            var sections = new List<ImageSectionDescriptor>();
            var rdr = new LeImageReader(RawImage, rvaIsds);
            Debug.WriteLine("Isd: Size Pges Start    Flags    Rva      GsId     Name");

            for (;;)
            {
                var isd = new ImageSectionDescriptor();
                isd.Size = rdr.ReadLeUInt16();
                if (isd.Size == 0)
                    break;
                isd.NumPages = rdr.ReadLeUInt16();
                isd.StartVPage = rdr.ReadLeUInt32();
                isd.Flags = rdr.ReadLeUInt32();
                if (isd.Size > 0x0C)
                {
                    isd.RvaFile = rdr.ReadLeUInt32();
                    if (isd.Size > 0x010)
                    {
                        isd.GlobalSectionIdent = rdr.ReadLeUInt32();
                        var count = rdr.ReadByte();
                        var sectionName = rdr.ReadBytes(count);
                        isd.SectionName = Encoding.ASCII.GetString(sectionName);
                    }
                }
                sections.Add(isd);
                Debug.WriteLine("{0}", isd);
            }
            return sections;
        }
Example #13
0
        private Header LoadHeader(LeImageReader rdr)
        {
            var header = new Header
            {
                HdrSize = rdr.ReadLeUInt16(),
                RvaTaa = rdr.ReadLeUInt16(),
                RvaSymbols = rdr.ReadLeUInt16(),
                RvaIdent = rdr.ReadLeUInt16(),
                RvaPatchData = rdr.ReadLeUInt16(),
                Spare0A = rdr.ReadLeUInt16(),
                IdMajor = rdr.ReadLeUInt16(),
                IdMinor = rdr.ReadLeUInt16(),

                HeaderBlocks = rdr.ReadByte(),
                ImageType = rdr.ReadByte(),
                Spare12 = rdr.ReadLeUInt16(),

                RequestedPrivilegeMask = rdr.ReadLeUInt64(),
                IoChannels = rdr.ReadLeUInt16(),
                IoSegPages = rdr.ReadLeUInt16(),
                ImageFlags = rdr.ReadLeUInt32(),
                GlobalSectionID = rdr.ReadLeUInt32(),
                SystemVersionNumber = rdr.ReadLeUInt32(),
            };
            return header;
        }
Example #14
0
        /*  DCCLIBS.DAT is a data file sorted on function name containing names and
            return types of functions found in include files, and the names and types
            of arguements. Only functions in this list will be considered library
            functions; others (like LXMUL@) are helper files, and need to be analysed
            by dcc, rather than considered as known functions. When a prototype is
            found (in searchPList()), the parameter info is written to the proc struct.
        */
        void readProtoFile(IServiceProvider services)
        {
            var diagSvc = services.RequireService<IDiagnosticsService>();
            var cfgSvc = services.RequireService<IConfigurationService>();
            var szProFName = cfgSvc.GetInstallationRelativePath("msdos", DCCLIBS); /* Full name of dclibs.lst */
            var fsSvc = services.RequireService<IFileSystemService>();
            if (fsSvc.FileExists(szProFName))
            {
                diagSvc.Warn(string.Format("Cannot open library prototype data file {0}.", szProFName));
                return;
            }
            var bytes = fsSvc.ReadAllBytes(szProFName);
            var fProto = new LeImageReader(bytes);
            int i;

            uint fileSig = fProto.ReadLeUInt32();
            if (fileSig != 0x70636364)      // "dccp"
            {
                diagSvc.Warn(string.Format("{0} is not a dcc prototype file.", szProFName));
                return;
            }

            ushort sectionID = fProto.ReadLeUInt16();
            if (sectionID != 0x4E46)        // "FN"
            {
                Debug.Print("FN (Function) subsection expected in {0}", szProFName);
                diagSvc.Warn(string.Format("{0} is not a dcc prototype file.", szProFName));
                return;
            }
            numFunc = fProto.ReadLeUInt16();    /* Num of entries to allocate */

            /* Allocate exactly correct # entries */
            pFunc = new PH_FUNC_STRUCT[numFunc];

            for (i = 0; i < numFunc; i++)
            {
                var symbuf = fProto.ReadBytes(SYMLEN);
                if (symbuf.Length != SYMLEN)
                    break;
                pFunc[i].typ = (hlType)fProto.ReadLeUInt16();
                pFunc[i].numArg = fProto.ReadLeUInt16();
                pFunc[i].firstArg = fProto.ReadLeUInt16();
                int c = fProto.ReadByte();
                pFunc[i].bVararg = (c != 0); //fread(&pFunc[i].bVararg, 1, 1, fProto);
            }

            sectionID = fProto.ReadLeUInt16();
            if (sectionID != 0x4D50)    // "PM"
            {
                Debug.Print("PM (Parameter) subsection expected in {0}", szProFName);
                return;
            }

            numArg = fProto.ReadLeUInt16();     /* Num of entries to allocate */

            /* Allocate exactly correct # entries */
            pArg = new hlType[numArg];

            for (i = 0; i < numArg; i++)
            {
                //      fread(&pArg[i], 1, SYMLEN, fProto);     /* No names to read as yet */
                pArg[i] = (hlType)fProto.ReadLeUInt16();
            }
        }
Example #15
0
        public bool SetupLibCheck(IServiceProvider services, string fpath, byte[] bytes)
        {
            var diag = services.RequireService<IDiagnosticsService>();
            var rdr = new LeImageReader(bytes);
            ushort w, len;
            int i;

            //readProtoFile();

            /* Read the parameters */
            uint fileSig;
            if (!rdr.TryReadLeUInt32(out fileSig) || fileSig != 0x73636364) // "dccs"
            {
                diag.Warn(string.Format("{0} is not a DCC signature file.", fpath));
                return false;
            }

            numKeys = rdr.ReadLeUInt16();
            numVert = rdr.ReadLeUInt16();
            PatLen = rdr.ReadLeUInt16();
            SymLen = rdr.ReadLeUInt16();
            if ((PatLen != PATLEN) || (SymLen != SYMLEN))
            {
                diag.Warn(string.Format("Can't use signature file with sym and pattern lengths of {0} and {1}.", SymLen, PatLen));
                return false;
            }

            // Initialise the perfhlib stuff. Also allocates T1, T2, g, etc
            // Set the parameters for the hash table
            g_pattern_hasher.setHashParams(
                            numKeys,                // The number of symbols
                            PatLen,                 // The length of the pattern to be hashed
                            256,                    // The character set of the pattern (0-FF)
                            (char)0,                // Minimum pattern character value
                            numVert);               // Specifies c, the sparseness of the graph. See Czech, Havas and Majewski for details
            T1base = g_pattern_hasher.readT1();
            T2base = g_pattern_hasher.readT2();
            g = g_pattern_hasher.readG();

            /* Read T1 and T2 tables */
            ushort ww;
            if (!rdr.TryReadLeUInt16(out ww) || ww != 0x3154)    // "T1"
            {
                Debug.Print("Expected 'T1'");
                diag.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }
            len = (ushort) (PatLen * 256u * 2);        // 2 = sizeof ushort
            w = rdr.ReadLeUInt16();
            if (w != len)
            {
                Debug.Print("Problem with size of T1: file {0}, calc {1}", w, len);
                diag.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }
            readFileSection(T1base, len, rdr);

            if (!rdr.TryReadLeUInt16(out ww) || ww != 0x3254)    // "T2"
            {
                Debug.Print("Expected 'T2'");
                return false;
            }
            w = rdr.ReadLeUInt16();
            if (w != len)
            {
                Debug.Print("Problem with size of T2: file %d, calc %d\n", w, len);
                diag.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }
            readFileSection(T2base, len, rdr);

            /* Now read the function g[] */
            if (!rdr.TryReadLeUInt16(out ww) || ww != 0x6767)    // "gg"
            {
                Debug.Print("Expected 'gg'");
                diag.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }
            len = (ushort) (numVert * 2); //  sizeof(uint16_t));
            w = rdr.ReadLeUInt16();
            if (w != len)
            {
                Debug.Print("Problem with size of g[]: file {0}, calc {1}", w, len);
                diag.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }
            readFileSection(g, len, rdr);

            /* This is now the hash table */
            /* First allocate space for the table */
            ht = new HT[numKeys];
            if (!rdr.TryReadLeUInt16(out ww) || ww != 0x7468)    // "ht"
            {
                Debug.Print("Expected 'ht'");
                diag.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }
            w = rdr.ReadLeUInt16();
            if (w != numKeys * (SymLen + PatLen + 2)) // sizeof(uint16_t)))
            {
                Debug.Print("Problem with size of hash table: file {0}, calc {1}", w, len);
                diag.Warn(string.Format("{0} is not a valid DCCS file.", fpath));
                return false;
            }

            ht = new HT[numKeys];
            for (i = 0; i < numKeys; i++)
            {
                var aSym = rdr.ReadBytes(SymLen)
                    .TakeWhile(b => b != 0).ToArray();

                ht[i] = new HT
                {
                    htSym = Encoding.ASCII.GetString(aSym),
                    htPat = rdr.ReadBytes(PatLen)
                };
            }
            return true;
        }