Пример #1
0
        public Relocations(BinaryReader reader, MModule mod)
        {
            uint start, end;

            if (mod.ModHeaders.OSHeaders.PEHeader.DataDirs[5].Rva == 0)
            {
                return;
            }

            start = mod.ModHeaders.Rva2Offset(mod.ModHeaders.OSHeaders.PEHeader.DataDirs[5].Rva);
            end   = start + mod.ModHeaders.OSHeaders.PEHeader.DataDirs[5].Size;

            //fill in Region props
            Start  = start;
            Length = end - start;

            reader.BaseStream.Position = start;

            RelocationBlock block;
            ArrayList       arr = new ArrayList();

            while (reader.BaseStream.Position < end)
            {
                block = new RelocationBlock(reader);
                arr.Add(block);
            }

            _blox = (RelocationBlock[])arr.ToArray(typeof(RelocationBlock));
        }
Пример #2
0
        public ImportAddress(uint n, BinaryReader reader, MModule mod)
        {
            if ((n & 0x80000000) != 0)
            {
                _ByOrdinal = true;
            }
            else
            {
                _ByOrdinal = false;
            }

            if (_ByOrdinal)
            {
                _Ordinal = n & 0x7fffffff;
            }
            else
            {
                uint nameOffs = n & 0x7fffffff;
                long offs     = reader.BaseStream.Position;
                reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(nameOffs);
                reader.ReadInt16(); //hint

                byte b = reader.ReadByte();

                while (b != 0)
                {
                    _Name += (char)b;
                    b      = reader.ReadByte();
                }

                reader.BaseStream.Position = offs;
            }
        }
Пример #3
0
        public MDBlob(BinaryReader reader)
        {
            //read length indicator
            _length = MModule.DecodeInt32(reader);

            _data = reader.ReadBytes(_length);
        }
Пример #4
0
        public MDTables(BinaryReader reader, MModule mod)
        {
            _mod = mod;

            SetupSchema(reader);

            //reader may now be accessed randomly to fill in actual strings etc.
        }
Пример #5
0
 public ExportDirTable(BinaryReader reader, MModule mod)
 {
     _ExportFlags           = reader.ReadUInt32();
     _TimeStamp             = reader.ReadUInt32();
     _MajorVersion          = reader.ReadUInt16();
     _MinorVersion          = reader.ReadUInt16();
     _Name                  = mod.StringFromRVA(reader, reader.ReadUInt32());
     _OrdinalBase           = reader.ReadUInt32();
     _AddressTableEntries   = reader.ReadUInt32();
     _NamePointerCount      = reader.ReadUInt32();
     _ExportAddressTableRVA = reader.ReadUInt32();
     _NamePointerRVA        = reader.ReadUInt32();
     _OrdinalRVA            = reader.ReadUInt32();
 }
Пример #6
0
        public ImpExports(BinaryReader reader, MModule mod)
        {
            ArrayList            ides = new ArrayList();
            ImportDirectoryEntry ide  = null;

            _exports = new ExportRecord[0];
            _ith     = new ImportDirectoryEntry[0];

            //imports

            if (mod.ModHeaders.OSHeaders.PEHeader.DataDirs[1].Rva != 0)
            {
                uint start, end;
                start = mod.ModHeaders.Rva2Offset(mod.ModHeaders.OSHeaders.PEHeader.DataDirs[1].Rva);
                end   = mod.ModHeaders.OSHeaders.PEHeader.DataDirs[1].Size + start;

                reader.BaseStream.Position = start;

                while (reader.BaseStream.Position < end)
                {
                    ide = new ImportDirectoryEntry(reader, mod);

                    //in older PEs it seems there is no null terminating entry, but in .NET ones there is.
                    if (ide.Name == null)
                    {
                        break;
                    }

                    ides.Add(ide);
                }

                _ith = (ImportDirectoryEntry[])ides.ToArray(typeof(ImportDirectoryEntry));
            }

            //exports

            if (mod.ModHeaders.OSHeaders.PEHeader.DataDirs[0].Rva != 0)
            {
                reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(mod.ModHeaders.OSHeaders.PEHeader.DataDirs[0].Rva);
                _extab = new ExportDirTable(reader, mod);

                _expAddrTab = new uint[_extab.AddressTableEntries];
                _expNameTab = new string[_extab.NamePointerCount];
                _expOrdTab  = new uint[_extab.NamePointerCount];

                reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(_extab.ExportAddressTableRVA);

                for (int i = 0; i < _extab.AddressTableEntries; ++i)
                {
                    _expAddrTab[i] = reader.ReadUInt32();
                }

                reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(_extab.OrdinalRVA);

                for (int i = 0; i < _extab.NamePointerCount; ++i)
                {
                    _expOrdTab[i] = reader.ReadUInt16();
                }

                reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(_extab.NamePointerRVA);

                for (int i = 0; i < _extab.NamePointerCount; ++i)
                {
                    _expNameTab[i] = mod.StringFromRVA(reader, reader.ReadUInt32());
                }

                //assemble array of exportrecords
                uint len = _extab.AddressTableEntries;
                if (len > _extab.NamePointerCount)
                {
                    len = _extab.NamePointerCount;
                }
                _exports = new ExportRecord[len];
                for (int i = 0; i < len; ++i)
                {
                    _exports[i] = new ExportRecord(_expOrdTab[i], _expAddrTab[i], _expNameTab[i]);
                }
            }
        }
Пример #7
0
        public ImportDirectoryEntry(BinaryReader reader, MModule mod)
        {
            Start = reader.BaseStream.Position;

            uint iltRVA = reader.ReadUInt32();

            _DateTimeStamp  = reader.ReadUInt32();
            _ForwarderChain = reader.ReadUInt32();
            uint nameRVA = reader.ReadUInt32();

            _Name = mod.StringFromRVA(reader, nameRVA);
            uint iatRVA = reader.ReadUInt32(); //can also get this from the PEHeader's data dirs

            Length = reader.BaseStream.Position - Start;

            long offs = reader.BaseStream.Position; // remember our position at the end of the imp dir entry record

            if (nameRVA == 0)
            {
                //indicate that this is not valid, because we reached the null terminating record
                //or because we are hopelessly lost
                _Name = null;
                return;
            }

            try
            {
                //get imp look table from RVA
                ArrayList arr;
                uint      tableOffs, field;

                if (iltRVA != 0)
                {
                    arr       = new ArrayList();
                    tableOffs = mod.ModHeaders.Rva2Offset(iltRVA);
                    reader.BaseStream.Position = tableOffs;
                    field = reader.ReadUInt32();
                    while (field != 0)
                    {
                        arr.Add(new ImportAddress(field, reader, mod));
                        field = reader.ReadUInt32();
                    }

                    _ImportLookupTable = (ImportAddress[])arr.ToArray(typeof(ImportAddress));
                }

                //get imp Addr table from RVA
                if (iatRVA != 0)
                {
                    arr       = new ArrayList();
                    tableOffs = mod.ModHeaders.Rva2Offset(iatRVA);
                    reader.BaseStream.Position = tableOffs;
                    field = reader.ReadUInt32();
                    while (field != 0)
                    {
                        arr.Add(field);
                        field = reader.ReadUInt32();
                    }

                    _ImportAddressTable = (uint[])arr.ToArray(typeof(uint));
                }
            }
            catch
            {
            }
            finally
            {
                //restore stream pos
                reader.BaseStream.Position = offs;
            }
        }
Пример #8
0
        public MDTables(BinaryReader reader, MModule mod)
        {
            _mod = mod;

            SetupSchema(reader);

            //reader may now be accessed randomly to fill in actual strings etc.
        }
Пример #9
0
        /// <summary>
        /// Decodes assembly metadata, headers and tables to required values ad file offsets
        /// </summary>
        /// <param name="fileName">Assembly path and filename</param>
        /// <param name="cliHeaderFlag">Reference to CLI Header flag value</param>
        /// <param name="cliHeaderFlagOffset">Reference to CLI Header flag file offset</param>
        /// <param name="strongNameSignatureOffset">Reference to CLI Header strong name signature file offset</param>
        /// <param name="publicKeyIndexOffset">Reference to Public Key Index in Assembly Table file offset</param>
        /// <param name="publicKeyOffset">Reference to Public Key file offset</param>
        /// <param name="assemblyFlag">Reference to Assembly Table Flag value</param>
        /// <param name="assemblyFlagOffset">Reference to Assembly Table Flag file offset</param>
        /// <param name="compiledRuntimeVersion">Reference to string with compiled runtime version</param>
        /// <param name="assemblyReferences">Reference to array to hold assembly references</param>
        /// <param name="blobIndexSize">Blob Index size in bytes</param>
        /// <returns>Returns a bool indicating if assembly data can be retieved successfully</returns>
        public static bool GetAssemblyData(string fileName, ref uint cliHeaderFlag, ref long cliHeaderFlagOffset, ref long strongNameSignatureOffset,
                                           ref long publicKeyIndexOffset, ref long publicKeyOffset, ref uint assemblyFlag, ref long assemblyFlagOffset,
                                           ref string compiledRuntimeVersion, ref ArrayList assemblyReferences, ref int blobIndexSize, bool getSigOnly)
        {
            MModule mod;
            BinaryReader r;

            FileStream stream = null;

            cliHeaderFlag = 0;
            cliHeaderFlagOffset = 0;
            strongNameSignatureOffset = 0;
            publicKeyIndexOffset = 0;
            publicKeyOffset = 0;
            compiledRuntimeVersion = String.Empty;
            assemblyFlag = 0;
            assemblyFlagOffset = 0;
            assemblyReferences.Clear();

            try
            {
                if (File.Exists(fileName))
                {
                    stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
                    r = new BinaryReader(stream);

                    mod = new MModule(r);

                    try
                    {
                        if (mod.ModHeaders.COR20Header != null)
                        {
                            cliHeaderFlag = mod.ModHeaders.COR20Header.Flags;
                            cliHeaderFlagOffset = mod.ModHeaders.COR20Header.Start + CLI_HEADER_FLAGS_OFFSET;
                            // if Strong Name Signature RVA is zero, no Strong Signature is available
                            strongNameSignatureOffset = (mod.ModHeaders.COR20Header.StrongNameSignature.Rva == 0
                                                             ? 0
                                                             : mod.ModHeaders.COR20Header.StrongNameSignature.Start);
                            compiledRuntimeVersion = mod.ModHeaders.MetaDataHeaders.StorageSigAndHeader.VersionString.Replace("\0", String.Empty);
                            blobIndexSize = mod.MDTables.GetBlobIndexSize();

                            // next loop sum tables byte length till reaching Assembly Table - this would give Assembly Table start offset
                            long assemblyTableOffset = mod.ModHeaders.MetaDataTableHeader.End;
                            for (int tablesCounter = 0; tablesCounter < (int) Types.Assembly; tablesCounter++)
                            {
                                assemblyTableOffset += mod.MDTables.Tables[tablesCounter].RawData.Length;
                            }

                            Table tableAssembly = mod.MDTables.GetTable(Types.Assembly);
                            if (tableAssembly.Count > 0) // this should be 1
                            {
                                if (tableAssembly[0][6].RawData == 0)
                                {
                                    // Index for public key points no nothing
                                    publicKeyOffset = 0;
                                }
                                else
                                {
                                    publicKeyOffset = mod.BlobHeap.Start + tableAssembly[0][6].RawData + 1;
                                }

                                assemblyFlag = (uint) tableAssembly[0][5].Data;

                                if (assemblyTableOffset > 0)
                                {
                                    publicKeyIndexOffset = assemblyTableOffset + ASSEMBLY_TABLE_PUBLIC_KEY_INDEX_OFFSET;
                                    assemblyFlagOffset = assemblyTableOffset + ASSEMBLY_TABLE_FLAGS_OFFSET;
                                }
                            }

                            if (getSigOnly)
                                return true;

                            // next loop sum tables byte length till reaching Assembly References Table - this would give Assembly References Table start offset
                            long referenceTableOffset = mod.ModHeaders.MetaDataTableHeader.End;
                            for (int tablesCounter = 0; tablesCounter < (int) Types.AssemblyRef; tablesCounter++)
                            {
                                referenceTableOffset += mod.MDTables.Tables[tablesCounter].RawData.Length;
                            }

                            if (referenceTableOffset > 0)
                            {
                                Table tableAssemblyReferences = mod.MDTables.GetTable(Types.AssemblyRef);
                                if (tableAssemblyReferences.Count > 0)
                                {
                                    for (int referencesCounter = 0; referencesCounter < tableAssemblyReferences.Count; referencesCounter++)
                                    {
                                        AssemblyReference reference =
                                            new AssemblyReference(tableAssemblyReferences[referencesCounter][6].Data.ToString(),
                                                                  tableAssemblyReferences[referencesCounter][0].Data + "." +
                                                                  tableAssemblyReferences[referencesCounter][1].Data + "." +
                                                                  tableAssemblyReferences[referencesCounter][2].Data + "." +
                                                                  tableAssemblyReferences[referencesCounter][3].Data,
                                                                  tableAssemblyReferences[referencesCounter][5].Data.ToString(),
                                                                  referenceTableOffset + (referencesCounter*tableAssemblyReferences.RowSize));
                                        assemblyReferences.Add(reference);
                                    }
                                }
                            }
                        }
                        else
                        {
                            return false;
                        }
                    }
                    finally
                    {
                        r.Close();
                    }
                }
            }
            finally
            {
                if (stream != null)
                {
                    stream.Close();
                }
            }

            return true;
        }
Пример #10
0
        public ImportDirectoryEntry(BinaryReader reader, MModule mod)
        {
            Start = reader.BaseStream.Position;

            uint iltRVA = reader.ReadUInt32();
            _DateTimeStamp = reader.ReadUInt32();
            _ForwarderChain = reader.ReadUInt32();
            uint nameRVA = reader.ReadUInt32();
            _Name = mod.StringFromRVA(reader, nameRVA);
            uint iatRVA = reader.ReadUInt32(); //can also get this from the PEHeader's data dirs

            Length = reader.BaseStream.Position - Start;

            long offs = reader.BaseStream.Position; // remember our position at the end of the imp dir entry record

            if (nameRVA == 0)
            {
                //indicate that this is not valid, because we reached the null terminating record
                //or because we are hopelessly lost
                _Name = null;
                return;
            }

            try
            {
                //get imp look table from RVA
                ArrayList arr;
                uint tableOffs, field;

                if (iltRVA != 0)
                {
                    arr = new ArrayList();
                    tableOffs = mod.ModHeaders.Rva2Offset(iltRVA);
                    reader.BaseStream.Position = tableOffs;
                    field = reader.ReadUInt32();
                    while (field != 0)
                    {
                        arr.Add(new ImportAddress(field, reader, mod));
                        field = reader.ReadUInt32();
                    }

                    _ImportLookupTable = (ImportAddress[]) arr.ToArray(typeof (ImportAddress));
                }

                //get imp Addr table from RVA
                if (iatRVA != 0)
                {
                    arr = new ArrayList();
                    tableOffs = mod.ModHeaders.Rva2Offset(iatRVA);
                    reader.BaseStream.Position = tableOffs;
                    field = reader.ReadUInt32();
                    while (field != 0)
                    {
                        arr.Add(field);
                        field = reader.ReadUInt32();
                    }

                    _ImportAddressTable = (uint[]) arr.ToArray(typeof (uint));
                }
            }
            catch
            {
            }
            finally
            {
                //restore stream pos
                reader.BaseStream.Position = offs;
            }
        }
Пример #11
0
        public ImportAddress(uint n, BinaryReader reader, MModule mod)
        {
            if ((n & 0x80000000) != 0)
            {
                _ByOrdinal = true;
            }
            else
            {
                _ByOrdinal = false;
            }

            if (_ByOrdinal)
            {
                _Ordinal = n & 0x7fffffff;
            }
            else
            {
                uint nameOffs = n & 0x7fffffff;
                long offs = reader.BaseStream.Position;
                reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(nameOffs);
                reader.ReadInt16(); //hint

                byte b = reader.ReadByte();

                while (b != 0)
                {
                    _Name += (char) b;
                    b = reader.ReadByte();
                }

                reader.BaseStream.Position = offs;
            }
        }
Пример #12
0
        public ImpExports(BinaryReader reader, MModule mod)
        {
            ArrayList ides = new ArrayList();
            ImportDirectoryEntry ide = null;

            _exports = new ExportRecord[0];
            _ith = new ImportDirectoryEntry[0];

            //imports

            if (mod.ModHeaders.OSHeaders.PEHeader.DataDirs[1].Rva != 0)
            {
                uint start, end;
                start = mod.ModHeaders.Rva2Offset(mod.ModHeaders.OSHeaders.PEHeader.DataDirs[1].Rva);
                end = mod.ModHeaders.OSHeaders.PEHeader.DataDirs[1].Size + start;

                reader.BaseStream.Position = start;

                while (reader.BaseStream.Position < end)
                {
                    ide = new ImportDirectoryEntry(reader, mod);

                    //in older PEs it seems there is no null terminating entry, but in .NET ones there is.
                    if (ide.Name == null)
                    {
                        break;
                    }

                    ides.Add(ide);
                }

                _ith = (ImportDirectoryEntry[]) ides.ToArray(typeof (ImportDirectoryEntry));
            }

            //exports

            if (mod.ModHeaders.OSHeaders.PEHeader.DataDirs[0].Rva != 0)
            {
                reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(mod.ModHeaders.OSHeaders.PEHeader.DataDirs[0].Rva);
                _extab = new ExportDirTable(reader, mod);

                _expAddrTab = new uint[_extab.AddressTableEntries];
                _expNameTab = new string[_extab.NamePointerCount];
                _expOrdTab = new uint[_extab.NamePointerCount];

                reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(_extab.ExportAddressTableRVA);

                for (int i = 0; i < _extab.AddressTableEntries; ++i)
                {
                    _expAddrTab[i] = reader.ReadUInt32();
                }

                reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(_extab.OrdinalRVA);

                for (int i = 0; i < _extab.NamePointerCount; ++i)
                {
                    _expOrdTab[i] = reader.ReadUInt16();
                }

                reader.BaseStream.Position = mod.ModHeaders.Rva2Offset(_extab.NamePointerRVA);

                for (int i = 0; i < _extab.NamePointerCount; ++i)
                {
                    _expNameTab[i] = mod.StringFromRVA(reader, reader.ReadUInt32());
                }

                //assemble array of exportrecords
                uint len = _extab.AddressTableEntries;
                if (len > _extab.NamePointerCount)
                {
                    len = _extab.NamePointerCount;
                }
                _exports = new ExportRecord[len];
                for (int i = 0; i < len; ++i)
                {
                    _exports[i] = new ExportRecord(_expOrdTab[i], _expAddrTab[i], _expNameTab[i]);
                }
            }
        }
Пример #13
0
 public ExportDirTable(BinaryReader reader, MModule mod)
 {
     _ExportFlags = reader.ReadUInt32();
     _TimeStamp = reader.ReadUInt32();
     _MajorVersion = reader.ReadUInt16();
     _MinorVersion = reader.ReadUInt16();
     _Name = mod.StringFromRVA(reader, reader.ReadUInt32());
     _OrdinalBase = reader.ReadUInt32();
     _AddressTableEntries = reader.ReadUInt32();
     _NamePointerCount = reader.ReadUInt32();
     _ExportAddressTableRVA = reader.ReadUInt32();
     _NamePointerRVA = reader.ReadUInt32();
     _OrdinalRVA = reader.ReadUInt32();
 }
Пример #14
0
        public Relocations(BinaryReader reader, MModule mod)
        {
            uint start, end;

            if (mod.ModHeaders.OSHeaders.PEHeader.DataDirs[5].Rva == 0)
            {
                return;
            }

            start = mod.ModHeaders.Rva2Offset(mod.ModHeaders.OSHeaders.PEHeader.DataDirs[5].Rva);
            end = start + mod.ModHeaders.OSHeaders.PEHeader.DataDirs[5].Size;

            //fill in Region props
            Start = start;
            Length = end - start;

            reader.BaseStream.Position = start;

            RelocationBlock block;
            ArrayList arr = new ArrayList();

            while (reader.BaseStream.Position < end)
            {
                block = new RelocationBlock(reader);
                arr.Add(block);
            }

            _blox = (RelocationBlock[]) arr.ToArray(typeof (RelocationBlock));
        }