예제 #1
0
 private void DecorateDebugInfo(Instruction instr, DebugInfoHelper debugRecords, ulong baseInstrIP)
 {
     if (debugRecords != null)
     {
         InstructionInfoFactory factory = new InstructionInfoFactory();
         InstructionInfo        info    = factory.GetInfo(instr);
         ulong codeOffset = instr.IP - baseInstrIP;
         debugRecords.Update(codeOffset);
         Variable variable = null;
         foreach (UsedMemory usedMemInfo in info.GetUsedMemory())
         {
             string baseRegister = usedMemInfo.Base.ToString();
             int    displacement;
             unchecked
             { displacement = (int)usedMemInfo.Displacement; }
             Dictionary <int, Variable> offsetToVariableMap;
             if (debugRecords.registerRelativeVariables.TryGetValue(usedMemInfo.Base.ToString(), out offsetToVariableMap))
             {
                 if (offsetToVariableMap.TryGetValue(displacement, out variable))
                 {
                     output.Write($"; [{usedMemInfo.Base.ToString().ToLower()}{(displacement < 0 ? '-' : '+')}{Math.Abs(displacement):X}h] = {variable.Type} {variable.Index}");
                 }
             }
         }
         foreach (UsedRegister usedMemInfo in info.GetUsedRegisters())
         {
             if (debugRecords.registerVariables.TryGetValue(usedMemInfo.Register.ToString(), out variable))
             {
                 output.Write($"; {usedMemInfo.Register.ToString().ToLower()} = {variable.Type} {variable.Index}");
             }
         }
     }
 }
예제 #2
0
 private void DecorateDebugInfo(Instruction instr, DebugInfoHelper debugRecords, ulong baseInstrIP)
 {
     if (debugRecords != null)
     {
         HashSet <Variable>     variables;
         InstructionInfoFactory factory = new InstructionInfoFactory();
         InstructionInfo        info    = factory.GetInfo(instr);
         ulong codeOffset = instr.IP - baseInstrIP;
         debugRecords.Update(codeOffset);
         foreach (UsedMemory usedMemInfo in info.GetUsedMemory())
         {
             string baseRegister = usedMemInfo.Base.ToString();
             int    displacement;
             unchecked
             { displacement = (int)usedMemInfo.Displacement; }
             Dictionary <int, HashSet <Variable> > offsetToVariableMap;
             if (debugRecords.registerRelativeVariables.TryGetValue(usedMemInfo.Base.ToString(), out offsetToVariableMap))
             {
                 if (offsetToVariableMap.TryGetValue(displacement, out variables))
                 {
                     output.Write($";");
                     foreach (Variable variable in variables)
                     {
                         output.Write($" [{usedMemInfo.Base.ToString().ToLower()}{(displacement < 0 ? '-' : '+')}{Math.Abs(displacement):X}h] = {variable.Type} {variable.Index}");
                     }
                 }
             }
         }
         foreach (UsedRegister usedMemInfo in info.GetUsedRegisters())
         {
             // TODO, if the code is accessing EAX but the debug info maps to RAX, then this match is going to fail.
             if (debugRecords.registerVariables.TryGetValue(usedMemInfo.Register.ToString(), out variables))
             {
                 output.Write($";");
                 foreach (Variable variable in variables)
                 {
                     output.Write($" {usedMemInfo.Register.ToString().ToLower()} = {variable.Type} {variable.Index}");
                 }
             }
         }
     }
 }
예제 #3
0
        public void Disassemble(PEFile currentFile, int bitness, ulong address, bool showMetadataTokens, bool showMetadataTokensInBase10)
        {
            // TODO: Decorate the disassembly with GCInfo
            ReadyToRunMethod readyToRunMethod = runtimeFunction.Method;

            WriteCommentLine(readyToRunMethod.SignatureString);

            Dictionary <ulong, UnwindCode> unwindInfo = null;

            if (ReadyToRunOptions.GetIsShowUnwindInfo(null) && bitness == 64)
            {
                unwindInfo = WriteUnwindInfo();
            }

            bool            isShowDebugInfo = ReadyToRunOptions.GetIsShowDebugInfo(null);
            DebugInfoHelper debugInfo       = null;

            if (isShowDebugInfo)
            {
                debugInfo = WriteDebugInfo();
            }

            byte[] codeBytes = new byte[runtimeFunction.Size];
            for (int i = 0; i < runtimeFunction.Size; i++)
            {
                codeBytes[i] = reader.Image[reader.GetOffset(runtimeFunction.StartAddress) + i];
            }

            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();
            ulong baseInstrIP = instructions[0].IP;

            foreach (var instr in instructions)
            {
                int byteBaseIndex = (int)(instr.IP - address);
                if (isShowDebugInfo && runtimeFunction.DebugInfo != null)
                {
                    foreach (var bound in runtimeFunction.DebugInfo.BoundsList)
                    {
                        if (bound.NativeOffset == byteBaseIndex)
                        {
                            if (bound.ILOffset == (uint)DebugInfoBoundsType.Prolog)
                            {
                                WriteCommentLine("Prolog");
                            }
                            else if (bound.ILOffset == (uint)DebugInfoBoundsType.Epilog)
                            {
                                WriteCommentLine("Epilog");
                            }
                            else
                            {
                                WriteCommentLine($"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());
                DecorateUnwindInfo(unwindInfo, baseInstrIP, instr);
                DecorateDebugInfo(instr, debugInfo, baseInstrIP);

                DecorateCallSite(currentFile, showMetadataTokens, showMetadataTokensInBase10, instr);
            }
            output.WriteLine();
        }