Ejemplo n.º 1
0
        public MetadataTable Load(TablesHeap h, MetadataReader rdr, uint[] lens, TableType type)
        {
            MetadataTable ret = new MetadataTable(h, type);

            Reader[] read = new Reader[ret.Columns.Length];
            for (int i = 0; i < ret.Columns.Length; i++)
            {
                int k             = i;
                var retColTypeObj = ret.Columns[i].Type;
                if (retColTypeObj is Type)
                {
                    var retColType = retColTypeObj as Type;
                    //if (retColType.IsSubclassOf(typeof(Enum)))
                    if (retColType.IsEnum)
                    {
                        var underEnumType = Enum.GetUnderlyingType(retColType);
                        //read[i] = DicEnumReader[underEnumType];
                        if (underEnumType == typeof(byte))
                        {
                            read[i] = new Reader(ReadByteFlag);
                        }
                        else if (underEnumType == typeof(System.UInt16))
                        {
                            read[i] = new Reader(ReadUInt16Flag);
                        }
                        else if (underEnumType == typeof(System.UInt32))
                        {
                            read[i] = new Reader(ReadUInt32Flag);
                        }

                        //switch (Enum.GetUnderlyingType(retColType).FullName)
                        //{
                        //    case "System.Byte":
                        //        read[i] = new Reader(ReadByteFlag);
                        //        break;
                        //    case "System.UInt16":
                        //        read[i] = new Reader(ReadUInt16Flag);
                        //        break;
                        //    case "System.UInt32":
                        //        read[i] = new Reader(ReadUInt32Flag);
                        //        break;
                        //}
                    }
                    else
                    {
                        //read[i] = DicReader[retColType];
                        if (retColType == typeof(byte))
                        {
                            read[i] = new Reader(ReadByte);
                        }
                        else if (retColType == typeof(System.UInt16))
                        {
                            read[i] = new Reader(ReadUInt16);
                        }
                        else if (retColType == typeof(System.UInt32))
                        {
                            read[i] = new Reader(ReadUInt32);
                        }
                        else if (retColType == typeof(NetPE.Core.Rva))
                        {
                            read[i] = new Reader(ReadRva);
                        }
                        else if (retColType == typeof(NetPE.Core.Metadata.BlobToken))
                        {
                            read[i] = new Reader(ReadBlobToken);
                        }
                        else if (retColType == typeof(NetPE.Core.Metadata.GUIDToken))
                        {
                            read[i] = new Reader(ReadGUIDToken);
                        }
                        else if (retColType == typeof(NetPE.Core.Metadata.StringToken))
                        {
                            read[i] = new Reader(ReadStringToken);
                        }


                        //switch ((ret.Columns[i].Type as Type).FullName)
                        //{
                        //    case "System.Byte":
                        //        read[i] = new Reader(ReadByte);
                        //        break;
                        //    case "System.UInt16":
                        //        read[i] = new Reader(ReadUInt16);
                        //        break;
                        //    case "System.UInt32":
                        //        read[i] = new Reader(ReadUInt32);
                        //        break;
                        //    case "NetPE.Core.Rva":
                        //        read[i] = new Reader(ReadRva);
                        //        break;
                        //    case "NetPE.Core.Metadata.BlobToken":
                        //        read[i] = new Reader(ReadBlobToken);
                        //        break;
                        //    case "NetPE.Core.Metadata.GUIDToken":
                        //        read[i] = new Reader(ReadGUIDToken);
                        //        break;
                        //    case "NetPE.Core.Metadata.StringToken":
                        //        read[i] = new Reader(ReadStringToken);
                        //        break;
                        //}
                    }
                }
                else if (retColTypeObj is TableType)
                {
                    read[i] = new Reader(ReadTableToken);
                }
                else if (retColTypeObj is CodedIndex)
                {
                    read[i] = new Reader(ReadCodedToken);
                }
            }

            List <Rva> rvas = new List <Rva>();

            for (int i = 1; i <= lens[(int)ret.Type]; i++)
            {
                MetadataRow r = new MetadataRow(ret, false);

                bool hasRva = ret.Type == TableType.MethodDef || ret.Type == TableType.FieldRVA;
                int  rvaIdx = 0;
                Rva  rva    = 0;

                for (int ii = 0; ii < read.Length; ii++)
                {
                    if (hasRva && (ret.Columns[ii].Type is Type) && ((ret.Columns[ii].Type as Type) == typeof(NetPE.Core.Rva)))
                    {
                        rvaIdx = ii;
                        rva    = (Rva)rdr.ReadUInt32();
                    }
                    else
                    {
                        r[ii] = read[ii](ii, ret, rdr, lens);
                    }
                }
                if (hasRva)
                {
                    r[rvaIdx] = rva;
                    rvas.Add(rva);
                }

                r.Token = new MetadataToken((MetadataTokenType)ret.Type, (uint)i);
                ret.Rows.Add(r);
            }
            ReadRvaData(ret, rdr, rvas, ret.Rows);

            return(ret);
        }
Ejemplo n.º 2
0
        void ReadRvaData(MetadataTable tbl, MetadataReader mdRdr, List <Rva> rvas, MetadataRowCollection rows)
        {
            List <Rva> sorted = new List <Rva>(rvas);

            sorted.Sort();
            for (int i = 0; i < rvas.Count; i++)
            {
                Rva           rva = rvas[i];
                MetadataRow   r   = rows[i + 1];
                byte[]        dat = null;
                VirtualReader rdr = new VirtualReader(mdRdr.BaseStream.File.SectionHeaders.GetVirtualStream());
                if (tbl.Type == TableType.FieldRVA)
                {
                    MetadataRoot root = tbl.Heap.Stream.Root;
                    rdr.SetPosition(rva);
                    MetadataRow     fd     = (r["Field"] as TableToken).ResolveRow();
                    FieldSig        sig    = new FieldSig();
                    SignatureReader sigRdr = new SignatureReader(new MetadataReader(root[MetadataStreamType.Blob]));
                    sigRdr.BaseStream.Position = (fd["Signature"] as BlobToken).Token.Index;
                    sig.Read(sigRdr);
                    int c = 0;
                    switch (sig.Type.Element)
                    {
                    case ElementType.Boolean:
                    case ElementType.UInt8:
                    case ElementType.Int8:
                        c = 1; break;

                    case ElementType.UInt16:
                    case ElementType.Int16:
                    case ElementType.Char:
                        c = 2; break;

                    case ElementType.UInt32:
                    case ElementType.Int32:
                    case ElementType.Single:
                        c = 4; break;

                    case ElementType.UInt64:
                    case ElementType.Int64:
                    case ElementType.Double:
                        c = 8; break;

                    case ElementType.ValueType:
                        TableToken vt = (sig.Type as VALUETYPE).Type;
                        foreach (MetadataRow cl in tbl.Heap[TableType.ClassLayout])
                        {
                            if (cl["Parent"] == vt)
                            {
                                c = (int)cl["ClassSize"];
                                break;
                            }
                        }
                        break;

                    default:
                        throw new InvalidOperationException("ReadRvaData");
                    }
                    dat = rdr.ReadBytes(c);
                }
                else if (tbl.Type == TableType.MethodDef && rva != 0)
                {
                    //MethodBody bdy;
                    //if (((MethodImplAttributes)r["ImplFlags"] & MethodImplAttributes.Native) == MethodImplAttributes.Native)
                    //{
                    //    bdy = new NativeMethodBody(r);
                    //}
                    //else
                    //{
                    //    bdy = new ManagedMethodBody(r);
                    //}
                    //rdr.SetPosition(rva);
                    //bdy.Load(rdr);
                    //rdr.SetPosition(rva);
                    //dat = rdr.ReadBytes((int)bdy.Size);
                    int idx;
                    Rva next;
                    if ((idx = sorted.IndexOf(rva)) == sorted.Count - 1)
                    {
                        CLRDirectory root = tbl.Heap.Stream.Root.Directory;
                        Rva          now;
                        next = uint.MaxValue;
                        rdr.SetPosition(root.Location.Address);
                        rdr.BaseStream.Seek(0x8, System.IO.SeekOrigin.Current);
                        if ((now = rdr.ReadRva()) < next && now != 0 && now > rva)
                        {
                            next = now;
                        }
                        rdr.BaseStream.Seek(0xC, System.IO.SeekOrigin.Current);
                        if ((now = rdr.ReadRva()) < next && now != 0 && now > rva)
                        {
                            next = now;
                        }
                        rdr.BaseStream.Seek(0x4, System.IO.SeekOrigin.Current);
                        if ((now = rdr.ReadRva()) < next && now != 0 && now > rva)
                        {
                            next = now;
                        }
                        rdr.BaseStream.Seek(0x4, System.IO.SeekOrigin.Current);
                        if ((now = rdr.ReadRva()) < next && now != 0 && now > rva)
                        {
                            next = now;
                        }
                        rdr.BaseStream.Seek(0x4, System.IO.SeekOrigin.Current);
                        if ((now = rdr.ReadRva()) < next && now != 0 && now > rva)
                        {
                            next = now;
                        }
                        rdr.BaseStream.Seek(0x4, System.IO.SeekOrigin.Current);
                        if ((now = rdr.ReadRva()) < next && now != 0 && now > rva)
                        {
                            next = now;
                        }
                        rdr.BaseStream.Seek(0x4, System.IO.SeekOrigin.Current);
                        if ((now = rdr.ReadRva()) < next && now != 0 && now > rva)
                        {
                            next = now;
                        }
                    }
                    else
                    {
                        next = sorted[idx + 1];
                    }
                    rdr.SetPosition(rva);
                    dat = rdr.ReadBytes((int)(next - rva));
                }
                if (!tbl.Heap.Stream.Root.Directory.Datas.ContainsAddress(rva) && dat != null)
                {
                    tbl.Heap.Stream.Root.Directory.Datas.Add(new CLRData()
                    {
                        Address = rva, Data = dat
                    });
                }
            }
        }