Пример #1
0
        internal Relocation(RelocationBlock relocBlock, long relocOffset, ushort relocValue)
        {
            block = relocBlock;

            int reloc_type = relocValue >> 12;
            int reloc_offset = relocValue & 0xFFF;

            type = (RelocationType)reloc_type;
            offset = Convert.ToUInt16(reloc_offset);
            value = relocValue;
            computed_rva = block.PageRVA;

            switch (type)
            {
                case RelocationType.Absolute:
                    break;
                case RelocationType.HighLow:
                    computed_rva += offset;
                    break;
                case RelocationType.Dir64:
                    computed_rva += offset;
                    break;      
                case RelocationType.High:
                case RelocationType.Low:
                default:
                    computed_rva = 0;
                    break;
            }

            location = new StreamLocation(relocOffset,size);
        }
Пример #2
0
 internal ImportLookupTableEntry(ImportLookupTable lookupTable, StreamLocation streamLoc, ulong entryAddress, int entryOrdinal)
 {
     table = lookupTable;
     location = streamLoc;
     address = entryAddress;
     ordinal = entryOrdinal;
 }
Пример #3
0
 internal NTHeaders(ExeReader exeReader, StreamLocation streamLoc, FileHeader fileHeader, OptionalHeader optHeader)
 {
     reader = exeReader;
     location = streamLoc;
     file_header = fileHeader;
     opt_header = optHeader;
 }
Пример #4
0
        internal CLRMetaDataHeader(CLRMetaData metaData)
        {
            long offset = metaData.Location.Offset;
            Stream stream = metaData.Content.Section.Sections.Reader.GetStream();

            stream.Seek(offset,SeekOrigin.Begin);

            MetaData = metaData;
            Signature = Utils.ReadUInt32(stream);

            if (Signature != CLR_METADATA_SIGNATURE)
                throw new ExeReaderException("Incorrect signature found in CLR meta-data header.");

            MajorVersion = Utils.ReadUInt16(stream);
            MinorVersion = Utils.ReadUInt16(stream);
            Reserved = Utils.ReadUInt32(stream);
            VersionLength = Utils.ReadUInt32(stream);
            Version = Utils.ReadString(stream,VersionLength);
            Flags = Utils.ReadUInt16(stream);
            Streams = Utils.ReadUInt16(stream);

            long size = stream.Position - offset;

            Location = new StreamLocation(offset,size);
        }
Пример #5
0
        internal CLRContent(DataDirectory dataDirectory, Section section) : base(dataDirectory,section)
        {
            long offset = section.RVAToOffset(dataDirectory.VirtualAddress);

            location = new StreamLocation(offset,dataDirectory.Size);
            header = new CLRHeader(this,dataDirectory);
            meta_data = null;
        }
Пример #6
0
        internal CLRMetaData(CLRContent clrContent)
        {
            long offset = clrContent.Section.RVAToOffset(clrContent.Header.MetaDataAddress);

            content = clrContent;
            location = new StreamLocation(offset,clrContent.Header.MetaDataSize);
            header = null;
            stream_table = null;
            streams = null;
        }
Пример #7
0
        internal CLRHeader(CLRContent clrContent, DataDirectory dataDirectory)
        {
            long offset = clrContent.Section.RVAToOffset(dataDirectory.VirtualAddress);
            Stream stream = clrContent.Section.Sections.Reader.GetStream();

            stream.Seek(offset,SeekOrigin.Begin);

            content = clrContent;
            location = new StreamLocation(offset,size);
            header = Utils.Read<IMAGE_COR20_HEADER>(stream);        
        }
        public void AssignAtomText(ScanStream ScanStream)
        {
            TextLocation wordBx = new StreamLocation(this.Pos).ToTextLocation(ScanStream);
            int          lx     = this.MatchLength;
            TextLocation wordEx =
                new StreamLocation(this.Pos + lx - 1).ToTextLocation(ScanStream);
            string scanText = ScanStream.Stream.Substring(this.Pos, lx);

            this.AtomText = new AtomText(
                this.MatchPattern.DelimClassification.ToScanAtomCode().Value,
                scanText, this.MatchPattern.ReplacementValue,
                wordBx, wordEx,
                this.MatchPattern.UserCode);
        }
Пример #9
0
        private static Tuple <TextLocation, TextWord> IsolateWordText(
            ScanStream ScanStream,
            TextTraits Traits,
            LiteralType?LiteralType,
            string LitText,
            int Bx, int?NonWordBx)
        {
            TextLocation wordBx   = null;
            TextWord     wordPart = null;

            // not a literal. A word that runs from Bx to immed before NonWordBx.
            if (LiteralType == null)
            {
                wordBx = new StreamLocation(Bx).ToTextLocation(ScanStream);
                int lx;
                if (NonWordBx == null)
                {
                    lx = ScanStream.Stream.Length - Bx;
                }
                else
                {
                    lx = NonWordBx.Value - Bx;
                }
                wordPart = new TextWord(
                    ScanStream.Substring(Bx, lx), WordClassification.Identifier, Traits);
            }

            // a quoted or numeric literal
            else
            {
                wordBx   = new StreamLocation(Bx).ToTextLocation(ScanStream);
                wordPart = new TextWord(LitText, LiteralType.Value, Traits);
            }

            return(new Tuple <TextLocation, TextWord>(wordBx, wordPart));
        }
Пример #10
0
 internal TLSContent(DataDirectory dataDirectory, Section section) : base(dataDirectory,section)
 {
     long offset = section.RVAToOffset(dataDirectory.VirtualAddress);
     location = new StreamLocation(offset,dataDirectory.Size);
 }
Пример #11
0
 internal FileHeader(ExeReader exeReader, IMAGE_FILE_HEADER fileHeader, StreamLocation streamLoc)
 {
     reader = exeReader;
     header = fileHeader;
     location = streamLoc;
 }
Пример #12
0
 internal DOSStub(ExeReader exeReader, StreamLocation streamLoc)
 {
     reader = exeReader;
     location = streamLoc;
 }
Пример #13
0
        private FileHeader LoadFileHeader(DOSHeader dosHeader)
        {
            IMAGE_FILE_HEADER native_file_header = Utils.Read<IMAGE_FILE_HEADER>(_stream,FileHeader.Size);
            StreamLocation location = new StreamLocation(dosHeader.FileAddressNewHeader + 4,FileHeader.Size);

            return new FileHeader(this,native_file_header,location);
        }
Пример #14
0
        // ------------------------ ScanNextAtom -------------------------
        // Scans to the next atom in the string. ( a word being the text bounded by the
        // delimeter and whitespace characters as spcfd in the TextTraits argument )
        // Return null when end of string.
        public static ScanAtomCursor ScanNextAtom(
            ScanStream ScanStream,
            TextTraits Traits, ScanAtomCursor CurrentWord)
        {
            // components of the next word.
            TextLocation wordBx    = null;
            int          nonWordIx = -1;
            int          nonWordLx = 0;

            ScanPattern             nonWordPat     = null;
            List <MatchScanPattern> nonWordPatList = null;
            AtomText atomText = null;
            List <MatchScanPattern> atomTextList = null;
            AtomText whitespaceText = null;
//      ScanAtomCode? priorCode = null;
            bool?priorCodeIsWhitespaceSignificant = null;

            // stay at the current location. return copy of the cursor, but with stayatflag
            // turned off.
            if (CurrentWord.StayAtFlag == true)
            {
                atomText   = CurrentWord.AtomText;
                nonWordPat = CurrentWord.AtomPattern;
                wordBx     = CurrentWord.StartLoc;
            }

            else
            {
                #region STEP1 setup the begin pos of the next word.
                // ----------------------------- STEP 1 ------------------------------
                // setup the begin pos of the next word.
                int bx;
                {
                    // save the ScanAtomCode of the prior word.
                    if ((CurrentWord.Position == RelativePosition.At) ||
                        (CurrentWord.Position == RelativePosition.After))
                    {
                        priorCodeIsWhitespaceSignificant = CurrentWord.WhitespaceIsSignificant;
//            priorCode = CurrentWord.AtomText.AtomCode;
                    }

                    // calc scan start position
                    bx = ScanAtom.CalcScanNextStart(ScanStream, Traits, CurrentWord);

                    // advance past whitespace
                    if (bx != -1)
                    {
                        int saveBx = bx;
                        bx = Scanner.ScanNotEqual(ScanStream.Stream, Traits.WhitespacePatterns, bx);

                        // there is some whitespace. depending on what preceeds and follows, may
                        // return this as the atom.
                        if ((priorCodeIsWhitespaceSignificant != null) &&
                            (priorCodeIsWhitespaceSignificant.Value == true))
                        {
                            if (bx != saveBx)
                            {
                                int whitespaceEx = -1;
                                if (bx == -1)
                                {
                                    whitespaceEx = ScanStream.Stream.Length - 1;
                                }
                                else
                                {
                                    whitespaceEx = bx - 1;
                                }
                                int whitespaceLx = whitespaceEx - saveBx + 1;

                                whitespaceText = new AtomText(
                                    ScanAtomCode.Whitespace,
                                    ScanStream.Stream.Substring(saveBx, whitespaceLx), " ",
                                    new StreamLocation(saveBx).ToTextLocation(ScanStream),
                                    new StreamLocation(whitespaceEx).ToTextLocation(ScanStream));
                            }
                        }
                    }
                }
                // end STEP 1.
                #endregion

                #region STEP 2. Isolate either numeric lib, quoted lit or scan to non word pattern
                // ------------------------------- STEP 2 ----------------------------------
                // Isolate either numeric literal, quoted literal or scan to the next non word
                // pattern.
                LiteralType?litType = null;
                string      litText = null;
                {
                    // got a decimal digit. isolate the numeric literal string.
                    if ((bx != -1) && (Char.IsDigit(ScanStream.Stream[bx]) == true))
                    {
                        var rv = Scanner.IsolateNumericLiteral(ScanStream, Traits, bx);
                        litType    = rv.Item1;
                        litText    = rv.Item2;
                        nonWordPat = rv.Item3; // the non word pattern immed after numeric literal
                        nonWordIx  = rv.Item4; // pos of foundPat
                    }

                    // got something.  now scan forward for the pattern that delimits the word.
                    else if (bx != -1)
                    {
                        {
                            var rv = Scanner.ScanEqualAny(ScanStream.Stream, bx, Traits.DelimPatterns);
                            nonWordPat     = rv.Item1;
                            nonWordIx      = rv.Item2;
                            nonWordLx      = rv.Item3;
                            nonWordPatList = rv.Item4;
                        }

                        // got a quote char. Isolate the quoted string, then find the delim that follows
                        // the quoted string.
                        if ((nonWordPat != null) &&
                            (nonWordPat.DelimClassification == DelimClassification.Quote) &&
                            (nonWordIx == bx))
                        {
                            var rv = Scanner.IsolateQuotedWord(ScanStream, Traits, nonWordIx);
                            litType    = rv.Item1;
                            litText    = rv.Item2;
                            nonWordPat = rv.Item3; // the non word pattern immed after quoted literal
                            nonWordIx  = rv.Item4; // pos of foundPat.
                        }
                    }
                }
                // end STEP 2.
                #endregion

                #region STEP 3 - setup wordBx and wordPart with the found word.
                {
                    // got nothing.
                    if (bx == -1)
                    {
                    }

                    // no delim found. word text all the way to the end.
                    else if (nonWordIx == -1)
                    {
                        if (whitespaceText != null)
                        {
                            atomText       = whitespaceText;
                            nonWordPat     = null;
                            nonWordPatList = null;
                        }

                        else
                        {
                            var rv = Scanner.IsolateWordText(
                                ScanStream, Traits, litType, litText, bx, null);
                            atomText = rv.Item3;
                            wordBx   = atomText.StartLoc;
                        }
                    }

                    // got a word and a non word pattern.
                    else if (nonWordIx > bx)
                    {
                        if (whitespaceText != null)
                        {
                            atomText       = whitespaceText;
                            nonWordPat     = null;
                            nonWordPatList = null;
                        }

                        else
                        {
                            var rv = Scanner.IsolateWordText(
                                ScanStream, Traits, litType, litText, bx, nonWordIx);
                            atomText = rv.Item3;
                            wordBx   = atomText.StartLoc;
                        }
                    }

                    // no word. just delim.
                    else
                    {
                        // the delim is comment to end. store as a word.
                        if (nonWordPat.DelimClassification == DelimClassification.CommentToEnd)
                        {
                            var rv     = Scanner.ScanEqualAny(ScanStream.Stream, bx, Traits.NewLinePatterns);
                            var eolPat = rv.Item1;
                            var eolIx  = rv.Item2;
                            if (eolPat == null)
                            {
                                int ex = ScanStream.Stream.Length - 1;
                                wordBx = new StreamLocation(nonWordIx).ToTextLocation(ScanStream);
                                TextLocation wordEx      = new StreamLocation(ex).ToTextLocation(ScanStream);
                                string       commentText = ScanStream.Substring(nonWordIx);

                                atomText = new AtomText(
                                    ScanAtomCode.CommentToEnd, commentText, null, wordBx, wordEx);

                                nonWordPat     = null;
                                nonWordPatList = null;
                            }
                            else
                            {
                                wordBx = new StreamLocation(nonWordIx).ToTextLocation(ScanStream);
                                int          lx     = eolIx - nonWordIx;
                                TextLocation wordEx =
                                    new StreamLocation(nonWordIx + lx - 1).ToTextLocation(ScanStream);
                                string commentText = ScanStream.Substring(nonWordIx, lx);
                                atomText = new AtomText(
                                    ScanAtomCode.CommentToEnd, commentText, null, wordBx, wordEx);
                                var sloc = wordBx.ToStreamLocation(ScanStream);

                                nonWordPat     = eolPat;
                                nonWordPatList = null;
                            }
                        }

                        // the word found is a non word or keyword pattern.
                        else
                        {
                            // got whitespace followed by keyword. Return the whitespace.
                            if ((nonWordPat.DelimClassification == DelimClassification.Keyword) &&
                                (whitespaceText != null))
                            {
                                atomText       = whitespaceText;
                                nonWordPat     = null;
                                nonWordPatList = null;
                            }

                            // there are more than one scan patterns that match.
                            else if (nonWordPatList != null)
                            {
                                atomTextList = new List <MatchScanPattern>();
                                foreach (var pat in nonWordPatList)
                                {
                                    wordBx = new StreamLocation(nonWordIx).ToTextLocation(ScanStream);
                                    int          lx     = pat.MatchLength;
                                    TextLocation wordEx =
                                        new StreamLocation(nonWordIx + lx - 1).ToTextLocation(ScanStream);
                                    string scanText = ScanStream.Stream.Substring(nonWordIx, lx);

                                    atomText = new AtomText(
                                        pat.MatchPattern.DelimClassification.ToScanAtomCode().Value,
                                        scanText,
                                        pat.MatchPattern.ReplacementValue,
                                        wordBx, wordEx);

                                    pat.AtomText = atomText;
                                    atomTextList.Add(pat);
                                }
                            }

                            else
                            {
                                wordBx = new StreamLocation(nonWordIx).ToTextLocation(ScanStream);
                                int          lx     = nonWordLx;
                                TextLocation wordEx =
                                    new StreamLocation(nonWordIx + lx - 1).ToTextLocation(ScanStream);
                                string scanText = ScanStream.Stream.Substring(nonWordIx, lx);

                                atomText = new AtomText(
                                    nonWordPat.DelimClassification.ToScanAtomCode().Value,
                                    scanText, nonWordPat.ReplacementValue,
                                    wordBx, wordEx);
                            }
                        }
                    }
                }
                #endregion
            }

            // store the results in the return cursor.
            ScanAtomCursor nx = null;
            if (atomText == null)
            {
                nx          = new ScanAtomCursor( );
                nx.Position = RelativePosition.End;
            }
            else if (atomTextList != null)
            {
                nx = new ScanAtomCursor(atomTextList);
            }
            else
            {
                nx          = new ScanAtomCursor(atomText, nonWordPat);
                nx.Position = RelativePosition.At;
            }

            return(nx);
        }
Пример #15
0
 internal DebugDirectory(DebugContent debugContent, long directoryOffset, IMAGE_DEBUG_DIRECTORY debugDirectory)
 {
     content = debugContent;
     location = new StreamLocation(directoryOffset,DebugDirectory.Size);
     directory = debugDirectory;
 }
Пример #16
0
        internal OptionalHeader64(ExeReader exeReader, IMAGE_OPTIONAL_HEADER64 optHeader, StreamLocation streamLoc) : base(exeReader,streamLoc)
        {
            header = optHeader;

            List<DataDirectory> dirs = new List<DataDirectory>();

            dirs.AddRange(new DataDirectory[] {
                new DataDirectory(DataDirectoryType.ExportTable,header.ExportTable),
                new DataDirectory(DataDirectoryType.ImportTable,header.ImportTable),
                new DataDirectory(DataDirectoryType.ResourceTable,header.ResourceTable),
                new DataDirectory(DataDirectoryType.ExceptionTable,header.ExceptionTable),
                new DataDirectory(DataDirectoryType.CertificateTable,header.CertificateTable),
                new DataDirectory(DataDirectoryType.BaseRelocationTable,header.BaseRelocationTable),
                new DataDirectory(DataDirectoryType.Debug,header.Debug),
                new DataDirectory(DataDirectoryType.Architecture,header.Architecture),
                new DataDirectory(DataDirectoryType.GlobalPtr,header.GlobalPtr),
                new DataDirectory(DataDirectoryType.TLSTable,header.TLSTable),
                new DataDirectory(DataDirectoryType.LoadConfigTable,header.LoadConfigTable),
                new DataDirectory(DataDirectoryType.BoundImport,header.BoundImport),
                new DataDirectory(DataDirectoryType.ImportAddressTable,header.IAT),
                new DataDirectory(DataDirectoryType.DelayImportDescriptor,header.DelayImportDescriptor),
                new DataDirectory(DataDirectoryType.CLRRuntimeHeader,header.CLRRuntimeHeader)
            });

            long dir_size = 16 * DataDirectories.EntrySize;
            StreamLocation location = new StreamLocation((streamLoc.Offset + streamLoc.Size) - dir_size,dir_size);

            data_dirs = new DataDirectories(this,location,dirs.Where(dir => dir.DirectoryType != DataDirectoryType.None).ToDictionary(dir => dir.DirectoryType));
        }
Пример #17
0
        private void LoadDOSStub()
        {
            if (_dos_header == null)
                LoadDOSHeader();

            long offset = _dos_header.Location.Offset + _dos_header.Location.Size;
            int size = _dos_header.FileAddressNewHeader - DOSHeader.Size;

            if ((offset + size) > _stream.Length)
                throw new ExeReaderException("Cannot read beyond end of stream.");

            StreamLocation location = new StreamLocation(offset,size);

            _dos_stub = new DOSStub(this,location);
        }
Пример #18
0
 internal TLSDirectory32(TLSContent tlsContent, long directoryOffset, IMAGE_TLS_DIRECTORY32 tlsDirectory) : base(tlsContent)
 {
     location = new StreamLocation(directoryOffset,TLSDirectory.Size32);
     directory = tlsDirectory;
 }
Пример #19
0
 internal ExportDirectory(ExportContent exportContent, IMAGE_EXPORT_DIRECTORY exportDir, StreamLocation streamLoc)
 {
     content = exportContent;
     directory = exportDir;
     location = streamLoc;
 }
Пример #20
0
        // ------------------------ ScanNextWord -------------------------
        // Scans to the next word in the string. ( a word being the text bounded by the
        // delimeter and whitespace characters as spcfd in the TextTraits argument )
        // Return null when end of string.
        public static ScanWordCursor ScanNextWord(
            ScanStream ScanStream,
            TextTraits Traits, ScanWordCursor CurrentWord)
        {
            // components of the next word.
            TextWord     wordPart   = null;
            TextLocation wordBx     = null;
            ScanPattern  nonWordPat = null;
            TextLocation nonWordLoc = null;
            int          nonWordIx  = -1;

            // stay at the current location. return copy of the cursor, but with stayatflag
            // turned off.
            if (CurrentWord.StayAtFlag == true)
            {
                nonWordPat = CurrentWord.DelimPattern;
                nonWordLoc = CurrentWord.DelimBx;
                wordPart   = CurrentWord.Word;
                wordBx     = CurrentWord.WordBx;
            }

            else
            {
                #region STEP1 setup the begin pos of the next word.
                // ----------------------------- STEP 1 ------------------------------
                // setup the begin pos of the next word.
                int bx;
                {
                    // calc scan start position
                    bx = ScanWord.CalcScanNextStart(ScanStream, Traits, CurrentWord);

                    // advance past whitespace
                    if (bx != -1)
                    {
                        bx = Scanner.ScanNotEqual(ScanStream.Stream, Traits.WhitespacePatterns, bx);
                    }
                }
                // end STEP 1.
                #endregion

                #region STEP 2. Isolate either numeric lib, quoted lit or scan to non word pattern
                // ------------------------------- STEP 2 ----------------------------------
                // Isolate either numeric literal, quoted literal or scan to the next non word
                // pattern.
                LiteralType?litType = null;
                string      litText = null;
                {
                    // got a decimal digit. isolate the numeric literal string.
                    if ((bx != -1) && (Char.IsDigit(ScanStream.Stream[bx]) == true))
                    {
                        var rv = ScanWord.IsolateNumericLiteral(ScanStream, Traits, bx);
                        litType    = rv.Item1;
                        litText    = rv.Item2;
                        nonWordPat = rv.Item3; // the non word pattern immed after numeric literal
                        nonWordIx  = rv.Item4; // pos of foundPat
                    }

                    // got something.  now scan forward for the pattern that delimits the word.
                    else if (bx != -1)
                    {
                        {
                            var rv = Scanner.ScanEqualAny(ScanStream.Stream, bx, Traits.DelimPatterns);
                            nonWordPat = rv.Item1;
                            nonWordIx  = rv.Item2;
                        }

                        // got a quote char. Isolate the quoted string, then find the delim that follows
                        // the quoted string.
                        if ((nonWordPat != null) &&
                            (nonWordPat.DelimClassification == DelimClassification.Quote) &&
                            (nonWordIx == bx))
                        {
                            var rv = IsolateQuotedWord(ScanStream, Traits, nonWordIx);
                            litType    = rv.Item1;
                            litText    = rv.Item2;
                            nonWordPat = rv.Item3; // the non word pattern immed after quoted literal
                            nonWordIx  = rv.Item4; // pos of foundPat.
                        }
                    }
                }
                // end STEP 2.
                #endregion

                #region STEP 3 - setup wordBx and wordPart with the found word.
                {
                    // got nothing.
                    if (bx == -1)
                    {
                    }

                    // no delim found. word text all the way to the end.
                    else if (nonWordIx == -1)
                    {
                        var rv = ScanWord.IsolateWordText(
                            ScanStream, Traits, litType, litText, bx, null);
                        wordBx   = rv.Item1;
                        wordPart = rv.Item2;

#if skip
                        wordBx = new StreamLocation(bx).ToTextLocation(ScanStream);
                        if (litType != null)
                        {
                            wordPart = new TextWord(litText, WordClassification.Quoted, Traits);
                        }
                        else
                        {
                            wordPart = new TextWord(
                                ScanStream.Substring(bx), WordClassification.Identifier, Traits);
                        }
#endif
                    }

                    // got a word and a non word pattern.
                    else if (nonWordIx > bx)
                    {
                        var rv = ScanWord.IsolateWordText(
                            ScanStream, Traits, litType, litText, bx, nonWordIx);
                        wordBx   = rv.Item1;
                        wordPart = rv.Item2;

#if skip
                        wordBx = new StreamLocation(bx).ToTextLocation(ScanStream);
                        int lx = foundIx - bx;
                        wordPart = new TextWord(
                            ScanStream.Substring(bx, lx), WordClassification.Identifier, Traits);
#endif

                        nonWordLoc = new StreamLocation(nonWordIx).ToTextLocation(ScanStream);
                    }

                    // no word. just delim.
                    else
                    {
                        nonWordLoc = new StreamLocation(nonWordIx).ToTextLocation(ScanStream);

                        // the delim is comment to end. store as a word.
                        if (nonWordPat.DelimClassification == DelimClassification.CommentToEnd)
                        {
                            var rv     = Scanner.ScanEqualAny(ScanStream.Stream, bx, Traits.NewLinePatterns);
                            var eolPat = rv.Item1;
                            var eolIx  = rv.Item2;
                            if (eolPat == null)
                            {
                                wordBx   = new StreamLocation(nonWordIx).ToTextLocation(ScanStream);
                                wordPart = new TextWord(
                                    ScanStream.Substring(nonWordIx), WordClassification.CommentToEnd, Traits);
                                nonWordLoc = null;
                                nonWordPat = null;
                            }
                            else
                            {
                                wordBx = new StreamLocation(nonWordIx).ToTextLocation(ScanStream);
                                int lx   = eolIx - nonWordIx;
                                var sloc = wordBx.ToStreamLocation(ScanStream);
                                wordPart = new TextWord(
                                    ScanStream.Substring(sloc.Value, lx), WordClassification.CommentToEnd, Traits);
                                nonWordLoc = new StreamLocation(eolIx).ToTextLocation(ScanStream);
                                nonWordPat = eolPat;
                            }
                        }

                        // if the delim pattern is not non word ( a divider ), store the pattern also
                        // as the word.
                        else if (Traits.DelimPatternsThatAreNonWords.Contains(nonWordPat) == false)
                        {
                            wordBx   = nonWordLoc;
                            wordPart = new TextWord(
                                nonWordPat.PatternValue,
                                nonWordPat.DelimClassification.ToWordClassification().Value,
                                Traits);
                        }
                    }
                }
                #endregion

                // delim is whitespace. scan ahead for something more meaningful than whitespace.
                if ((nonWordPat != null) && (Traits.IsWhitespace(nonWordPat)))
                {
                    StreamLocation dx = nonWordLoc.ToStreamLocation(ScanStream);
                    int            fx = Scanner.ScanNotEqual(
                        ScanStream.Stream, Traits.WhitespacePatterns, dx.Value + nonWordPat.Length);
                    var pat = Traits.DelimPatterns.MatchAt(ScanStream.Stream, fx);
                    if (pat != null)
                    {
                        nonWordLoc = new StreamLocation(fx).ToTextLocation(ScanStream);
                        nonWordPat = pat;
                    }
                }
            }

            // store the results in the return cursor.
            ScanWordCursor nx = null;
            if ((wordPart == null) && (nonWordPat == null))
            {
                nx          = new ScanWordCursor( );
                nx.Position = RelativePosition.End;
            }
            else
            {
                nx          = new ScanWordCursor(wordPart, wordBx, nonWordLoc, nonWordPat);
                nx.Position = RelativePosition.At;
            }

            return(nx);
        }
Пример #21
0
        private void LoadSectionTable()
        {
            if (_nt_headers == null)
                LoadNTHeaders();

            long offset = _nt_headers.Location.Offset + _nt_headers.Location.Size;

            _stream.Seek(offset,SeekOrigin.Begin);

            List<IMAGE_SECTION_HEADER> headers = new List<IMAGE_SECTION_HEADER>();

            for(var i = 0; i < _nt_headers.FileHeader.NumberOfSections; i++)
            {
                IMAGE_SECTION_HEADER header = Utils.Read<IMAGE_SECTION_HEADER>(_stream,SectionTableEntry.Size);

                headers.Add(header);
            }

            long size = headers.Count * SectionTableEntry.Size;
            StreamLocation location = new StreamLocation(offset,size);

            _section_table = new SectionTable(this,location,headers);
        }
Пример #22
0
        private OptionalHeader LoadOptionalHeader(FileHeader fileHeader)
        {
            CharacteristicsType characteristics = fileHeader.GetCharacteristics();
            bool is_x64 = !((characteristics & CharacteristicsType.Supports32Bit) == CharacteristicsType.Supports32Bit);
            IMAGE_OPTIONAL_HEADER32 opt_header_32 = new IMAGE_OPTIONAL_HEADER32();
            IMAGE_OPTIONAL_HEADER64 opt_header_64 = new IMAGE_OPTIONAL_HEADER64();
            StreamLocation location = null;
            OptionalHeader opt_header = null;

            if (!is_x64)
            {
                opt_header_32 = Utils.Read<IMAGE_OPTIONAL_HEADER32>(_stream,OptionalHeader.Size32);
                location = new StreamLocation(fileHeader.Location.Offset + fileHeader.Location.Size,OptionalHeader.Size32);
                opt_header = new OptionalHeader32(this,opt_header_32,location);
            }
            else
            {
                opt_header_64 = Utils.Read<IMAGE_OPTIONAL_HEADER64>(_stream,OptionalHeader.Size64);
                location = new StreamLocation(fileHeader.Location.Offset + fileHeader.Location.Size,OptionalHeader.Size64);
                opt_header = new OptionalHeader64(this,opt_header_64,location);
            }

            return opt_header;
        }
Пример #23
0
 internal LoadConfigDirectory64(LoadConfigContent lcContent, long directoryOffset, IMAGE_LOAD_CONFIG_DIRECTORY64 lcDirectory) : base(lcContent)
 {
     location = new StreamLocation(directoryOffset,LoadConfigDirectory.Size64);
     directory = lcDirectory;
 }
Пример #24
0
        // ------------------------ ScanNextAtom -------------------------
        // Scans to the next atom in the string. ( a word being the text bounded by the
        // delimiter and whitespace characters as spcfd in the TextTraits argument )
        // Return null when end of string.
        public static ScanAtomCursor OrigScanNextAtom(
            ScanStream ScanStream,
            TextTraits Traits, ScanAtomCursor CurrentWord)
        {
            // components of the next word.
            TextLocation wordBx    = null;
            int          nonWordIx = -1;
            int          nonWordLx = 0;

            ScanPattern        nonWordPat = null;
            PatternScanResults nonWord    = null;

            AtomText atomText = null;
            List <MatchScanPattern> atomTextList = null;
            AtomText whitespaceText = null;

            ScanAtomCode?tokenCode      = null; // ScanAtomCode of this token.
            int?         tokenLx        = null;
            ScanAtomCode?priorTokenCode = null;

            //      ScanAtomCode? priorCode = null;
            bool?priorCodeIsWhitespaceSignificant = null;

            // stay at the current location. return copy of the cursor, but with stayatflag
            // turned off.
            if (CurrentWord.StayAtFlag == true)
            {
                atomText       = CurrentWord.AtomText;
                tokenCode      = atomText.AtomCode;
                priorTokenCode = null;
                nonWordPat     = CurrentWord.AtomPattern;
                wordBx         = CurrentWord.StartLoc;
            }

            else
            {
                #region STEP1 setup the begin pos of the next word.
                // ----------------------------- STEP 1 ------------------------------
                // setup the begin pos of the next word.
                int bx;
                {
                    // save the ScanAtomCode of the prior word.
                    if ((CurrentWord.Position == RelativePosition.At) ||
                        (CurrentWord.Position == RelativePosition.After))
                    {
                        priorTokenCode = CurrentWord.AtomCode;
                        priorCodeIsWhitespaceSignificant = CurrentWord.WhitespaceIsSignificant;
                    }

                    // calc scan start position
                    bx = ScanAtom.CalcScanNextStart(ScanStream, Traits, CurrentWord);

                    // advance past whitespace
                    if (bx != -1)
                    {
                        int saveBx = bx;
                        bx = Scanner.ScanNotEqual(ScanStream.Stream, Traits.WhitespacePatterns, bx);

                        // there is some whitespace. Isolate it as AtomText.
                        // This method will return the whitespace as the token. But need to look at
                        // the token before and after to classify the whitespace as significant or
                        // not. ( whitespace between identifiers or keywords is significant.
                        // Whitespace between symbols is not significant.
                        // note: even insignificant whitespace is returned as a token because the
                        //       whitespace is needed when redisplaying the statement text.
                        if (bx != saveBx)
                        {
                            int whitespaceEx = -1;
                            if (bx == -1)
                            {
                                whitespaceEx = ScanStream.Stream.Length - 1;
                            }
                            else
                            {
                                whitespaceEx = bx - 1;
                            }
                            int whitespaceLx = whitespaceEx - saveBx + 1;

                            string userCode = null;
                            whitespaceText = new AtomText(
                                ScanAtomCode.Whitespace,
                                ScanStream.Stream.Substring(saveBx, whitespaceLx), " ",
                                new StreamLocation(saveBx).ToTextLocation(ScanStream),
                                new StreamLocation(whitespaceEx).ToTextLocation(ScanStream),
                                userCode);
                        }
                    }
                }
                // end STEP 1.
                #endregion

                #region STEP 2. Isolate either numeric lit, quoted lit or identifier/keyword.
                // ------------------------------- STEP 2 ----------------------------------
                // Isolate either numeric literal, quoted literal or scan to the next non word
                // pattern.
                LiteralType?litType = null;
                string      litText = null;
                {
                    // got a decimal digit. isolate the numeric literal string.
                    if ((bx != -1) && (Char.IsDigit(ScanStream.Stream[bx]) == true))
                    {
                        var rv = Scanner.IsolateNumericLiteral(ScanStream, Traits, bx);
                        litType = rv.Item1;
                        litText = rv.Item2;
                        nonWord = rv.Item3;
//            nonWordPat = rv.Item4;  // the non word pattern immed after numeric literal
//            nonWordIx = rv.Item5;   // pos of foundPat
                        tokenCode = ScanAtomCode.Numeric;
                    }

                    // got something.  now scan forward for the pattern that delimits the word.
                    else if (bx != -1)
                    {
                        {
                            nonWord = Scanner.ScanEqualAny(ScanStream.Stream, bx, Traits.DelimPatterns);
//              nonWordPat = rv.Item1;
//              nonWordIx = rv.Item2;
//              nonWordLx = rv.Item3;
//              nonWord = rv.Item3;
                        }

                        // a special value starter. scan further for the spcval word.
                        var startPat = nonWord.FindPattern(DelimClassification.SpecialValueStarter);
                        if (startPat != null)
                        {
                        }

                        // word chars all the way to the end.
                        //            if (nonWordPat == null)
                        if (nonWord == null)
                        {
                            tokenCode = ScanAtomCode.Identifier;
                            tokenLx   = ScanStream.Stream.Length - bx;
                        }

                        else if (nonWord.FoundAtPosition(DelimClassification.Quote, bx))
                        {
                            var rv = Scanner.IsolateQuotedWord(ScanStream, Traits, bx);
                            litType = rv.Item1;
                            litText = rv.Item2;
//              nonWordPat = rv.Item3;  // the non word pattern immed after quoted literal
//              nonWordIx = rv.Item4;   // pos of foundPat.
                            nonWord   = rv.Item3;
                            tokenCode = ScanAtomCode.Quoted;
                        }

#if skip
                        // got a quote char. Isolate the quoted string, then find the delim that follows
                        // the quoted string.
                        else if ((nonWordPat.DelimClassification == DelimClassification.Quote) &&
                                 (nonWordIx == bx))
                        {
                            var rv = Scanner.IsolateQuotedWord(ScanStream, Traits, nonWordIx);
                            litType    = rv.Item1;
                            litText    = rv.Item2;
                            nonWordPat = rv.Item3; // the non word pattern immed after quoted literal
                            nonWordIx  = rv.Item4; // pos of foundPat.
                            nonWord    = rv.Item5;
                            tokenCode  = ScanAtomCode.Quoted;
                        }
#endif
                        // delim pattern found past the start of the scan. That means there are
                        // identifier chars from the start of the scan to the found delim.
                        else if (bx != nonWord.Position)
                        //            else if (bx != nonWordIx)
                        {
                            tokenCode = ScanAtomCode.Identifier;
                            tokenLx   = nonWord.Position - bx;
                            //              tokenLx = nonWordIx - bx;
                        }

                        else if (nonWordPat != null)
                        {
                            tokenCode = nonWordPat.DelimClassification.ToScanAtomCode();
                        }

                        // should never get here.
                        else
                        {
                            tokenCode = null;
                        }
                    }

                    // attempt to classify the identifier token as a keyword.
                    if ((tokenCode != null) && (tokenCode.Value == ScanAtomCode.Identifier))
                    {
                        var rv = Traits.KeywordPatterns.MatchPatternToSubstring(
                            ScanStream.Stream, bx, tokenLx.Value);
                        var kwdResults = rv.Item3;
                        var kwdPat     = kwdResults.FirstFoundPattern;
                        if (kwdPat != null)
                        {
                            tokenCode  = kwdPat.MatchPattern.DelimClassification.ToScanAtomCode();
                            nonWordPat = kwdPat.MatchPattern;
                            nonWord    = kwdResults;
                            nonWordIx  = bx;
                            nonWordLx  = kwdPat.MatchLength;
                        }

#if skip
                        var matchPat      = rv.Item1;
                        var keywordTextLx = rv.Item2; // the actual lgth of matched text.
                        if (matchPat != null)
                        {
                            tokenCode      = matchPat.DelimClassification.ToScanAtomCode();
                            nonWordPat     = matchPat;
                            nonWordPatList = null;
                            nonWord        = null;
                            nonWordIx      = bx;
                            nonWordLx      = keywordTextLx;
                        }
#endif
                    }
                }
                // end STEP 2.
                #endregion

                #region STEP 3 - setup wordBx and wordPart with the found word.
                {
                    // got whitespace.
                    if (whitespaceText != null)
                    {
                        ScanAtomCode wstc = ScanAtomCode.Whitespace;

                        if (priorTokenCode == null)
                        {
                            wstc = ScanAtomCode.InsignificantWhitespace;
                        }
                        else if (tokenCode == null)
                        {
                            wstc = ScanAtomCode.InsignificantWhitespace;
                        }
                        else if ((priorTokenCode.Value.WhitespaceIsSignificant() == true) &&
                                 (tokenCode.Value.WhitespaceIsSignificant() == true))
                        {
                            wstc = ScanAtomCode.Whitespace;
                        }
                        else
                        {
                            wstc = ScanAtomCode.InsignificantWhitespace;
                        }

                        atomText          = whitespaceText;
                        atomText.AtomCode = wstc;
                    }

                    // got nothing.
                    else if (bx == -1)
                    {
                    }

                    // no delim found. word text all the way to the end.
                    else if (nonWord.IsEmpty == true)
                    //          else if (nonWordIx == -1)
                    {
                        if (whitespaceText != null)
                        {
                            atomText   = whitespaceText;
                            nonWordPat = null;
                        }

                        else
                        {
                            // get the text from start of scan to end of string.
                            var rv = Scanner.IsolateWordText(
                                ScanStream, Traits, litType, litText, bx, null);
                            atomText = rv.Item3;
                            wordBx   = atomText.StartLoc;
                        }
                    }

                    // got a word and a non word pattern.
                    else if (nonWord.Position > bx)
                    //          else if (nonWordIx > bx)
                    {
                        if (whitespaceText != null)
                        {
                            atomText   = whitespaceText;
                            nonWord    = new PatternScanResults();
                            nonWordPat = null;
                        }

                        else
                        {
                            var rv = Scanner.IsolateWordText(
                                ScanStream, Traits, litType, litText, bx, nonWord.Position);
                            //              var rv = Scanner.IsolateWordText(
                            //                ScanStream, Traits, litType, litText, bx, nonWordIx);
                            atomText = rv.Item3;
                            wordBx   = atomText.StartLoc;
                        }
                    }

                    // no word. just delim.
                    else
                    {
                        // the delim is comment to end. store as a word.
                        if (nonWordPat.DelimClassification == DelimClassification.CommentToEnd)
                        {
                            var rv = ScanAtom.ClassifyAsComment(ScanStream, Traits, bx);
                            wordBx     = rv.Item1;
                            atomText   = rv.Item2;
                            nonWordPat = rv.Item3;
                            nonWord    = rv.Item4;
#if skip
                            var rv     = Scanner.ScanEqualAny(ScanStream.Stream, bx, Traits.NewLinePatterns);
                            var eolPat = rv.Item1;
                            var eolIx  = rv.Item2;

                            // no newline pattern found. Comment to the end of the text stream.
                            if (eolPat == null)
                            {
                                int ex = ScanStream.Stream.Length - 1;
                                wordBx = new StreamLocation(nonWordIx).ToTextLocation(ScanStream);
                                TextLocation wordEx      = new StreamLocation(ex).ToTextLocation(ScanStream);
                                string       commentText = ScanStream.Substring(nonWordIx);

                                string userCode = null;
                                atomText = new AtomText(
                                    ScanAtomCode.CommentToEnd, commentText, null, wordBx, wordEx,
                                    userCode);

                                nonWordPat     = null;
                                nonWordPatList = null;
                            }

                            else
                            {
                                wordBx = new StreamLocation(nonWordIx).ToTextLocation(ScanStream);
                                int          lx     = eolIx - nonWordIx;
                                TextLocation wordEx =
                                    new StreamLocation(nonWordIx + lx - 1).ToTextLocation(ScanStream);
                                string commentText = ScanStream.Substring(nonWordIx, lx);
                                string userCode    = null;
                                atomText = new AtomText(
                                    ScanAtomCode.CommentToEnd, commentText, null, wordBx, wordEx,
                                    userCode);
                                var sloc = wordBx.ToStreamLocation(ScanStream);

                                nonWordPat     = eolPat;
                                nonWordPatList = null;
                            }
#endif
                        }

                        // the word found is a non word or keyword pattern.
                        else
                        {
                            // got whitespace followed by keyword. Return the whitespace.
                            if ((nonWordPat.DelimClassification == DelimClassification.Keyword) &&
                                (whitespaceText != null))
                            {
                                atomText   = whitespaceText;
                                nonWord    = new PatternScanResults();
                                nonWordPat = null;
                            }

                            // there are more than one scan patterns that match.
                            else if (nonWord.FoundCount > 1)
                            //              else if (nonWordPatList != null)
                            {
                                atomTextList = new List <MatchScanPattern>();

                                foreach (var pat in nonWord)
                                {
                                    wordBx = new StreamLocation(nonWord.Position).ToTextLocation(ScanStream);
                                    int          lx     = pat.MatchLength;
                                    TextLocation wordEx =
                                        new StreamLocation(nonWord.Position + lx - 1).ToTextLocation(ScanStream);
                                    string scanText = ScanStream.Stream.Substring(nonWord.Position, lx);

                                    atomText = new AtomText(
                                        pat.MatchPattern.DelimClassification.ToScanAtomCode().Value,
                                        scanText,
                                        pat.MatchPattern.ReplacementValue,
                                        wordBx, wordEx,
                                        pat.MatchPattern.UserCode);

                                    pat.AtomText = atomText;
                                    atomTextList.Add(pat);
                                }
#if skip
                                foreach (var pat in nonWordPatList)
                                {
                                    wordBx = new StreamLocation(nonWordIx).ToTextLocation(ScanStream);
                                    int          lx     = pat.MatchLength;
                                    TextLocation wordEx =
                                        new StreamLocation(nonWordIx + lx - 1).ToTextLocation(ScanStream);
                                    string scanText = ScanStream.Stream.Substring(nonWordIx, lx);

                                    atomText = new AtomText(
                                        pat.MatchPattern.DelimClassification.ToScanAtomCode().Value,
                                        scanText,
                                        pat.MatchPattern.ReplacementValue,
                                        wordBx, wordEx,
                                        pat.MatchPattern.UserCode);

                                    pat.AtomText = atomText;
                                    atomTextList.Add(pat);
                                }
#endif
                            }

                            else
                            {
                                var foundPat = nonWord.FirstFoundPattern;
                                wordBx = new StreamLocation(nonWord.Position).ToTextLocation(ScanStream);
                                int          lx     = foundPat.MatchLength;
                                TextLocation wordEx =
                                    new StreamLocation(nonWord.Position + lx - 1).ToTextLocation(ScanStream);
                                string scanText = ScanStream.Stream.Substring(nonWord.Position, lx);

                                atomText = new AtomText(
                                    foundPat.MatchPattern.DelimClassification.ToScanAtomCode().Value,
                                    scanText, foundPat.MatchPattern.ReplacementValue,
                                    wordBx, wordEx,
                                    foundPat.MatchPattern.UserCode);

#if skip
                                wordBx = new StreamLocation(nonWordIx).ToTextLocation(ScanStream);
                                int          lx     = nonWordLx;
                                TextLocation wordEx =
                                    new StreamLocation(nonWordIx + lx - 1).ToTextLocation(ScanStream);
                                string scanText = ScanStream.Stream.Substring(nonWordIx, lx);

                                atomText = new AtomText(
                                    nonWordPat.DelimClassification.ToScanAtomCode().Value,
                                    scanText, nonWordPat.ReplacementValue,
                                    wordBx, wordEx,
                                    nonWordPat.UserCode);
#endif
                            }
                        }
                    }
                }
                #endregion
            }

            // store the results in the return cursor.
            ScanAtomCursor nx = null;
            if (atomText == null)
            {
                nx          = new ScanAtomCursor();
                nx.Position = RelativePosition.End;
            }
            else if (atomTextList != null)
            {
                nx = new ScanAtomCursor(atomTextList);
            }
            else
            {
                //        nx = new ScanAtomCursor(atomText, nonWordPat);
                if ((nonWord == null) || (nonWord.IsEmpty == true))
                {
                    nx = new ScanAtomCursor(atomText, nonWordPat);
                }
                else
                {
                    nx = new ScanAtomCursor(atomText, nonWord.FirstFoundPattern.MatchPattern);
                }
                nx.Position = RelativePosition.At;
            }

            return(nx);
        }
Пример #25
0
 internal DOSHeader(ExeReader exeReader, IMAGE_DOS_HEADER dosHeader, StreamLocation streamLoc)
 {
     reader = exeReader;
     header = dosHeader;
     location = streamLoc;
 }
Пример #26
0
        private void LoadDOSHeader()
        {
            _stream.Seek(0,SeekOrigin.Begin);

            IMAGE_DOS_HEADER native_dos_header = Utils.Read<IMAGE_DOS_HEADER>(_stream,DOSHeader.Size);

            if (native_dos_header.e_magic != DOSHeader.DOS_MAGIC_MZ)
                throw new ExeReaderException("Incorrect magic number specified in MS-DOS header.");

            if (native_dos_header.e_lfanew == 0)
                throw new ExeReaderException("No new header location specified in MS-DOS header, most likely a 16-bit executable.");

            if (native_dos_header.e_lfanew >= (256 * (1024 * 1024)))
                throw new ExeReaderException("New header location specified in MS-DOS header is beyond 256mb boundary (see RtlImageNtHeaderEx).");

            if (native_dos_header.e_lfanew % 4 != 0)
                throw new ExeReaderException("New header location specified in MS-DOS header is not properly aligned.");

            if (native_dos_header.e_lfanew < DOSHeader.Size)
                throw new ExeReaderException("New header location specified is invalid.");

            StreamLocation location = new StreamLocation(0,DOSHeader.Size);

            _dos_header = new DOSHeader(this,native_dos_header,location);
        }
        private async Task OpenInputStreamAsync()
        {
            Debug.Assert(
                State.OpenInputStream == this.state,
                "OpenInputStreamAsync called, but state is not OpenInputStream.");

            this.hasWork = false;

            await Task.Run(() =>
            {
                this.NotifyStarting();
                this.Controller.CheckCancellation();

                if (this.transferJob.Source.Type == TransferLocationType.Stream)
                {
                    StreamLocation streamLocation = this.transferJob.Source as StreamLocation;
                    this.inputStream = streamLocation.Stream;
                    this.ownsStream  = false;

                    if (!this.inputStream.CanRead)
                    {
                        throw new NotSupportedException(string.Format(
                                                            CultureInfo.CurrentCulture,
                                                            Resources.StreamMustSupportReadException,
                                                            "inputStream"));
                    }

                    if (!this.inputStream.CanSeek)
                    {
                        throw new NotSupportedException(string.Format(
                                                            CultureInfo.CurrentCulture,
                                                            Resources.StreamMustSupportSeekException,
                                                            "inputStream"));
                    }
                }
                else
                {
                    FileLocation fileLocation = this.transferJob.Source as FileLocation;
                    Debug.Assert(
                        null != fileLocation,
                        "Initializing StreamedReader instance, but source is neither a stream nor a file");

                    try
                    {
                        if (fileLocation.RelativePath != null &&
                            fileLocation.RelativePath.Length > Constants.MaxRelativePathLength)
                        {
                            string errorMessage = string.Format(
                                CultureInfo.CurrentCulture,
                                Resources.RelativePathTooLong,
                                fileLocation.RelativePath);
                            throw  new TransferException(TransferErrorCode.OpenFileFailed, errorMessage);
                        }
#if DOTNET5_4
                        string filePath = fileLocation.FilePath;
                        if (Interop.CrossPlatformHelpers.IsWindows)
                        {
                            filePath = LongPath.ToUncPath(fileLocation.FilePath);
                        }
                        // Attempt to open the file first so that we throw an exception before getting into the async work
                        this.inputStream = new FileStream(
                            filePath,
                            FileMode.Open,
                            FileAccess.Read,
                            FileShare.Read);
#else
                        this.inputStream = LongPathFile.Open(
                            fileLocation.FilePath,
                            FileMode.Open,
                            FileAccess.Read,
                            FileShare.Read);
#endif
                        this.ownsStream = true;
                    }
                    catch (Exception ex)
                    {
                        if ((ex is NotSupportedException) ||
                            (ex is IOException) ||
                            (ex is UnauthorizedAccessException) ||
                            (ex is SecurityException) ||
                            (ex is ArgumentException && !(ex is ArgumentNullException)))
                        {
                            string exceptionMessage = string.Format(
                                CultureInfo.CurrentCulture,
                                Resources.FailedToOpenFileException,
                                fileLocation.FilePath,
                                ex.Message);

                            throw new TransferException(
                                TransferErrorCode.OpenFileFailed,
                                exceptionMessage,
                                ex);
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
            });

            this.SharedTransferData.TotalLength = this.inputStream.Length;

            int count = (int)Math.Ceiling((double)(this.SharedTransferData.TotalLength - this.transferJob.CheckPoint.EntryTransferOffset) / this.SharedTransferData.BlockSize);

            if (null != this.transferJob.CheckPoint.TransferWindow)
            {
                count += this.transferJob.CheckPoint.TransferWindow.Count;
            }

            this.lastTransferWindow = new Queue <long>(this.transferJob.CheckPoint.TransferWindow);

            this.md5HashStream = new MD5HashStream(
                this.inputStream,
                this.transferJob.CheckPoint.EntryTransferOffset,
                true);

            this.PreProcessed = true;

            // This reader will come into 'Finish' state after all chunks are read and MD5 calculation completes.
            // So initialize the CountDownEvent to count (number of chunks to read) + 1 (md5 calculation).
            this.countdownEvent = new CountdownEvent(count + 1);

            if (0 != count)
            {
                // Change the state to 'ReadStream' before awaiting MD5 calculation task to not block the reader.
                this.state   = State.ReadStream;
                this.hasWork = true;
            }

            if (!this.md5HashStream.FinishedSeparateMd5Calculator)
            {
                await Task.Run(() =>
                {
                    this.md5HashStream.CalculateMd5(this.Scheduler.MemoryManager, this.Controller.CheckCancellation);
                });
            }

            this.SetChunkFinish();
        }
Пример #28
0
        private async Task OpenInputStreamAsync()
        {
            Debug.Assert(
                State.OpenInputStream == this.state,
                "OpenInputStreamAsync called, but state is not OpenInputStream.");

            this.hasWork = false;

            await Task.Run(() =>
            {
                this.NotifyStarting();
                this.Controller.CheckCancellation();

                if (this.transferJob.Source.Type == TransferLocationType.Stream)
                {
                    StreamLocation streamLocation = this.transferJob.Source as StreamLocation;
                    this.inputStream = streamLocation.Stream;
                    this.ownsStream  = false;

                    if (!this.inputStream.CanRead)
                    {
                        throw new NotSupportedException(string.Format(
                                                            CultureInfo.CurrentCulture,
                                                            Resources.StreamMustSupportReadException,
                                                            "inputStream"));
                    }

                    if (!this.inputStream.CanSeek)
                    {
                        throw new NotSupportedException(string.Format(
                                                            CultureInfo.CurrentCulture,
                                                            Resources.StreamMustSupportSeekException,
                                                            "inputStream"));
                    }
                }
                else
                {
                    FileLocation fileLocation = this.transferJob.Source as FileLocation;
                    Debug.Assert(
                        null != fileLocation,
                        "Initializing StreamedReader instance, but source is neither a stream nor a file");
                    this.SharedTransferData.SourceLocation = fileLocation.ToString();

                    try
                    {
                        // Attempt to open the file first so that we throw an exception before getting into the async work
                        this.inputStream = new FileStream(
                            fileLocation.FilePath,
                            FileMode.Open,
                            FileAccess.Read,
                            FileShare.Read);

                        this.ownsStream = true;
                    }
                    catch (Exception ex)
                    {
                        if ((ex is NotSupportedException) ||
                            (ex is IOException) ||
                            (ex is UnauthorizedAccessException) ||
                            (ex is SecurityException) ||
                            (ex is ArgumentException && !(ex is ArgumentNullException)))
                        {
                            string exceptionMessage = string.Format(
                                CultureInfo.CurrentCulture,
                                Resources.FailedToOpenFileException,
                                fileLocation.FilePath,
                                ex.Message);

                            throw new TransferException(
                                TransferErrorCode.OpenFileFailed,
                                exceptionMessage,
                                ex);
                        }
                        else
                        {
                            throw;
                        }
                    }
                }
            });

            this.SharedTransferData.TotalLength = this.inputStream.Length;

            int count = (int)Math.Ceiling((double)(this.SharedTransferData.TotalLength - this.transferJob.CheckPoint.EntryTransferOffset) / this.Scheduler.TransferOptions.BlockSize);

            if (null != this.transferJob.CheckPoint.TransferWindow)
            {
                count += this.transferJob.CheckPoint.TransferWindow.Count;
            }

            this.lastTransferWindow = new Queue <long>(this.transferJob.CheckPoint.TransferWindow);

            this.md5HashStream = new MD5HashStream(
                this.inputStream,
                this.transferJob.CheckPoint.EntryTransferOffset,
                true);

            this.PreProcessed = true;

            if (!this.md5HashStream.FinishedSeparateMd5Calculator)
            {
                await Task.Run(() =>
                {
                    this.md5HashStream.CalculateMd5(this.Scheduler.MemoryManager, this.Controller.CheckCancellation);
                });
            }

            if (0 == count)
            {
                this.countdownEvent = new CountdownEvent(1);
                this.SetChunkFinish();
            }
            else
            {
                this.countdownEvent = new CountdownEvent(count);

                this.state   = State.ReadStream;
                this.hasWork = true;
            }
        }
Пример #29
0
 public GenericLocationSupport(long offset, long size, object parentObj)
 {
     location = new StreamLocation(offset,size);
     parent = parentObj;
 }
        ClassifyAsComment(ScanStream ScanStream, TextTraits Traits, int Bx)
        {
            TextLocation       wordBx     = null;
            AtomText           atomText   = null;
            ScanPattern        nonWordPat = null;
            PatternScanResults nonWord    = null;

            // look prior to see if this comment to the end of the line is the first non
            // blank on the line.
            bool isFirstNonBlankOnLine = false;

            if (Bx == 0)
            {
                isFirstNonBlankOnLine = true;
            }
            else
            {
                // go back to the first non blank.
                int ix = Scanner.ScanReverseNotEqual(
                    ScanStream.Stream, Bx - 1, Traits.WhitespaceWithoutNewLinePatterns);
                if (ix == -1) // nothing but blanks to start of string.
                {
                    isFirstNonBlankOnLine = true;
                }

                else
                {
                    var rv = Traits.NewLinePatterns.MatchFirstPatternEndsAtStringLocation(
                        ScanStream.Stream, ix);
                    var pat   = rv.Item1;
                    var patBx = rv.Item2;

                    // is a new line pattern. there is nothing but spaces between this new line
                    // and the start of the comment.
                    if (pat != null)
                    {
                        isFirstNonBlankOnLine = true;
                    }
                }
            }

            // set the atomCode of this atom depending on if the comment starts the line.
            ScanAtomCode atomCode = ScanAtomCode.CommentToEnd;

            if (isFirstNonBlankOnLine == true)
            {
                atomCode = ScanAtomCode.EntireLineCommentToEnd;
            }

            // scan for a new line. That is the end of the comment.
            {
                nonWord = Scanner.ScanEqualAny(ScanStream.Stream, Bx, Traits.NewLinePatterns);
//        eolPat = rv.Item1;
//        eolIx = rv.Item2;
//        nonWord = rv.Item3;
            }

            // no newline pattern found. Comment to the end of the text stream.
            if (nonWord.IsEmpty == true)
//      if (eolPat == null)
            {
                int ex = ScanStream.Stream.Length - 1;
                wordBx = new StreamLocation(Bx).ToTextLocation(ScanStream);
                TextLocation wordEx      = new StreamLocation(ex).ToTextLocation(ScanStream);
                string       commentText = ScanStream.Substring(Bx);

                string userCode = null;
                atomText = new AtomText(
                    atomCode, commentText, null, wordBx, wordEx,
                    userCode);

//        nonWordPat = eolPat;
            }

            else
            {
                wordBx = new StreamLocation(Bx).ToTextLocation(ScanStream);
                int lx = nonWord.Position - Bx;
//        int lx = eolIx - Bx;
                TextLocation wordEx =
                    new StreamLocation(Bx + lx - 1).ToTextLocation(ScanStream);
                string commentText = ScanStream.Substring(Bx, lx);
                string userCode    = null;
                atomText = new AtomText(
                    atomCode, commentText, null, wordBx, wordEx,
                    userCode);
                var sloc = wordBx.ToStreamLocation(ScanStream);

//        nonWordPat = eolPat;
            }
            return(new Tuple <TextLocation, AtomText, ScanPattern, PatternScanResults>
                       (wordBx, atomText, nonWordPat, nonWord));
        }
Пример #31
0
 internal OptionalHeader(ExeReader exeReader, StreamLocation streamLoc)
 {
     reader = exeReader;
     location = streamLoc;
 }
Пример #32
0
        private void LoadNTHeaders()
        {
            if (_dos_header == null)
                LoadDOSHeader();

            _stream.Seek(_dos_header.FileAddressNewHeader,SeekOrigin.Begin);

            LoadPESignature();

            FileHeader file_header = LoadFileHeader(_dos_header);
            OptionalHeader opt_header = LoadOptionalHeader(file_header);
            StreamLocation location = new StreamLocation(_dos_header.FileAddressNewHeader,4 + file_header.Location.Size + opt_header.Location.Size);

            _nt_headers = new NTHeaders(this,location,file_header,opt_header);

            if (_nt_headers.FileHeader != null)
            {
                CharacteristicsType characteristics = _nt_headers.FileHeader.GetCharacteristics();

                is_32bit = ((characteristics & CharacteristicsType.Supports32Bit) == CharacteristicsType.Supports32Bit);
                is_64bit = !is_32bit;
            }

            if (_nt_headers.OptionalHeader != null)
            {
                is_32bit = (_nt_headers.OptionalHeader.GetMagic() == MagicType.PE32);
                is_64bit = !is_32bit;
            }

            DataDirectory clr_dir = _nt_headers.OptionalHeader.DataDirectories[DataDirectoryType.CLRRuntimeHeader];

            is_clr = (clr_dir != null && clr_dir.VirtualAddress > 0 && clr_dir.Size > 0);
        }
Пример #33
0
        private async Task OpenInputStreamAsync()
        {
            Debug.Assert(
                State.OpenInputStream == this.state,
                "OpenInputStreamAsync called, but state is not OpenInputStream.");

            if (Interlocked.CompareExchange(ref workToken, 0, 1) == 0)
            {
                return;
            }

            await Task.Yield();

            this.NotifyStarting();
            this.Controller.CheckCancellation();

            if (this.transferJob.Source.Type == TransferLocationType.Stream)
            {
                StreamLocation streamLocation = this.transferJob.Source as StreamLocation;
                this.inputStream = streamLocation.Stream;
                this.ownsStream  = false;

                if (!this.inputStream.CanRead)
                {
                    throw new NotSupportedException(string.Format(
                                                        CultureInfo.CurrentCulture,
                                                        Resources.StreamMustSupportReadException,
                                                        "inputStream"));
                }
            }
            else
            {
                FileLocation fileLocation = this.transferJob.Source as FileLocation;
                Debug.Assert(
                    null != fileLocation,
                    "Initializing StreamedReader instance, but source is neither a stream nor a file");

                try
                {
                    if (fileLocation.RelativePath != null &&
                        fileLocation.RelativePath.Length > Constants.MaxRelativePathLength)
                    {
                        string errorMessage = string.Format(
                            CultureInfo.CurrentCulture,
                            Resources.RelativePathTooLong,
                            fileLocation.RelativePath);
                        throw new TransferException(TransferErrorCode.OpenFileFailed, errorMessage);
                    }

                    this.filePath = fileLocation.FilePath.ToLongPath();

#if DOTNET5_4
                    // Attempt to open the file first so that we throw an exception before getting into the async work
                    this.inputStream = new FileStream(
                        filePath,
                        FileMode.Open,
                        FileAccess.Read,
                        FileShare.Read);
#else
                    this.inputStream = LongPathFile.Open(
                        this.filePath,
                        FileMode.Open,
                        FileAccess.Read,
                        FileShare.Read);
#endif
                    this.ownsStream = true;
                }
                catch (Exception ex)
                {
                    if ((ex is NotSupportedException) ||
                        (ex is IOException) ||
                        (ex is UnauthorizedAccessException) ||
                        (ex is SecurityException) ||
                        (ex is ArgumentException && !(ex is ArgumentNullException)))
                    {
                        string exceptionMessage = string.Format(
                            CultureInfo.CurrentCulture,
                            Resources.FailedToOpenFileException,
                            fileLocation.FilePath,
                            ex.Message);

                        throw new TransferException(
                                  TransferErrorCode.OpenFileFailed,
                                  exceptionMessage,
                                  ex);
                    }
                    else
                    {
                        throw;
                    }
                }
            }

            try
            {
                this.SharedTransferData.TotalLength = this.inputStream.Length;
            }
            catch (NotSupportedException)
            {
                this.SharedTransferData.TotalLength = -1;
            }

            // Only do calculation related to transfer window when the file contains multiple chunks.
            if (!this.EnableOneChunkFileOptimization)
            {
                var checkpoint = this.transferJob.CheckPoint;

                checkpoint.TransferWindow.Sort();

                this.readLength = checkpoint.EntryTransferOffset;

                if (checkpoint.TransferWindow.Any())
                {
                    // The size of last block can be smaller than BlockSize.
                    this.readLength -= Math.Min(checkpoint.EntryTransferOffset - checkpoint.TransferWindow.Last(), this.SharedTransferData.BlockSize);
                    this.readLength -= (checkpoint.TransferWindow.Count - 1) * this.SharedTransferData.BlockSize;
                }

                if (this.readLength < 0)
                {
                    throw new InvalidOperationException(Resources.RestartableInfoCorruptedException);
                }
                else if ((checkpoint.EntryTransferOffset > 0) && (!this.inputStream.CanSeek))
                {
                    throw new NotSupportedException(string.Format(
                                                        CultureInfo.CurrentCulture,
                                                        Resources.StreamMustSupportSeekException,
                                                        "inputStream"));
                }

                this.lastTransferWindow = new Queue <long>(this.transferJob.CheckPoint.TransferWindow);
            }

            this.md5HashStream = new MD5HashStream(
                this.inputStream,
                this.transferJob.CheckPoint.EntryTransferOffset,
                true);

            this.PreProcessed = true;

            if (this.readLength != this.SharedTransferData.TotalLength)
            {
                // Change the state to 'ReadStream' before awaiting MD5 calculation task to not block the reader.
                this.state     = State.ReadStream;
                this.workToken = 1;
            }
            else
            {
                Interlocked.Exchange(ref this.readCompleted, 1);
            }

            if (!this.md5HashStream.FinishedSeparateMd5Calculator)
            {
                await Task.Run(() =>
                {
                    this.md5HashStream.CalculateMd5(this.Scheduler.MemoryManager, this.Controller.CheckCancellation);
                });
            }

            this.SetChunkFinish();
        }
        private async Task OpenInputStreamAsync()
        {
            Debug.Assert(
                State.OpenInputStream == this.state,
                "OpenInputStreamAsync called, but state is not OpenInputStream.");

            if (Interlocked.CompareExchange(ref workToken, 0, 1) == 0)
            {
                return;
            }

            await Task.Yield();

            this.NotifyStarting();
            this.Controller.CheckCancellation();

            if (this.transferJob.Source.Type == TransferLocationType.Stream)
            {
                StreamLocation streamLocation = this.transferJob.Source as StreamLocation;
                this.inputStream = streamLocation.Stream;
                this.ownsStream = false;

                if (!this.inputStream.CanRead)
                {
                    throw new NotSupportedException(string.Format(
                        CultureInfo.CurrentCulture,
                        Resources.StreamMustSupportReadException,
                        "inputStream"));
                }
            }
            else
            {
                FileLocation fileLocation = this.transferJob.Source as FileLocation;
                Debug.Assert(
                    null != fileLocation,
                    "Initializing StreamedReader instance, but source is neither a stream nor a file");

                try
                {
                    if (fileLocation.RelativePath != null
                        && fileLocation.RelativePath.Length > Constants.MaxRelativePathLength)
                    {
                        string errorMessage = string.Format(
                            CultureInfo.CurrentCulture,
                            Resources.RelativePathTooLong,
                            fileLocation.RelativePath);
                        throw new TransferException(TransferErrorCode.OpenFileFailed, errorMessage);
                    }
#if DOTNET5_4
                    string filePath = fileLocation.FilePath;
                    if (Interop.CrossPlatformHelpers.IsWindows)
                    {
                        filePath = LongPath.ToUncPath(fileLocation.FilePath);
                    }
                    // Attempt to open the file first so that we throw an exception before getting into the async work
                    this.inputStream = new FileStream(
                        filePath,
                        FileMode.Open,
                        FileAccess.Read,
                        FileShare.Read);
#else
                        this.inputStream = LongPathFile.Open(
                            fileLocation.FilePath,
                            FileMode.Open,
                            FileAccess.Read,
                            FileShare.Read);
#endif
                    this.ownsStream = true;
                }
                catch (Exception ex)
                {
                    if ((ex is NotSupportedException) ||
                        (ex is IOException) ||
                        (ex is UnauthorizedAccessException) ||
                        (ex is SecurityException) ||
                        (ex is ArgumentException && !(ex is ArgumentNullException)))
                    {
                        string exceptionMessage = string.Format(
                                    CultureInfo.CurrentCulture,
                                    Resources.FailedToOpenFileException,
                                    fileLocation.FilePath,
                                    ex.Message);

                        throw new TransferException(
                                TransferErrorCode.OpenFileFailed,
                                exceptionMessage,
                                ex);
                    }
                    else
                    {
                        throw;
                    }
                }
            }
            }).ConfigureAwait(false);