コード例 #1
0
 public FixupCell(int index, uint tableIndex, uint cellOffset, ReadyToRunSignature signature)
 {
     Index      = index;
     TableIndex = tableIndex;
     CellOffset = cellOffset;
     Signature  = signature;
 }
コード例 #2
0
 public ImportSectionEntry(int index, int startOffset, int startRVA, long section, uint signatureRVA, ReadyToRunSignature signature)
 {
     Index        = index;
     StartOffset  = startOffset;
     StartRVA     = startRVA;
     Section      = section;
     SignatureRVA = signatureRVA;
     Signature    = signature;
 }
コード例 #3
0
        private void DecorateCallSite(PEFile currentFile, bool showMetadataTokens, bool showMetadataTokensInBase10, Instruction instr)
        {
            if (instr.IsCallNearIndirect)
            {
                int importCellAddress = (int)instr.IPRelativeMemoryAddress;
                if (reader.ImportSignatures.ContainsKey(importCellAddress))
                {
                    output.Write(" ; ");
                    ReadyToRunSignature signature = reader.ImportSignatures[importCellAddress];
                    switch (signature)
                    {
                    case MethodDefEntrySignature methodDefSignature:
                        var methodDefToken = MetadataTokens.EntityHandle(unchecked ((int)methodDefSignature.MethodDefToken));
                        if (showMetadataTokens)
                        {
                            if (showMetadataTokensInBase10)
                            {
                                output.WriteReference(currentFile, methodDefToken, $"({MetadataTokens.GetToken(methodDefToken)}) ", "metadata");
                            }
                            else
                            {
                                output.WriteReference(currentFile, methodDefToken, $"({MetadataTokens.GetToken(methodDefToken):X8}) ", "metadata");
                            }
                        }
                        methodDefToken.WriteTo(currentFile, output, Decompiler.Metadata.GenericContext.Empty);
                        break;

                    case MethodRefEntrySignature methodRefSignature:
                        var methodRefToken = MetadataTokens.EntityHandle(unchecked ((int)methodRefSignature.MethodRefToken));
                        if (showMetadataTokens)
                        {
                            if (showMetadataTokensInBase10)
                            {
                                output.WriteReference(currentFile, methodRefToken, $"({MetadataTokens.GetToken(methodRefToken)}) ", "metadata");
                            }
                            else
                            {
                                output.WriteReference(currentFile, methodRefToken, $"({MetadataTokens.GetToken(methodRefToken):X8}) ", "metadata");
                            }
                        }
                        methodRefToken.WriteTo(currentFile, output, Decompiler.Metadata.GenericContext.Empty);
                        break;

                    default:
                        output.WriteLine(reader.ImportSignatures[importCellAddress].ToString(new SignatureFormattingOptions()));
                        break;
                    }
                    output.WriteLine();
                }
            }
            else
            {
                output.WriteLine();
            }
        }
コード例 #4
0
        /// <summary>
        /// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/zap/zapimport.cpp">ZapImportSectionsTable::Save</a>
        /// </summary>
        private void EnsureImportSections()
        {
            if (_importSections != null)
            {
                return;
            }
            _importSections   = new List <ReadyToRunImportSection>();
            _importSignatures = new Dictionary <int, ReadyToRunSignature>();
            if (!ReadyToRunHeader.Sections.TryGetValue(ReadyToRunSectionType.ImportSections, out ReadyToRunSection importSectionsSection))
            {
                return;
            }
            int offset    = GetOffset(importSectionsSection.RelativeVirtualAddress);
            int endOffset = offset + importSectionsSection.Size;

            while (offset < endOffset)
            {
                int rva                     = NativeReader.ReadInt32(Image, ref offset);
                int sectionOffset           = GetOffset(rva);
                int startOffset             = sectionOffset;
                int size                    = NativeReader.ReadInt32(Image, ref offset);
                CorCompileImportFlags flags = (CorCompileImportFlags)NativeReader.ReadUInt16(Image, ref offset);
                byte type                   = NativeReader.ReadByte(Image, ref offset);
                byte entrySize              = NativeReader.ReadByte(Image, ref offset);
                if (entrySize == 0)
                {
                    switch (Machine)
                    {
                    case Machine.I386:
                    case Machine.ArmThumb2:
                        entrySize = 4;
                        break;

                    case Machine.Amd64:
                    case Machine.Arm64:
                        entrySize = 8;
                        break;

                    default:
                        throw new NotImplementedException(Machine.ToString());
                    }
                }
                int entryCount = 0;
                if (entrySize != 0)
                {
                    entryCount = size / entrySize;
                }
                int signatureRVA = NativeReader.ReadInt32(Image, ref offset);

                int signatureOffset = 0;
                if (signatureRVA != 0)
                {
                    signatureOffset = GetOffset(signatureRVA);
                }
                List <ReadyToRunImportSection.ImportSectionEntry> entries = new List <ReadyToRunImportSection.ImportSectionEntry>();
                for (int i = 0; i < entryCount; i++)
                {
                    int  entryOffset = sectionOffset - startOffset;
                    long section     = NativeReader.ReadInt64(Image, ref sectionOffset);
                    uint sigRva      = NativeReader.ReadUInt32(Image, ref signatureOffset);
                    int  sigOffset   = GetOffset((int)sigRva);
                    ReadyToRunSignature signature = MetadataNameFormatter.FormatSignature(_assemblyResolver, this, sigOffset);
                    entries.Add(new ReadyToRunImportSection.ImportSectionEntry(entries.Count, entryOffset, entryOffset + rva, section, sigRva, signature));
                    _importSignatures.Add(rva + entrySize * i, signature);
                }

                int auxDataRVA    = NativeReader.ReadInt32(Image, ref offset);
                int auxDataOffset = 0;
                if (auxDataRVA != 0)
                {
                    auxDataOffset = GetOffset(auxDataRVA);
                }
                _importSections.Add(new ReadyToRunImportSection(_importSections.Count, this, rva, size, flags, type, entrySize, signatureRVA, entries, auxDataRVA, auxDataOffset, Machine, ReadyToRunHeader.MajorVersion));
            }
        }
コード例 #5
0
        private void Disassemble(PEFile currentFile, ITextOutput output, ReadyToRunReader reader, ReadyToRunMethod readyToRunMethod, RuntimeFunction runtimeFunction, int bitness, ulong address, bool showMetadataTokens, bool showMetadataTokensInBase10)
        {
            WriteCommentLine(output, readyToRunMethod.SignatureString);
            byte[] codeBytes = new byte[runtimeFunction.Size];
            for (int i = 0; i < runtimeFunction.Size; i++)
            {
                codeBytes[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i];
            }

            // TODO: Decorate the disassembly with Unwind, GC and debug info
            var codeReader = new ByteArrayCodeReader(codeBytes);
            var decoder    = Decoder.Create(bitness, codeReader);

            decoder.IP = address;
            ulong endRip = decoder.IP + (uint)codeBytes.Length;

            var instructions = new InstructionList();

            while (decoder.IP < endRip)
            {
                decoder.Decode(out instructions.AllocUninitializedElement());
            }

            string    disassemblyFormat = ReadyToRunOptions.GetDisassemblyFormat(null);
            Formatter formatter         = null;

            if (disassemblyFormat.Equals(ReadyToRunOptions.intel))
            {
                formatter = new NasmFormatter();
            }
            else
            {
                Debug.Assert(disassemblyFormat.Equals(ReadyToRunOptions.gas));
                formatter = new GasFormatter();
            }
            formatter.Options.DigitSeparator        = "`";
            formatter.Options.FirstOperandCharIndex = 10;
            var tempOutput = new StringOutput();

            foreach (var instr in instructions)
            {
                int byteBaseIndex = (int)(instr.IP - address);
                if (runtimeFunction.DebugInfo != null)
                {
                    foreach (var bound in runtimeFunction.DebugInfo.BoundsList)
                    {
                        if (bound.NativeOffset == byteBaseIndex)
                        {
                            if (bound.ILOffset == (uint)DebugInfoBoundsType.Prolog)
                            {
                                WriteCommentLine(output, "Prolog");
                            }
                            else if (bound.ILOffset == (uint)DebugInfoBoundsType.Epilog)
                            {
                                WriteCommentLine(output, "Epilog");
                            }
                            else
                            {
                                WriteCommentLine(output, $"IL_{bound.ILOffset:x4}");
                            }
                        }
                    }
                }
                formatter.Format(instr, tempOutput);
                output.Write(instr.IP.ToString("X16"));
                output.Write(" ");
                int instrLen = instr.Length;
                for (int i = 0; i < instrLen; i++)
                {
                    output.Write(codeBytes[byteBaseIndex + i].ToString("X2"));
                }
                int missingBytes = 10 - instrLen;
                for (int i = 0; i < missingBytes; i++)
                {
                    output.Write("  ");
                }
                output.Write(" ");
                output.Write(tempOutput.ToStringAndReset());
                int importCellAddress = (int)instr.IPRelativeMemoryAddress;
                if (instr.IsCallNearIndirect && reader.ImportCellNames.ContainsKey(importCellAddress))
                {
                    output.Write(" ; ");
                    ReadyToRunSignature signature = reader.ImportSignatures[(int)instr.IPRelativeMemoryAddress];
                    switch (signature)
                    {
                    case MethodDefEntrySignature methodDefSignature:
                        var methodDefToken = MetadataTokens.EntityHandle(unchecked ((int)methodDefSignature.MethodDefToken));
                        if (showMetadataTokens)
                        {
                            if (showMetadataTokensInBase10)
                            {
                                output.WriteReference(currentFile, methodDefToken, $"({MetadataTokens.GetToken(methodDefToken)}) ", "metadata");
                            }
                            else
                            {
                                output.WriteReference(currentFile, methodDefToken, $"({MetadataTokens.GetToken(methodDefToken):X8}) ", "metadata");
                            }
                        }
                        methodDefToken.WriteTo(currentFile, output, Decompiler.Metadata.GenericContext.Empty);
                        break;

                    case MethodRefEntrySignature methodRefSignature:
                        var methodRefToken = MetadataTokens.EntityHandle(unchecked ((int)methodRefSignature.MethodRefToken));
                        if (showMetadataTokens)
                        {
                            if (showMetadataTokensInBase10)
                            {
                                output.WriteReference(currentFile, methodRefToken, $"({MetadataTokens.GetToken(methodRefToken)}) ", "metadata");
                            }
                            else
                            {
                                output.WriteReference(currentFile, methodRefToken, $"({MetadataTokens.GetToken(methodRefToken):X8}) ", "metadata");
                            }
                        }
                        methodRefToken.WriteTo(currentFile, output, Decompiler.Metadata.GenericContext.Empty);
                        break;

                    default:
                        output.WriteLine(reader.ImportCellNames[importCellAddress]);
                        break;
                    }
                    output.WriteLine();
                }
                else
                {
                    output.WriteLine();
                }
            }
            output.WriteLine();
        }