Esempio n. 1
0
        public static void SimpleFormatTest(int codeSize, string hexBytes, Code code, DecoderOptions options, string formattedString, Formatter formatter, Action <Decoder> initDecoder)
        {
            var decoder = CreateDecoder(codeSize, hexBytes, options, out _);

            initDecoder?.Invoke(decoder);
            var nextRip = decoder.IP;
            var instr   = decoder.Decode();

            Assert.Equal(code, instr.Code);
            Assert.Equal((ushort)nextRip, instr.IP16);
            Assert.Equal((uint)nextRip, instr.IP32);
            Assert.Equal(nextRip, instr.IP);
            nextRip += (uint)instr.ByteLength;
            Assert.Equal(nextRip, decoder.IP);
            Assert.Equal((ushort)nextRip, instr.NextIP16);
            Assert.Equal((uint)nextRip, instr.NextIP32);
            Assert.Equal(nextRip, instr.NextIP);

            var output = new StringBuilderFormatterOutput();

            formatter.Format(ref instr, output);
            var actualFormattedString = output.ToStringAndReset();

#pragma warning disable xUnit2006 // Do not use invalid string equality check
            // Show the full string without ellipses by using Equal<string>() instead of Equal()
            Assert.Equal <string>(formattedString, actualFormattedString);
#pragma warning restore xUnit2006 // Do not use invalid string equality check
        }
Esempio n. 2
0
        private void Disassemble(ITextOutput output, ReadyToRunReader reader, ReadyToRunMethod readyToRunMethod, RuntimeFunction runtimeFunction, int bitness, ulong address)
        {
            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 StringBuilderFormatterOutput();

            foreach (var instr in instructions)
            {
                int byteBaseIndex = (int)(instr.IP - address);
                formatter.Format(instr, tempOutput);
                output.Write(instr.IP.ToString("X16"));
                output.Write(" ");
                int instrLen = instr.ByteLength;
                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.WriteLine(tempOutput.ToStringAndReset());
            }
            output.WriteLine();
        }
Esempio n. 3
0
        static void ShellcodeDecoder(string shellcode, string RIP, bool x64)
        {
            string[] hexValues = shellcode.Split("\\x").Skip(1).ToArray();
            int      bitness;

            if (x64)
            {
                bitness = 64;
            }
            else
            {
                bitness = 32;
            }
            byte[] code = hexValues
                          .Select(value => Convert.ToByte(value, 16))
                          .ToArray();
            var   codeBytes  = code;
            var   codeReader = new ByteArrayCodeReader(codeBytes);
            var   decoder    = Iced.Intel.Decoder.Create(bitness, codeReader);
            ulong CodeRIP    = Convert.ToUInt64(RIP, 16);

            decoder.IP = CodeRIP;

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

            var instructions = new InstructionList();

            while (decoder.IP < endRip)
            {
                decoder.Decode(out instructions.AllocUninitializedElement());
            }
            var formatter = new NasmFormatter();

            formatter.Options.DigitSeparator        = "";
            formatter.Options.FirstOperandCharIndex = 10;
            var output = new StringBuilderFormatterOutput();

            foreach (ref var instr in instructions)
            {
                formatter.Format(instr, output);
                int instrLen      = instr.ByteLength;
                int byteBaseIndex = (int)(instr.IP - CodeRIP);
                for (int i = 0; i < instrLen; i++)
                {
                    Console.Write(codeBytes[byteBaseIndex + i].ToString("X2"));
                }
                int missingBytes = 10 - instrLen;
                for (int i = 0; i < missingBytes; i++)
                {
                    Console.Write("  ");
                }
                Console.Write(" ");
                Console.WriteLine(output.ToStringAndReset().ToUpper());
            }
        }
Esempio n. 4
0
        public static void FormatTest(int codeSize, string hexBytes, Code code, string formattedString, Formatter formatter)
        {
            var decoder = CreateDecoder(codeSize, hexBytes, out ulong nextRip);
            var instr   = decoder.Decode();

            Assert.Equal(code, instr.Code);
            Assert.Equal((ushort)nextRip, instr.IP16);
            Assert.Equal((uint)nextRip, instr.IP32);
            Assert.Equal(nextRip, instr.IP64);
            nextRip += (uint)instr.ByteLength;
            Assert.Equal(nextRip, decoder.InstructionPointer);
            Assert.Equal((ushort)nextRip, instr.NextIP16);
            Assert.Equal((uint)nextRip, instr.NextIP32);
            Assert.Equal(nextRip, instr.NextIP64);

            var output = new StringBuilderFormatterOutput();

            formatter.Format(ref instr, output);
            var actualFormattedString = output.ToStringAndReset();

#pragma warning disable xUnit2006 // Do not use invalid string equality check
            // Show the full string without ellipses by using Equal<string>() instead of Equal()
            Assert.Equal <string>(formattedString, actualFormattedString);
#pragma warning restore xUnit2006 // Do not use invalid string equality check

            formatter.FormatMnemonic(ref instr, output);
            var mnemonic = output.ToStringAndReset();
            int opCount  = formatter.GetOperandCount(ref instr);
            var operands = opCount == 0 ? Array.Empty <string>() : new string[opCount];
            for (int i = 0; i < operands.Length; i++)
            {
                formatter.FormatOperand(ref instr, output, i);
                operands[i] = output.ToStringAndReset();
            }
            output.Write(mnemonic, FormatterOutputTextKind.Text);
            if (operands.Length > 0)
            {
                output.Write(" ", FormatterOutputTextKind.Text);
                for (int i = 0; i < operands.Length; i++)
                {
                    if (i > 0)
                    {
                        formatter.FormatOperandSeparator(ref instr, output);
                    }
                    output.Write(operands[i], FormatterOutputTextKind.Text);
                }
            }
            actualFormattedString = output.ToStringAndReset();
            Assert.Equal(formattedString, actualFormattedString);

            formatter.FormatAllOperands(ref instr, output);
            var allOperands = output.ToStringAndReset();
            actualFormattedString = allOperands.Length == 0 ? mnemonic : mnemonic + " " + allOperands;
            Assert.Equal(formattedString, actualFormattedString);
        }
Esempio n. 5
0
        public static void TestFormatterDoesNotThrow(Formatter formatter)
        {
            var output = new StringBuilderFormatterOutput();

            foreach (var info in DecoderTests.DecoderTestUtils.GetDecoderTests(includeOtherTests: true, includeInvalid: true))
            {
                var decoder = CreateDecoder(info.Bitness, info.HexBytes, info.Options, out _);
                decoder.Decode(out var instr);
                formatter.Format(ref instr, output);
                output.Reset();
            }
        }
Esempio n. 6
0
        private static void Disasm(Stream stream, uint size, TextWriter writer, Formatter formatter = null)
        {
            var buffer = ArrayPool <byte> .Shared.Rent((int)size);

            var startPosition = stream.Position;

            stream.Read(buffer, 0, (int)size);
            stream.Position = startPosition;

            // You can also pass in a hex string, eg. "90 91 929394", or you can use your own CodeReader
            // reading data from a file or memory etc
            var codeReader = new StreamCodeReader(stream, size);
            var decoder    = Decoder.Create(IntPtr.Size * 8, codeReader);

            decoder.IP = (ulong)0;
            ulong endRip = decoder.IP + (uint)size;

            // This list is faster than List<Instruction> since it uses refs to the Instructions
            // instead of copying them (each Instruction is 32 bytes in size). It has a ref indexer,
            // and a ref iterator. Add() uses 'in' (ref readonly).
            var instructions = new InstructionList();

            while (decoder.IP < endRip)
            {
                // The method allocates an uninitialized element at the end of the list and
                // returns a reference to it which is initialized by Decode().
                decoder.Decode(out instructions.AllocUninitializedElement());
            }

            // Formatters: Masm*, Nasm* and Gas* (AT&T)
            if (formatter == null)
            {
                formatter = new NasmFormatter();
                formatter.Options.DigitSeparator        = "";
                formatter.Options.FirstOperandCharIndex = 10;
            }
            var output = new StringBuilderFormatterOutput();

            // Use InstructionList's ref iterator (C# 7.3) to prevent copying 32 bytes every iteration
            foreach (ref var instr in instructions)
            {
                // Don't use instr.ToString(), it allocates more, uses masm syntax and default options
                formatter.Format(instr, output);
                writer.Write($"{instr.IP:X16} ");
                for (int i = 0; i < instr.ByteLength; i++)
                {
                    writer.Write(buffer[(int)instr.IP + i].ToString("X2"));
                }
                writer.Write(new string(' ', 16 * 2 - instr.ByteLength * 2));
                writer.WriteLine($"{output.ToStringAndReset()}");
            }
        }
        internal static string Format(Instruction instruction, Formatter formatter, bool printInstructionAddresses, uint pointerSize)
        {
            var output = new StringBuilderFormatterOutput();

            if (printInstructionAddresses)
            {
                FormatInstructionPointer(instruction, formatter, pointerSize, output);
            }

            formatter.Format(instruction, output);

            return(output.ToString());
        }
Esempio n. 8
0
        void FormatMnemonicOptions1(string hexBytes, Code code, int bitness, string formattedString, FormatMnemonicOptions options)
        {
            var decoder = Decoder.Create(bitness, new ByteArrayCodeReader(hexBytes));

            decoder.Decode(out var instr);
            Assert.Equal(code, instr.Code);
            var formatter = GasFormatterFactory.Create();
            var output    = new StringBuilderFormatterOutput();

            formatter.FormatMnemonic(ref instr, output, options);
            var actualFormattedString = output.ToStringAndReset();

#pragma warning disable xUnit2006 // Do not use invalid string equality check
            // Show the full string without ellipses by using Equal<string>() instead of Equal()
            Assert.Equal <string>(formattedString, actualFormattedString);
#pragma warning restore xUnit2006 // Do not use invalid string equality check
        }
Esempio n. 9
0
        void DisplInBrackets(string hexBytes, int bitness, string formattedString, Flags flags)
        {
            var decoder = Decoder.Create(bitness, new ByteArrayCodeReader(hexBytes));

            switch (bitness)
            {
            case 16: decoder.IP = DecoderConstants.DEFAULT_IP16; break;

            case 32: decoder.IP = DecoderConstants.DEFAULT_IP32; break;

            case 64: decoder.IP = DecoderConstants.DEFAULT_IP64; break;

            default: throw new InvalidOperationException();
            }
            decoder.Decode(out var instr);

            var resolver = new TestSymbolResolver {
                tryGetSymbol = (in Instruction instruction, int operand, int instructionOperand, ulong address, int addressSize, out SymbolResult symbol) => {
                    if (instructionOperand == 1 && (flags & Flags.Symbol) != 0)
                    {
                        symbol = new SymbolResult(address, "symbol", FormatterOutputTextKind.Data, (flags & Flags.Signed) != 0 ? SymbolFlags.Signed : SymbolFlags.None);
                        return(true);
                    }
                    symbol = default;
                    return(false);
                },
            };
            var formatter = (MasmFormatter)MasmFormatterFactory.Create_Resolver(resolver).formatter;

            formatter.MasmOptions.SymbolDisplInBrackets = (flags & Flags.SymbolDisplInBrackets) != 0;
            formatter.MasmOptions.DisplInBrackets       = (flags & Flags.DisplInBrackets) != 0;
            formatter.MasmOptions.RipRelativeAddresses  = (flags & Flags.Rip) != 0;
            formatter.MasmOptions.ShowZeroDisplacements = (flags & Flags.ShowZeroDisplacements) != 0;
            formatter.MasmOptions.AddDsPrefix32         = (flags & Flags.NoAddDsPrefix32) == 0;

            var output = new StringBuilderFormatterOutput();

            formatter.Format(instr, output);
            var actualFormattedString = output.ToStringAndReset();

#pragma warning disable xUnit2006 // Do not use invalid string equality check
            // Show the full string without ellipses by using Equal<string>() instead of Equal()
            Assert.Equal <string>(formattedString, actualFormattedString);
#pragma warning restore xUnit2006 // Do not use invalid string equality check
        }
Esempio n. 10
0
        public static void FormatTest(ref Instruction instr, string formattedString, Formatter formatter)
        {
            var output = new StringBuilderFormatterOutput();

            formatter.Format(ref instr, output);
            var actualFormattedString = output.ToStringAndReset();

#pragma warning disable xUnit2006 // Do not use invalid string equality check
            // Show the full string without ellipses by using Equal<string>() instead of Equal()
            Assert.Equal <string>(formattedString, actualFormattedString);
#pragma warning restore xUnit2006 // Do not use invalid string equality check

            formatter.FormatMnemonic(ref instr, output);
            var mnemonic = output.ToStringAndReset();
            int opCount  = formatter.GetOperandCount(ref instr);
            var operands = opCount == 0 ? Array.Empty <string>() : new string[opCount];
            for (int i = 0; i < operands.Length; i++)
            {
                formatter.FormatOperand(ref instr, output, i);
                operands[i] = output.ToStringAndReset();
            }
            output.Write(mnemonic, FormatterOutputTextKind.Text);
            if (operands.Length > 0)
            {
                output.Write(" ", FormatterOutputTextKind.Text);
                for (int i = 0; i < operands.Length; i++)
                {
                    if (i > 0)
                    {
                        formatter.FormatOperandSeparator(ref instr, output);
                    }
                    output.Write(operands[i], FormatterOutputTextKind.Text);
                }
            }
            actualFormattedString = output.ToStringAndReset();
            Assert.Equal(formattedString, actualFormattedString);

            formatter.FormatAllOperands(ref instr, output);
            var allOperands = output.ToStringAndReset();
            actualFormattedString = allOperands.Length == 0 ? mnemonic : mnemonic + " " + allOperands;
            Assert.Equal(formattedString, actualFormattedString);
        }
Esempio n. 11
0
        private static void DecodeMethod(IntPtr ptr, uint size, StringBuilder builder, Formatter formatter = null)
        {
            // You can also pass in a hex string, eg. "90 91 929394", or you can use your own CodeReader
            // reading data from a file or memory etc.
            var codeReader = new UnmanagedCodeReader(ptr, size);
            var decoder    = Decoder.Create(IntPtr.Size * 8, codeReader);

            decoder.IP = (ulong)ptr.ToInt64();
            ulong endRip = decoder.IP + (uint)size;

            // This list is faster than List<Instruction> since it uses refs to the Instructions
            // instead of copying them (each Instruction is 32 bytes in size). It has a ref indexer,
            // and a ref iterator. Add() uses 'in' (ref readonly).
            var instructions = new InstructionList();

            while (decoder.IP < endRip)
            {
                // The method allocates an uninitialized element at the end of the list and
                // returns a reference to it which is initialized by Decode().
                decoder.Decode(out instructions.AllocUninitializedElement());
            }

            // Formatters: Masm*, Nasm* and Gas* (AT&T)
            if (formatter == null)
            {
                formatter = new NasmFormatter();
                formatter.Options.DigitSeparator        = "`";
                formatter.Options.FirstOperandCharIndex = 10;
            }
            var output = new StringBuilderFormatterOutput();

            // Use InstructionList's ref iterator (C# 7.3) to prevent copying 32 bytes every iteration
            foreach (ref var instr in instructions)
            {
                // Don't use instr.ToString(), it allocates more, uses masm syntax and default options
                formatter.Format(in instr, output);
                builder.AppendLine($"{instr.IP:X16} {output.ToStringAndReset()}");
            }
        }
        private static void FormatInstructionPointer(Instruction instruction, Formatter formatter, uint pointerSize, StringBuilderFormatterOutput output)
        {
            string ipFormat = formatter.Options.LeadingZeroes
                ? pointerSize == 4 ? "X8" : "X16"
                : "X";

            output.Write(instruction.IP.ToString(ipFormat), FormatterOutputTextKind.Text);
            output.Write(" ", FormatterOutputTextKind.Text);
        }