Ejemplo n.º 1
0
        private void AppendRelocationSection(UnmanagedDataReader s, DataSectionDescription relocationSection)
        {
            uint delta;
            uint offset = GetVirtualRelativeAddress(relocationSection.VirtualAddress, out delta);
            ReaderWithOffsetArgs arg;
            RelocationSection    section;

            if (offset == 0)
            {
                return;
            }

            // read the info:
            s.Jump(offset);

            // add all sections:
            section = new RelocationSection();
            arg     = new ReaderWithOffsetArgs(s, offset, delta, section);
            while (Append <RelocationSection.ImageBaseRelocation, WindowsPortableExecutable, ReaderWithOffsetArgs>
                       (s, this, arg))
            {
            }

            // append relocation section when any data was read from file:
            if (section.Count > 0)
            {
                section.UpdateFileInfo(RelocationSection.DefaultName, offset, s.CurrentOffset - offset);
                section.UpdateVirtualInfo(offset, s.CurrentOffset - offset);

                Add(section);
            }
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Init constructor of ReaderWithOffset.
 /// </summary>
 public ReaderWithOffsetArgs(UnmanagedDataReader source, uint offset, uint delta, object tag)
 {
     this.source = source;
     this.offset = offset;
     this.delta  = delta;
     this.tag    = tag;
 }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Extracts info about Import section.
        /// </summary>
        private void AppendImportSection(UnmanagedDataReader s, DataSectionDescription importSection, DataSectionDescription importBoundSection, NtHeaderSection ntSection)
        {
            ImportFunctionSection ifs = new ImportFunctionSection();
            uint delta;
            uint offset = GetVirtualRelativeAddress(importSection.VirtualAddress, out delta);

            if (offset == 0 || ntSection == null)
            {
                return;
            }

            // analize data inside given section:
            ReaderWithOffsetArgs arg = new ReaderWithOffsetArgs(s, offset, delta, ifs);

            // read the info:
            s.Jump(offset);
            while (Append <ImportFunctionModule.ImageImportDescriptor, WindowsPortableExecutable, ReaderWithOffsetArgs>
                       (s, this, arg))
            {
                // store the current location:
                offset = s.CurrentOffset;

                // read functions assigned to given module:
                if (ntSection.MachineType == MachineType.Intel_x86)
                {
                    ReadImportData <ImportFunctionModule.ImageImportData32, WindowsPortableExecutable>(s, arg.Tag as ImportFunctionModule);
                }
                else
                if (ntSection.MachineType == MachineType.Intel_x64)
                {
                    ReadImportData <ImportFunctionModule.ImageImportData64, WindowsPortableExecutable>(s, arg.Tag as ImportFunctionModule);
                }

                // restore the offset:
                s.Jump(offset);
                arg.Tag = ifs;
            }

            // check if there is additional bound-import infor available and read it:
            if (importBoundSection != null)
            {
                ReaderWithOffsetArgs iArg = new ReaderWithOffsetArgs(s, importBoundSection.VirtualAddress, 0, ifs);

                s.Jump(importBoundSection.VirtualAddress);
                while (Append <ImportFunctionModule.ImageBoundImportDescription, WindowsPortableExecutable, ReaderWithOffsetArgs>(s, this, iArg))
                {
                }
            }

            // if import section was correctly filled by at least one element then store it:
            if (ifs.Count > 0)
            {
                ifs.UpdateFileInfo(ImportFunctionSection.DefaultName, offset, s.LastReadSize * (uint)ifs.Count);
                ifs.UpdateVirtualInfo(importSection.VirtualAddress, importSection.Size);
                Add(ifs);
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Loads proper binary sections based on given source.
        /// </summary>
        protected override void Load(UnmanagedDataReader s, BinaryLoadArgs e)
        {
            WindowsPortableExecutableLoadArgs a = e as WindowsPortableExecutableLoadArgs ??
                                                  new WindowsPortableExecutableLoadArgs();

            /////////////////////////////////////////
            // detect file type:

            // is it a .lib file?
            string text = s.ReadStringAnsiAt(0, LibHeaderNameLength);

            if (text == LibHeaderName)
            {
                LoadLibBinary(s, a);
            }

            // read MS-DOS compatible header and based on that
            // try to detect values of the fields correct for specific formats:
            DosHeaderSection dosSection = Read <DosHeaderSection.ImageDosHeader, DosHeaderSection>(s, false);

            if (dosSection == null)
            {
                return;
            }

            // load data as exe/dll binary:
            if (dosSection.IsExecutable)
            {
                Add(dosSection);

                // jump to new NT header:
                if (s.Jump(dosSection.NtHeaderAddress) == uint.MaxValue)
                {
                    return;
                }

                LoadExeBinary(s, a);
                return;
            }

            // load debug file:
            if (dosSection.IsDebugBinary)
            {
                s.UndoRead();
                LoadDbgBinary(s, a);
                return;
            }

            // load data as object binary:
            if (dosSection.IsObjectBinary)
            {
                s.UndoRead();
                LoadObjBinary(s, a);
                return;
            }
        }
Ejemplo n.º 6
0
        private void AppendResourceSection(UnmanagedDataReader s, DataSectionDescription resourceSection)
        {
            uint delta;
            uint offset = GetVirtualRelativeAddress(resourceSection.VirtualAddress, out delta);

            if (offset == 0)
            {
                return;
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Load section descriptions from given file.
        /// </summary>
        public void Load(string fileName, BinaryLoadArgs e)
        {
            fullPath = Path.GetFullPath(fileName);
            name     = Path.GetFileName(fileName);

            if (File.Exists(fullPath))
            {
                if (e == null || e.UseMapping)
                {
                    // create readers:
                    UnmanagedDataReader s;
                    FileSharedMemory    fs = null;

                    try
                    {
                        fs = new FileSharedMemory(fullPath,
                                                  (e == null || e.IsReadOnlyMode
                                                       ? SharedMemory.AccessTypes.ReadOnly
                                                       : SharedMemory.AccessTypes.ReadWrite));
                        s = new UnmanagedDataReader(fs.Address, fs.Size);

                        // and parse the file:
                        Load(s, e);
                    }
                    finally
                    {
                        if (fs != null)
                        {
                            fs.Close();
                        }
                    }
                }
                else
                {
                    // read brutally the whole file into memory and parse:
                    byte[] x = File.ReadAllBytes(fullPath);

                    // check if not empty:
                    if (x.Length > 0)
                    {
                        IntPtr p = Marshal.AllocHGlobal(x.Length);

                        if (p != IntPtr.Zero)
                        {
                            Marshal.Copy(x, 0, p, x.Length);
                            Load(new UnmanagedDataReader(p, (uint)x.Length), e);
                            Marshal.FreeHGlobal(p);
                        }
                    }
                }
            }
        }
Ejemplo n.º 8
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);
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Extracts info about Export section.
        /// </summary>
        private void AppendExportSection(UnmanagedDataReader s, DataSectionDescription exportSection)
        {
            uint delta;
            uint offset = GetVirtualRelativeAddress(exportSection.VirtualAddress, out delta);

            if (offset == 0)
            {
                return;
            }

            // read the info:
            s.Jump(offset);
            Append <ExportFunctionSection.ImageExportDirectory, WindowsPortableExecutable, ReaderWithOffsetArgs>
                (s, this, new ReaderWithOffsetArgs(s, offset, delta, exportSection));
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Attaches 64-bit specific info about imported functions.
        /// </summary>
        private bool AttachImportData(ref ImportFunctionModule.ImageImportData64 r, UnmanagedDataReader s, uint delta, ImportFunctionModule m)
        {
            if (m == null)
            {
                return(false);
            }

            // check if there is any data attached:
            if (r.OrdinalOrAddressOfData == 0)
            {
                return(false);
            }

            if (r.IsOrdinal)
            {
                ImportFunctionModule.ImageImportData64 thunk = new ImportFunctionModule.ImageImportData64();

                if (s.ReadAt(ref thunk, m.FirstThunk - delta))
                {
                    m.Add(new ImportFunctionDescription(r.Ordinal,
                                                        m.IsBinded ? thunk.OrdinalOrAddressOfData : 0));
                }
            }
            else
            {
                ImportFunctionModule.ImageImportByName funName = new ImportFunctionModule.ImageImportByName();
                ImportFunctionModule.ImageImportData64 thunk   = new ImportFunctionModule.ImageImportData64();

                if (s.ReadAt(ref thunk, m.FirstThunk - delta))
                {
                    if (s.ReadAt(ref funName, (uint)r.OrdinalOrAddressOfData - delta))
                    {
                        m.Add(new ImportFunctionDescription(
                                  s.ReadStringAnsiAt((uint)r.OrdinalOrAddressOfData - delta + sizeof(short)),
                                  m.IsBinded ? thunk.OrdinalOrAddressOfData : 0,
                                  (uint)funName.Hint));
                    }
                }
            }

            return(true);
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Reads detailed data of imported elements.
        /// </summary>
        private void ReadImportData <T, S>(UnmanagedDataReader s, ImportFunctionModule m)
            where T : struct
            where S : class, IBinaryAppender <T, ReaderWithOffsetArgs>
        {
            if (m != null)
            {
                uint xDelta;
                uint xOffset = GetVirtualRelativeAddress(m.NextModuleAddress, out xDelta);

                if (xOffset != 0)
                {
                    s.Jump(xOffset);
                    while (Append <T, S, ReaderWithOffsetArgs>
                               (s, this as S, new ReaderWithOffsetArgs(s, xOffset, xDelta, m)))
                    {
                        m.FirstThunk += s.LastReadSize;
                    }
                }
            }
        }
Ejemplo n.º 12
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);
        }
Ejemplo n.º 13
0
 /// <summary>
 /// Loads proper binary sections based on given source.
 /// </summary>
 protected abstract void Load(UnmanagedDataReader s, BinaryLoadArgs e);
Ejemplo n.º 14
0
 /// <summary>
 /// Reads given structure from specified source.
 /// </summary>
 protected S Read <T, S>(UnmanagedDataReader source)
     where T : struct
     where S : BinarySection, IBinaryConverter <T>, new()
 {
     return(Read <T, S>(source, true));
 }
Ejemplo n.º 15
0
 /// <summary>
 /// Loads binary as Visual Studio C++ .lib file.
 /// </summary>
 private void LoadLibBinary(UnmanagedDataReader s, WindowsPortableExecutableLoadArgs e)
 {
 }
Ejemplo n.º 16
0
        /// <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;
        }