Esempio n. 1
0
        static Dictionary <long, MethodExportInfo> GetOffsetToExportInfoDictionary(IImageStream reader, IPEImage peImage, ImageDataDirectory exportHdr, CpuArch cpuArch)
        {
            reader.Position = (long)peImage.ToFileOffset(exportHdr.VirtualAddress);
            // Skip Characteristics(4), TimeDateStamp(4), MajorVersion(2), MinorVersion(2), Name(4)
            reader.Position += 16;
            uint ordinalBase         = reader.ReadUInt32();
            int  numFuncs            = reader.ReadInt32();
            int  numNames            = reader.ReadInt32();
            long offsetOfFuncs       = (long)peImage.ToFileOffset((RVA)reader.ReadUInt32());
            long offsetOfNames       = (long)peImage.ToFileOffset((RVA)reader.ReadUInt32());
            long offsetOfNameIndexes = (long)peImage.ToFileOffset((RVA)reader.ReadUInt32());

            var names = ReadNames(reader, peImage, numNames, offsetOfNames, offsetOfNameIndexes);

            reader.Position = offsetOfFuncs;
            var allInfos = new MethodExportInfo[numFuncs];
            var dict     = new Dictionary <long, MethodExportInfo>(numFuncs);

            for (int i = 0; i < allInfos.Length; i++)
            {
                var  currOffset = reader.Position;
                var  nextOffset = reader.Position + 4;
                uint funcRva    = 0;
                var  rva        = (RVA)reader.ReadUInt32();
                reader.Position = (long)peImage.ToFileOffset(rva);
                bool rvaValid   = rva != 0 && cpuArch.TryGetExportedRvaFromStub(reader, peImage, out funcRva);
                long funcOffset = rvaValid ? (long)peImage.ToFileOffset((RVA)funcRva) : 0;
                var  exportInfo = new MethodExportInfo((ushort)(ordinalBase + (uint)i));
                if (funcOffset != 0)
                {
                    dict[funcOffset] = exportInfo;
                }
                allInfos[i]     = exportInfo;
                reader.Position = nextOffset;
            }

            foreach (var info in names)
            {
                int index = info.Index;
                if ((uint)index >= (uint)numFuncs)
                {
                    continue;
                }
                allInfos[index].Ordinal = null;
                allInfos[index].Name    = info.Name;
            }

            return(dict);
        }
Esempio n. 2
0
 public void Read(IImageStream stream)
 {
     index            = stream.ReadInt32();
     stream.Position += 10;
     attributes       = GetAttributes(stream.ReadUInt16());
     name             = PdbReader.ReadCString(stream);
 }
Esempio n. 3
0
		public void Read(IImageStream stream) {
			stream.Position = 0;
			Language = new Guid(stream.ReadBytes(0x10));
			LanguageVendor = new Guid(stream.ReadBytes(0x10));
			DocumentType = new Guid(stream.ReadBytes(0x10));
			CheckSumAlgorithmId = new Guid(stream.ReadBytes(0x10));

			var len = stream.ReadInt32();
			if (stream.ReadUInt32() != 0)
				throw new PdbException("Unexpected value");

			CheckSum = stream.ReadBytes(len);
		}
Esempio n. 4
0
        public void Read(IImageStream stream)
        {
            stream.Position     = 0;
            Language            = new Guid(stream.ReadBytes(0x10));
            LanguageVendor      = new Guid(stream.ReadBytes(0x10));
            DocumentType        = new Guid(stream.ReadBytes(0x10));
            CheckSumAlgorithmId = new Guid(stream.ReadBytes(0x10));

            var len = stream.ReadInt32();

            if (stream.ReadUInt32() != 0)
            {
                throw new PdbException("Unexpected value");
            }

            CheckSum = stream.ReadBytes(len);
        }
Esempio n. 5
0
        public void Read(IImageStream stream, long recEnd)
        {
            stream.Position += 4;
            var end = stream.ReadUInt32();

            stream.Position += 4;
            var len = stream.ReadUInt32();

            stream.Position += 8;
            token            = stream.ReadInt32();
            Address          = PdbAddress.ReadAddress(stream);
            stream.Position += 1 + 2;
            Name             = PdbReader.ReadCString(stream);

            stream.Position = recEnd;
            Root            = new DbiScope(this, null, "", Address.Offset, len);
            Root.Read(new RecursionCounter(), stream, end);
            FixOffsets(new RecursionCounter(), Root);
        }
Esempio n. 6
0
        void ReadLines(DbiFunction[] funcs, Dictionary <long, DbiDocument> documents, IImageStream stream, long end)
        {
            var address = PdbAddress.ReadAddress(stream);

            int first = 0;
            int last  = funcs.Length - 1;
            int found = -1;

            while (first <= last)
            {
                var index = first + ((last - first) >> 1);
                var addr  = funcs[index].Address;
                if (addr < address)
                {
                    first = index + 1;
                }
                else if (addr > address)
                {
                    last = index - 1;
                }
                else
                {
                    found = index;
                    break;
                }
            }
            if (found == -1)
            {
                return;
            }

            var flags = stream.ReadUInt16();

            stream.Position += 4;

            if (funcs[found].Lines == null)
            {
                while (found > 0)
                {
                    var prevFunc = funcs[found - 1];
                    if (prevFunc != null || prevFunc.Address != address)
                    {
                        break;
                    }
                    found--;
                }
            }
            else
            {
                while (found < funcs.Length - 1 && funcs[found] != null)
                {
                    var nextFunc = funcs[found + 1];
                    if (nextFunc.Address != address)
                    {
                        break;
                    }
                    found++;
                }
            }
            var func = funcs[found];

            if (func.Lines != null)
            {
                return;
            }
            func.Lines = new List <SymbolSequencePoint>();

            while (stream.Position < end)
            {
                var document = documents[stream.ReadUInt32()];
                var count    = stream.ReadUInt32();
                stream.Position += 4;

                const int LINE_ENTRY_SIZE = 8;
                const int COL_ENTRY_SIZE  = 4;
                var       lineTablePos    = stream.Position;
                var       colTablePos     = stream.Position + count * LINE_ENTRY_SIZE;

                for (uint i = 0; i < count; i++)
                {
                    stream.Position = lineTablePos + i * LINE_ENTRY_SIZE;

                    var line = new SymbolSequencePoint {
                        Document = document
                    };
                    line.Offset = stream.ReadInt32();
                    var lineFlags = stream.ReadUInt32();

                    line.Line    = (int)(lineFlags & 0x00ffffff);
                    line.EndLine = line.Line + (int)((lineFlags >> 24) & 0x7F);
                    if ((flags & 1) != 0)
                    {
                        stream.Position = colTablePos + i * COL_ENTRY_SIZE;
                        line.Column     = stream.ReadUInt16();
                        line.EndColumn  = stream.ReadUInt16();
                    }

                    func.Lines.Add(line);
                }
            }
        }
Esempio n. 7
0
        object ReadValue(SerializationType etype, TypeSig argType, out TypeSig realArgType)
        {
            if (!recursionCounter.Increment())
            {
                throw new CABlobParserException("Too much recursion");
            }

            object result;

            switch (etype)
            {
            case SerializationType.Boolean:
                realArgType = module.CorLibTypes.Boolean;
                result      = reader.ReadByte() != 0;
                break;

            case SerializationType.Char:
                realArgType = module.CorLibTypes.Char;
                result      = (char)reader.ReadUInt16();
                break;

            case SerializationType.I1:
                realArgType = module.CorLibTypes.SByte;
                result      = reader.ReadSByte();
                break;

            case SerializationType.U1:
                realArgType = module.CorLibTypes.Byte;
                result      = reader.ReadByte();
                break;

            case SerializationType.I2:
                realArgType = module.CorLibTypes.Int16;
                result      = reader.ReadInt16();
                break;

            case SerializationType.U2:
                realArgType = module.CorLibTypes.UInt16;
                result      = reader.ReadUInt16();
                break;

            case SerializationType.I4:
                realArgType = module.CorLibTypes.Int32;
                result      = reader.ReadInt32();
                break;

            case SerializationType.U4:
                realArgType = module.CorLibTypes.UInt32;
                result      = reader.ReadUInt32();
                break;

            case SerializationType.I8:
                realArgType = module.CorLibTypes.Int64;
                result      = reader.ReadInt64();
                break;

            case SerializationType.U8:
                realArgType = module.CorLibTypes.UInt64;
                result      = reader.ReadUInt64();
                break;

            case SerializationType.R4:
                realArgType = module.CorLibTypes.Single;
                result      = reader.ReadSingle();
                break;

            case SerializationType.R8:
                realArgType = module.CorLibTypes.Double;
                result      = reader.ReadDouble();
                break;

            case SerializationType.String:
                realArgType = module.CorLibTypes.String;
                result      = ReadUTF8String();
                break;

            // It's ET.ValueType if it's eg. a ctor enum arg type
            case (SerializationType)ElementType.ValueType:
                if (argType == null)
                {
                    throw new CABlobParserException("Invalid element type");
                }
                realArgType = argType;
                result      = ReadEnumValue(GetEnumUnderlyingType(argType));
                break;

            // It's ET.Object if it's a ctor object arg type
            case (SerializationType)ElementType.Object:
            case SerializationType.TaggedObject:
                realArgType = ReadFieldOrPropType();
                var arraySig = realArgType as SZArraySig;
                if (arraySig != null)
                {
                    result = ReadArrayArgument(arraySig);
                }
                else
                {
                    TypeSig tmpType;
                    result = ReadValue((SerializationType)realArgType.ElementType, realArgType, out tmpType);
                }
                break;

            // It's ET.Class if it's eg. a ctor System.Type arg type
            case (SerializationType)ElementType.Class:
                var tdr = argType as TypeDefOrRefSig;
                if (tdr != null && tdr.DefinitionAssembly.IsCorLib() && tdr.Namespace == "System")
                {
                    if (tdr.TypeName == "Type")
                    {
                        result = ReadValue(SerializationType.Type, tdr, out realArgType);
                        break;
                    }
                    if (tdr.TypeName == "String")
                    {
                        result = ReadValue(SerializationType.String, tdr, out realArgType);
                        break;
                    }
                    if (tdr.TypeName == "Object")
                    {
                        result = ReadValue(SerializationType.TaggedObject, tdr, out realArgType);
                        break;
                    }
                }

                // Assume it's an enum that couldn't be resolved
                realArgType = argType;
                return(ReadEnumValue(null));

            case SerializationType.Type:
                realArgType = argType;
                result      = ReadType();
                break;

            case SerializationType.Enum:
                realArgType = ReadType();
                result      = ReadEnumValue(GetEnumUnderlyingType(realArgType));
                break;

            default:
                throw new CABlobParserException("Invalid element type");
            }

            recursionCounter.Decrement();
            return(result);
        }
Esempio n. 8
0
        public static bool TryReadNumeric(IImageStream stream, long end, out object value)
        {
            value = null;
            if (stream.Position + 2 > end)
            {
                return(false);
            }
            var numLeaf = (NumericLeaf)stream.ReadUInt16();

            if (numLeaf < NumericLeaf.LF_NUMERIC)
            {
                value = (short)numLeaf;
                return(true);
            }

            switch (numLeaf)
            {
            case NumericLeaf.LF_CHAR:
                if (stream.Position > end)
                {
                    return(false);
                }
                value = stream.ReadSByte();
                return(true);

            case NumericLeaf.LF_SHORT:
                if (stream.Position + 2 > end)
                {
                    return(false);
                }
                value = stream.ReadInt16();
                return(true);

            case NumericLeaf.LF_USHORT:
                if (stream.Position + 2 > end)
                {
                    return(false);
                }
                value = stream.ReadUInt16();
                return(true);

            case NumericLeaf.LF_LONG:
                if (stream.Position + 4 > end)
                {
                    return(false);
                }
                value = stream.ReadInt32();
                return(true);

            case NumericLeaf.LF_ULONG:
                if (stream.Position + 4 > end)
                {
                    return(false);
                }
                value = stream.ReadUInt32();
                return(true);

            case NumericLeaf.LF_REAL32:
                if (stream.Position + 4 > end)
                {
                    return(false);
                }
                value = stream.ReadSingle();
                return(true);

            case NumericLeaf.LF_REAL64:
                if (stream.Position + 8 > end)
                {
                    return(false);
                }
                value = stream.ReadDouble();
                return(true);

            case NumericLeaf.LF_QUADWORD:
                if (stream.Position + 8 > end)
                {
                    return(false);
                }
                value = stream.ReadInt64();
                return(true);

            case NumericLeaf.LF_UQUADWORD:
                if (stream.Position + 8 > end)
                {
                    return(false);
                }
                value = stream.ReadUInt64();
                return(true);

            case NumericLeaf.LF_VARSTRING:
                if (stream.Position + 2 > end)
                {
                    return(false);
                }
                int varStrLen = stream.ReadUInt16();
                if (stream.Position + varStrLen > end)
                {
                    return(false);
                }
                value = Encoding.UTF8.GetString(stream.ReadBytes(varStrLen));
                return(true);

            case NumericLeaf.LF_VARIANT:
                if (stream.Position + 0x10 > end)
                {
                    return(false);
                }
                int  v0    = stream.ReadInt32();
                int  v1    = stream.ReadInt32();
                int  v2    = stream.ReadInt32();
                int  v3    = stream.ReadInt32();
                byte scale = (byte)(v0 >> 16);
                if (scale <= 28)
                {
                    value = new decimal(v2, v3, v1, v0 < 0, scale);
                }
                else
                {
                    value = null;
                }
                return(true);

            default:
                return(false);
            }
        }
Esempio n. 9
0
        bool ReadCore(out TypeSig type, out object value)
        {
            if (!recursionCounter.Increment())
            {
                type  = null;
                value = null;
                return(false);
            }

            bool          res;
            ITypeDefOrRef tdr;
            UTF8String    ns, name;
            var           et = (ElementType)reader.ReadByte();

            switch (et)
            {
            case ElementType.Boolean:
                type  = module.CorLibTypes.Boolean;
                value = reader.ReadBoolean();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.Char:
                type  = module.CorLibTypes.Char;
                value = (char)reader.ReadUInt16();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.I1:
                type  = module.CorLibTypes.SByte;
                value = reader.ReadSByte();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.U1:
                type  = module.CorLibTypes.Byte;
                value = reader.ReadByte();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.I2:
                type  = module.CorLibTypes.Int16;
                value = reader.ReadInt16();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.U2:
                type  = module.CorLibTypes.UInt16;
                value = reader.ReadUInt16();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.I4:
                type  = module.CorLibTypes.Int32;
                value = reader.ReadInt32();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.U4:
                type  = module.CorLibTypes.UInt32;
                value = reader.ReadUInt32();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.I8:
                type  = module.CorLibTypes.Int64;
                value = reader.ReadInt64();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.U8:
                type  = module.CorLibTypes.UInt64;
                value = reader.ReadUInt64();
                if (reader.Position < reader.Length)
                {
                    type = ReadTypeDefOrRefSig();
                }
                res = true;
                break;

            case ElementType.R4:
                type  = module.CorLibTypes.Single;
                value = reader.ReadSingle();
                res   = true;
                break;

            case ElementType.R8:
                type  = module.CorLibTypes.Double;
                value = reader.ReadDouble();
                res   = true;
                break;

            case ElementType.String:
                type  = module.CorLibTypes.String;
                value = ReadString();
                res   = true;
                break;

            case ElementType.Ptr:
                res = Read(out type, out value);
                if (res)
                {
                    type = new PtrSig(type);
                }
                break;

            case ElementType.ByRef:
                res = Read(out type, out value);
                if (res)
                {
                    type = new ByRefSig(type);
                }
                break;

            case ElementType.Object:
                type  = module.CorLibTypes.Object;
                value = null;
                res   = true;
                break;

            case ElementType.ValueType:
                tdr   = ReadTypeDefOrRef();
                type  = tdr.ToTypeSig();
                value = null;
                if (GetName(tdr, out ns, out name) && ns == stringSystem && tdr.DefinitionAssembly.IsCorLib())
                {
                    if (name == stringDecimal)
                    {
                        if (reader.Length - reader.Position != 13)
                        {
                            goto default;
                        }
                        try {
                            byte b = reader.ReadByte();
                            value = new Decimal(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32(), (b & 0x80) != 0, (byte)(b & 0x7F));
                        }
                        catch {
                            goto default;
                        }
                    }
                    else if (name == stringDateTime)
                    {
                        if (reader.Length - reader.Position != 8)
                        {
                            goto default;
                        }
                        try {
                            value = new DateTime(reader.ReadInt64());
                        }
                        catch {
                            goto default;
                        }
                    }
                }
                if (value == null && reader.Position != reader.Length)
                {
                    value = reader.ReadRemainingBytes();
                }
                res = true;
                break;

            case ElementType.Class:
                type  = new ClassSig(ReadTypeDefOrRef());
                value = reader.Position == reader.Length ? null : reader.ReadRemainingBytes();
                res   = true;
                break;

            case ElementType.CModReqd:
                tdr = ReadTypeDefOrRef();
                res = Read(out type, out value);
                if (res)
                {
                    type = new CModReqdSig(tdr, type);
                }
                break;

            case ElementType.CModOpt:
                tdr = ReadTypeDefOrRef();
                res = Read(out type, out value);
                if (res)
                {
                    type = new CModOptSig(tdr, type);
                }
                break;

            case ElementType.Var:
            case ElementType.Array:
            case ElementType.GenericInst:
            case ElementType.TypedByRef:
            case ElementType.I:
            case ElementType.U:
            case ElementType.FnPtr:
            case ElementType.SZArray:
            case ElementType.MVar:
            case ElementType.End:
            case ElementType.Void:
            case ElementType.ValueArray:
            case ElementType.R:
            case ElementType.Internal:
            case ElementType.Module:
            case ElementType.Sentinel:
            case ElementType.Pinned:
            default:
                Debug.Fail("Unsupported element type in LocalConstant sig blob: " + et.ToString());
                res   = false;
                type  = null;
                value = null;
                break;
            }

            recursionCounter.Decrement();
            return(res);
        }
Esempio n. 10
0
        /// <summary>
        /// Reads the next type
        /// </summary>
        /// <returns>A new <see cref="TypeSig"/> instance or <c>null</c> if invalid element type</returns>
        TypeSig ReadType()
        {
            if (!recursionCounter.Increment())
            {
                return(null);
            }

            uint    num;
            TypeSig nextType, result = null;

            switch ((ElementType)reader.ReadByte())
            {
            case ElementType.Void:          result = corLibTypes.Void; break;

            case ElementType.Boolean:       result = corLibTypes.Boolean; break;

            case ElementType.Char:          result = corLibTypes.Char; break;

            case ElementType.I1:            result = corLibTypes.SByte; break;

            case ElementType.U1:            result = corLibTypes.Byte; break;

            case ElementType.I2:            result = corLibTypes.Int16; break;

            case ElementType.U2:            result = corLibTypes.UInt16; break;

            case ElementType.I4:            result = corLibTypes.Int32; break;

            case ElementType.U4:            result = corLibTypes.UInt32; break;

            case ElementType.I8:            result = corLibTypes.Int64; break;

            case ElementType.U8:            result = corLibTypes.UInt64; break;

            case ElementType.R4:            result = corLibTypes.Single; break;

            case ElementType.R8:            result = corLibTypes.Double; break;

            case ElementType.String:        result = corLibTypes.String; break;

            case ElementType.TypedByRef: result = corLibTypes.TypedReference; break;

            case ElementType.I:                     result = corLibTypes.IntPtr; break;

            case ElementType.U:                     result = corLibTypes.UIntPtr; break;

            case ElementType.Object:        result = corLibTypes.Object; break;

            case ElementType.Ptr:           result = new PtrSig(ReadType()); break;

            case ElementType.ByRef:         result = new ByRefSig(ReadType()); break;

            case ElementType.ValueType:     result = new ValueTypeSig(ReadTypeDefOrRef()); break;

            case ElementType.Class:         result = new ClassSig(ReadTypeDefOrRef()); break;

            case ElementType.FnPtr:         result = new FnPtrSig(ReadSig()); break;

            case ElementType.SZArray:       result = new SZArraySig(ReadType()); break;

            case ElementType.CModReqd:      result = new CModReqdSig(ReadTypeDefOrRef(), ReadType()); break;

            case ElementType.CModOpt:       result = new CModOptSig(ReadTypeDefOrRef(), ReadType()); break;

            case ElementType.Sentinel:      result = new SentinelSig(); break;

            case ElementType.Pinned:        result = new PinnedSig(ReadType()); break;

            case ElementType.Var:
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new GenericVar(num);
                break;

            case ElementType.MVar:
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new GenericMVar(num);
                break;

            case ElementType.ValueArray:
                nextType = ReadType();
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new ValueArraySig(nextType, num);
                break;

            case ElementType.Module:
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new ModuleSig(num, ReadType());
                break;

            case ElementType.GenericInst:
                nextType = ReadType();
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                var genericInstSig = new GenericInstSig(nextType as ClassOrValueTypeSig, num);
                var args           = genericInstSig.GenericArguments;
                for (uint i = 0; i < num; i++)
                {
                    args.Add(ReadType());
                }
                result = genericInstSig;
                break;

            case ElementType.Array:
                nextType = ReadType();
                uint rank;
                if (!reader.ReadCompressedUInt32(out rank))
                {
                    break;
                }
                if (rank == 0)
                {
                    result = new ArraySig(nextType, rank);
                    break;
                }
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                var sizes = new List <uint>((int)num);
                for (uint i = 0; i < num; i++)
                {
                    uint size;
                    if (!reader.ReadCompressedUInt32(out size))
                    {
                        goto exit;
                    }
                    sizes.Add(size);
                }
                if (!reader.ReadCompressedUInt32(out num))
                {
                    break;
                }
                var lowerBounds = new List <int>((int)num);
                for (uint i = 0; i < num; i++)
                {
                    int size;
                    if (!reader.ReadCompressedInt32(out size))
                    {
                        goto exit;
                    }
                    lowerBounds.Add(size);
                }
                result = new ArraySig(nextType, rank, sizes, lowerBounds);
                break;

            case ElementType.Internal:
                IntPtr address;
                if (IntPtr.Size == 4)
                {
                    address = new IntPtr(reader.ReadInt32());
                }
                else
                {
                    address = new IntPtr(reader.ReadInt64());
                }
                result = helper.ConvertRTInternalAddress(address);
                break;

            case ElementType.End:
            case ElementType.R:
            default:
                result = null;
                break;
            }
exit:
            recursionCounter.Decrement();
            return(result);
        }