bool IBinaryAppender <RelocationSection.ImageBaseRelocation, ReaderWithOffsetArgs> .Attach(ref RelocationSection.ImageBaseRelocation s, uint size, ReaderWithOffsetArgs arg)
        {
            UnmanagedDataReader   r       = arg.Source;
            RelocationSection     section = arg.Tag as RelocationSection;
            RelocationDescription desc;
            ushort         data = 0;
            RelocationType type;
            uint           count;
            uint           offset;

            // validate input data:
            if (s.SizeOfBlock == 0 || s.VirtualAddress == 0 || section == null)
            {
                return(false);
            }

            // append data to section:
            count = (s.SizeOfBlock - (uint)Marshal.SizeOf(typeof(RelocationSection.ImageBaseRelocation))) /
                    (uint)Marshal.SizeOf(typeof(ushort));

            if (count > 0)
            {
                desc = new RelocationDescription(s.VirtualAddress, s.SizeOfBlock);

                for (uint i = 0; i < count; i++)
                {
                    if (r.Read(ref data))
                    {
                        type   = (RelocationType)((data & 0xF000) >> 12);
                        offset = (uint)(data & 0x0FFF);

                        if (type == RelocationType.BasedHighAdjust)
                        {
                            if (r.Read(ref data))
                            {
                                offset += ((uint)data) << 12;
                                count--;
                            }
                        }

                        desc.Add(new RelocationItem(type, offset));
                    }
                    else
                    {
                        break;
                    }
                }

                // if data is defined inside the given description:
                if (desc.Count > 0)
                {
                    section.Add(desc);
                }
            }

            return(true);
        }
Exemple #2
0
        /// <summary>
        /// Reads given structure and appends info to given section.
        /// </summary>
        protected static bool Append <T, S, Z>(UnmanagedDataReader source, S section, Z arg)
            where T : struct
            where S : class, IBinaryAppender <T, Z>
        {
            T headerElement = new T();

            // load native type:
            if (section != null && source.Read(ref headerElement))
            {
                return(section.Attach(ref headerElement, source.LastReadSize, arg));
            }

            // return failure:
            return(false);
        }
Exemple #3
0
        /// <summary>
        /// Reads given structure from specified source.
        /// </summary>
        protected S Read <T, S>(UnmanagedDataReader source, bool canStore)
            where T : struct
            where S : BinarySection, IBinaryConverter <T>, new()
        {
            T headerNativeType = new T();

            // load native data:
            if (source.Read(ref headerNativeType))
            {
                S section = new S();
                if (section.Convert(ref headerNativeType, source.LastReadStartOffset, source.LastReadSize))
                {
                    if (canStore)
                    {
                        Add(section);
                    }
                    return(section);
                }
            }

            // return failure in reading:
            return(null);
        }
        /// <summary>
        /// Loads a binary data as a Windows COFF Portable Executable.
        /// </summary>
        private void LoadExeBinary(UnmanagedDataReader s, WindowsPortableExecutableLoadArgs e)
        {
            NtHeaderSection         ntSection;
            NtOptionalHeaderSection ntOptionalSection;
            DataHeaderSection       dataSection;

            // read Win NT compatible header:
            ntSection = Read <NtHeaderSection.ImageNtHeader, NtHeaderSection>(s);
            if (ntSection == null)
            {
                return;
            }

            // detect the type of optional header:
            ushort magicNumber = 0;

            if (!s.Read(ref magicNumber))
            {
                return;
            }

            // undo the last read:
            s.UndoRead();

            // now parse the corresponding sections:
            if (magicNumber == NtOptionalHeaderSection.OptionalHeader32Magic)
            {
                ntOptionalSection = Read <NtOptionalHeaderSection.ImageOptionalHeader32, NtOptionalHeaderSection>(s);
            }
            else if (magicNumber == NtOptionalHeaderSection.OptionalHeader64Magic)
            {
                ntOptionalSection = Read <NtOptionalHeaderSection.ImageOptionalHeader64, NtOptionalHeaderSection>(s);
            }
            else
            {
                ntOptionalSection = Read <NtOptionalHeaderSection.ImageOptionalHeaderROM, NtOptionalHeaderSection>(s);
            }

            // and read specified number of other section locations:
            if (ntOptionalSection != null)
            {
                for (uint i = 0; i < ntOptionalSection.DataDirectoryCount; i++)
                {
                    if (!Append <DataSectionDescription.ImageDataDirectory, WindowsPortableExecutable, DirectoryEntry>
                            (s, this, (DirectoryEntry)i))
                    {
                        return;
                    }
                }
            }

            // read data sections:
            for (uint i = 0; i < ntSection.DataSectionCount; i++)
            {
                dataSection = Read <DataHeaderSection.ImageSectionHeader, DataHeaderSection>(s);
                if (dataSection == null)
                {
                    break;
                }
                dataSections.Add(dataSection);
            }

            if (knownSections != null)
            {
                if (e.LoadExports)
                {
                    // add export information section:
                    DataSectionDescription exportSection;

                    if (knownSections.TryGetValue(DirectoryEntry.Export, out exportSection))
                    {
                        AppendExportSection(s, exportSection);
                    }
                }

                if (e.LoadImports)
                {
                    // add import information section:
                    DataSectionDescription importSection;
                    DataSectionDescription importBoundSection;

                    if (knownSections.TryGetValue(DirectoryEntry.Import, out importSection))
                    {
                        knownSections.TryGetValue(DirectoryEntry.BoundImport, out importBoundSection);
                        AppendImportSection(s, importSection, importBoundSection, ntSection);
                    }
                }

                if (e.LoadResources)
                {
                    // add resources information section:
                    DataSectionDescription resourceSection;

                    if (knownSections.TryGetValue(DirectoryEntry.Resource, out resourceSection))
                    {
                        AppendResourceSection(s, resourceSection);
                    }
                }

                if (e.LoadBaseRelocations)
                {
                    // add relocation information section:
                    DataSectionDescription relocationSection;

                    if (knownSections.TryGetValue(DirectoryEntry.BaseRelocationTable, out relocationSection))
                    {
                        AppendRelocationSection(s, relocationSection);
                    }
                }
            }

            // remove temporary data:
            knownSections = null;
            dataSections  = null;
        }