예제 #1
0
        void WriteStringToken(int col, MetadataTable tbl, MetadataWriter wtr, uint[] lens, object val)
        {
            StringsHeap sh = wtr.BaseStream.Root[MetadataStreamType.Strings].Heap as StringsHeap;

            if (sh.Stream.Length > ushort.MaxValue)
            {
                wtr.Write((uint)(val as StringToken).Token.Value);
            }
            else
            {
                wtr.Write((ushort)(val as StringToken).Token.Value);
            }
        }
예제 #2
0
        public uint CreateAssemblyRef(IAssembly assembly)
        {
            var rid = TablesHeap.AssemblyRefTable.Create();
            var row = new RawAssemblyRefRow((ushort)assembly.Version.Major, (ushort)assembly.Version.Minor,
                                            (ushort)assembly.Version.Build, (ushort)assembly.Version.Revision,
                                            (uint)assembly.Attributes,
                                            BlobHeap.Create(GetPublicKeyOrTokenBytes(assembly.PublicKeyOrToken)),
                                            StringsHeap.Create(assembly.Name),
                                            StringsHeap.Create(assembly.Culture),
                                            BlobHeap.Create((assembly as AssemblyRef)?.Hash));

            TablesHeap.AssemblyRefTable.Set(rid, ref row);
            return(rid);
        }
        static string GetString(StringsHeap heap, ColumnInfo column, HexPosition position)
        {
            if (heap == null)
            {
                return(null);
            }
            uint value = column.Size == 2 ? heap.Span.Buffer.ReadUInt16(position) : heap.Span.Buffer.ReadUInt32(position);

            if (value == 0)
            {
                return(null);
            }
            const int MAX_LEN = 0x400;

            return(heap.Read(value, MAX_LEN));
        }
예제 #4
0
        public uint CreateAssemblyRef(IAssembly assembly)
        {
            var rid = TablesHeap.AssemblyRefTable.Create();
            var row = TablesHeap.AssemblyRefTable.Get(rid);

            row.MajorVersion     = (ushort)assembly.Version.Major;
            row.MinorVersion     = (ushort)assembly.Version.Minor;
            row.BuildNumber      = (ushort)assembly.Version.Build;
            row.RevisionNumber   = (ushort)assembly.Version.Revision;
            row.Flags            = (uint)assembly.Attributes;
            row.PublicKeyOrToken = BlobHeap.Create(GetPublicKeyOrTokenBytes(assembly.PublicKeyOrToken));
            row.Name             = StringsHeap.Create(assembly.Name);
            row.Locale           = StringsHeap.Create(assembly.Culture);
            row.HashValue        = BlobHeap.Create((assembly as AssemblyRef)?.Hash);
            return(rid);
        }
예제 #5
0
        static object ReadStringToken(int col, MetadataTable tbl, MetadataReader rdr, uint[] lens)
        {
            if (rdr.BaseStream.Root[MetadataStreamType.Strings] == null)
            {
                rdr.ReadUInt16();
                return(StringToken.Null);
            }
            StringsHeap sh = rdr.BaseStream.Root[MetadataStreamType.Strings].Heap as StringsHeap;
            uint        tkn;

            if (sh.Stream.Length > ushort.MaxValue)
            {
                tkn = rdr.ReadUInt32();
            }
            else
            {
                tkn = rdr.ReadUInt16();
            }
            return(sh.Resolve(new MetadataToken(tkn)));
        }
예제 #6
0
        public void Reconstruct()
        {
            newStringsHeap = new StringsHeap(netHeader, netHeader.StringsHeap.headeroffset, new Structures.METADATA_STREAM_HEADER(), "#Strings");
            newStringsHeap.binWriter.Write((byte)0);

            RemoveEmptyTables();
            WriteMetaDataTablessHeaders();
            WriteMetaDataRows();
            UpdateHeapOffsetSizes();
            WriteTablesHeapHeader();

            netHeader.ClearCache();
            int stringsHeapIndex = netHeader.MetaDataStreams.FindIndex(s => s is StringsHeap);

            netHeader.MetaDataStreams[stringsHeapIndex] = newStringsHeap;

            tablesHeap.MakeEmpty();
            tablesHeap.mainStream        = stream;
            tablesHeap.binWriter         = new BinaryWriter(stream);
            tablesHeap.binReader         = new BinaryReader(stream);
            tablesHeap.streamHeader.Size = (uint)stream.Length;
        }
예제 #7
0
        ResourceInfo[] CreateResourceInfos(HexBufferFile file, MDTable resourceTable, StringsHeap stringsHeap)
        {
            if (resourceTable == null)
            {
                return(Array.Empty <ResourceInfo>());
            }
            var list = new List <ResourceInfo>((int)resourceTable.Rows);

            var recordPos = resourceTable.Span.Start;
            var buffer    = file.Buffer;

            for (uint rid = 1; rid <= resourceTable.Rows; rid++, recordPos += resourceTable.RowSize)
            {
                uint offset     = buffer.ReadUInt32(recordPos);
                uint nameOffset = resourceTable.TableInfo.Columns[2].Size == 2 ?
                                  buffer.ReadUInt16(recordPos + 8) :
                                  buffer.ReadUInt32(recordPos + 8);
                uint implementation = resourceTable.TableInfo.Columns[3].Size == 2 ?
                                      buffer.ReadUInt16(recordPos + resourceTable.RowSize - 2) :
                                      buffer.ReadUInt32(recordPos + resourceTable.RowSize - 4);

                if (!CodedToken.Implementation.Decode(implementation, out MDToken implementationToken))
                {
                    continue;
                }
                if (implementationToken.Rid != 0)
                {
                    continue;
                }

                var resourceSpan = GetResourceSpan(file.Buffer, offset);
                if (resourceSpan == null)
                {
                    continue;
                }

                var token        = new MDToken(Table.ManifestResource, rid);
                var filteredName = NameUtils.FilterName(stringsHeap?.Read(nameOffset) ?? string.Empty);
                list.Add(new ResourceInfo(token.Raw, resourceSpan.Value, filteredName));
            }

            list.Sort(ResourceInfoComparer.Instance);
            return(list.ToArray());
        }
예제 #8
0
 public virtual void VisitStringsHeap(StringsHeap heap)
 {
 }
예제 #9
0
 public override void VisitStringsHeap(StringsHeap heap)
 {
     this.asm.StaticArray(moduleName + " StringsHeap", heap.Data);
 }
 public virtual void VisitStringsHeap(StringsHeap heap)
 {
 }
예제 #11
0
 internal StringToken(StringsHeap h) : base(h)
 {
 }
예제 #12
0
        DotNetHeap[] CreateCompressedHeaps()
        {
            var         list        = new List <DotNetHeap>();
            StringsHeap stringsHeap = null;
            USHeap      usHeap      = null;
            BlobHeap    blobHeap    = null;
            GUIDHeap    guidHeap    = null;
            TablesHeap  tablesHeap  = null;
            PdbHeap     pdbHeap     = null;

            for (int i = storageStreamHeaders.Length - 1; i >= 0; i--)
            {
                var ssh  = storageStreamHeaders[i];
                var span = new HexBufferSpan(file.Buffer, ssh.DataSpan);

                switch (ssh.Name)
                {
                case "#Strings":
                    if (stringsHeap == null)
                    {
                        stringsHeap = new StringsHeapImpl(span);
                        list.Add(stringsHeap);
                        continue;
                    }
                    break;

                case "#US":
                    if (usHeap == null)
                    {
                        usHeap = new USHeapImpl(span);
                        list.Add(usHeap);
                        continue;
                    }
                    break;

                case "#Blob":
                    if (blobHeap == null)
                    {
                        blobHeap = new BlobHeapImpl(span);
                        list.Add(blobHeap);
                        continue;
                    }
                    break;

                case "#GUID":
                    if (guidHeap == null)
                    {
                        guidHeap = new GUIDHeapImpl(span);
                        list.Add(guidHeap);
                        continue;
                    }
                    break;

                case "#~":
                    if (tablesHeap == null && span.Length >= TablesHeapImpl.MinimumSize)
                    {
                        tablesHeap = new TablesHeapImpl(span, TablesHeapType.Compressed);
                        list.Add(tablesHeap);
                        continue;
                    }
                    break;

                case "#!":
                    list.Add(new HotHeapImpl(span));
                    continue;

                case "#Pdb":
                    if (pdbHeap == null && span.Length >= PdbHeapImpl.MinimumSize)
                    {
                        pdbHeap = new PdbHeapImpl(span);
                        list.Add(pdbHeap);
                        continue;
                    }
                    break;
                }
                list.Add(new UnknownHeapImpl(span));
            }

            list.Reverse();
            return(list.ToArray());
        }
예제 #13
0
        DotNetHeap[] CreateENCHeaps()
        {
            var         list        = new List <DotNetHeap>();
            StringsHeap stringsHeap = null;
            USHeap      usHeap      = null;
            BlobHeap    blobHeap    = null;
            GUIDHeap    guidHeap    = null;
            TablesHeap  tablesHeap  = null;

            foreach (var ssh in storageStreamHeaders)
            {
                var span = new HexBufferSpan(file.Buffer, ssh.DataSpan);

                switch (ssh.Name.ToUpperInvariant())
                {
                case "#STRINGS":
                    if (stringsHeap == null)
                    {
                        stringsHeap = new StringsHeapImpl(span);
                        list.Add(stringsHeap);
                        continue;
                    }
                    break;

                case "#US":
                    if (usHeap == null)
                    {
                        usHeap = new USHeapImpl(span);
                        list.Add(usHeap);
                        continue;
                    }
                    break;

                case "#BLOB":
                    if (blobHeap == null)
                    {
                        blobHeap = new BlobHeapImpl(span);
                        list.Add(blobHeap);
                        continue;
                    }
                    break;

                case "#GUID":
                    if (guidHeap == null)
                    {
                        guidHeap = new GUIDHeapImpl(span);
                        list.Add(guidHeap);
                        continue;
                    }
                    break;

                case "#~":                      // Only if #Schema is used
                case "#-":
                    if (tablesHeap == null && span.Length >= TablesHeapImpl.MinimumSize)
                    {
                        tablesHeap = new TablesHeapImpl(span, TablesHeapType.ENC);
                        list.Add(tablesHeap);
                        continue;
                    }
                    break;
                }
                list.Add(new UnknownHeapImpl(span));
            }
            return(list.ToArray());
        }
예제 #14
0
        private ValueType GetStringIndex(Workspace workspace, string str)
        {
            StringsHeap stringsHeap = workspace.GetStream <StringsHeap>();

            return(GetHeapOffset(stringsHeap, stringsHeap.GetStringOffset(str)));
        }
예제 #15
0
        internal MetadataRow(MetadataTable tbl, bool needInit)
            : base(tbl)
        {
            vals = new object[tbl.TableDef.Columns.Length];
            par  = tbl;
            if (!needInit)
            {
                return;
            }

            BlobHeap    bh = tbl.Heap.Stream.Root[MetadataStreamType.Blob].Heap as BlobHeap;
            StringsHeap sh = tbl.Heap.Stream.Root[MetadataStreamType.Strings].Heap as StringsHeap;
            GUIDHeap    gh = tbl.Heap.Stream.Root[MetadataStreamType.GUID].Heap as GUIDHeap;

            foreach (MetadataColumn col in tbl.Columns)
            {
                if (col.Type is Type)
                {
                    if ((col.Type as Type).IsEnum)
                    {
                        this[col.Index] = Enum.ToObject(col.Type as Type, 0);
                    }
                    else
                    {
                        switch ((col.Type as Type).FullName)
                        {
                        case "System.Byte":
                            this[col.Index] = (byte)0;
                            break;

                        case "System.UInt16":
                            this[col.Index] = (ushort)0;
                            break;

                        case "System.UInt32":
                            this[col.Index] = (uint)0;
                            break;

                        case "NetPE.Core.Rva":
                            this[col.Index] = (Rva)0;
                            break;

                        case "NetPE.Core.Metadata.BlobToken":
                            this[col.Index] = bh.Resolve(new MetadataToken(MetadataTokenType.Unknown, 0));
                            break;

                        case "NetPE.Core.Metadata.GUIDToken":
                            this[col.Index] = gh.Resolve(new MetadataToken(MetadataTokenType.Unknown, 0));
                            break;

                        case "NetPE.Core.Metadata.StringToken":
                            this[col.Index] = sh.Resolve(new MetadataToken(MetadataTokenType.Unknown, 0));
                            break;
                        }
                    }
                }
                else if (col.Type is TableType)
                {
                    this[col.Index] = new TableToken(tbl.Heap, new MetadataToken((MetadataTokenType)(TableType)col.Type, 0));
                }
                else if (col.Type is CodedIndex)
                {
                    this[col.Index] = new TableToken(tbl.Heap, new MetadataToken((MetadataTokenType)CodedIndexDefs.MdCodedIndexDefs[(CodedIndex)col.Type].TableTypes[0].Key, 0));
                }
            }
        }