Provides a simple wrapper around the C# ported udis86 library.
Inheritance: IDisposable
Example #1
0
        private static int Main(string[] args)
        {
            Console.WriteLine();
            Console.WriteLine("Mosa.Tool.Disassembler.Intel.Disassembler [www.mosa-project.org]");
            Console.WriteLine("Copyright 2016. New BSD License.");
            Console.WriteLine("Written by Phil Garcia ([email protected])");
            Console.WriteLine();

            if (args.Length < 2)
            {
                Console.WriteLine("Usage: Disassembler -offset <offset> -address <address> -o <output file> <source file>");
                Console.Error.WriteLine("ERROR: Missing arguments");
                return -1;
            }

            try
            {
                var options = new Options();
                options.LoadArguments(args);

                // Need a new instance of translator every time as they aren't thread safe
                var translator = new IntelTranslator();

                // Configure the translator to output instruction addresses and instruction binary as hex
                translator.IncludeAddress = true;
                translator.IncludeBinary = true;

                var code2 = File.ReadAllBytes(options.InputFile);

                var code = new byte[code2.Length];

                for (ulong i = options.FileOffset; i < (ulong)code2.Length; i++)
                {
                    code[i - options.FileOffset] = code2[i];
                }

                //using (var disasm = new SharpDisasm.Disassembler(code, ArchitectureMode.x86_32, options.StartingAddress, true, Vendor.Any, options.FileOffset))
                using (var disasm = new SharpDisasm.Disassembler(code, ArchitectureMode.x86_32, options.StartingAddress, true, Vendor.Any))
                {
                    using (var dest = File.CreateText(options.OutputFile))
                    {
                        foreach (var instruction in disasm.Disassemble())
                        {
                            var inst = translator.Translate(instruction);
                            dest.WriteLine(inst);

                            if (options.Length != 0 && instruction.PC > options.StartingAddress + options.Length)
                                break;
                        }
                    }
                }

                return 0;
            }
            catch (Exception e)
            {
                Console.Error.WriteLine("Exception: {0}", e.ToString());
                return -1;
            }
        }
Example #2
0
        public IntPtr GetNativeFunctionPointer()
        {
            if (HasStableEntryPoint() == false)
            {
                return(IntPtr.Zero);
            }

            IntPtr ptrEntry = GetFunctionPointer();

            if (ptrEntry == IntPtr.Zero)
            {
                return(IntPtr.Zero);
            }

            SharpDisasm.ArchitectureMode mode = (IntPtr.Size == 8) ? SharpDisasm.ArchitectureMode.x86_64 : SharpDisasm.ArchitectureMode.x86_32;
            SharpDisasm.Disassembler.Translator.IncludeAddress = false;
            SharpDisasm.Disassembler.Translator.IncludeBinary  = false;

            {
                byte[] buf    = ptrEntry.ReadBytes(NativeMethods.MaxLengthOpCode);
                var    disasm = new SharpDisasm.Disassembler(buf, mode, (ulong)ptrEntry.ToInt64());

                Instruction inst = disasm.Disassemble().First();
                if (inst.Mnemonic == SharpDisasm.Udis86.ud_mnemonic_code.UD_Ijmp)
                {
                    // Visual Studio + F5 Debug = Always point to "Fixup Precode"
                    long address = (long)inst.PC + inst.Operands[0].Value;
                    return(new IntPtr(address));
                }
                else
                {
                    return(ptrEntry);
                }
            }
        }
Example #3
0
 private static List <Instruction> Disassemble(ulong methodAddress, uint methodSize, ArchitectureMode arch)
 {
     using (var disassembler = new SharpDisassembler((IntPtr)(long)methodAddress, (int)methodSize, arch, methodAddress, true))
     {
         return(disassembler.Disassemble().ToList());
     }
 }
Example #4
0
        /// <summary>
        ///     Takes the raw binary code segment and feeds it into the x86 disassembler library
        /// </summary>
        /// <param name="segment"></param>
        /// <returns></returns>
        private List <DisassemblyLine> DisassembleSegment(Segment segment)
        {
            //Only DisassembleSegment Code Segments
            if (!segment.Flags.Contains(EnumSegmentFlags.Code))
            {
                return(new List <DisassemblyLine>());
            }

            var output = new List <DisassemblyLine>();

            var disassembler = new SharpDisasm.Disassembler(segment.Data, ArchitectureMode.x86_16, 0, true);

            //Perform Raw Disassembly
            var ordinal = 0;

            foreach (var disassembly in disassembler.Disassemble())
            {
                output.Add(new DisassemblyLine
                {
                    Disassembly       = disassembly,
                    Comments          = new List <string>(),
                    Ordinal           = ordinal,
                    BranchFromRecords = new ConcurrentBag <BranchRecord>(),
                    BranchToRecords   = new ConcurrentBag <BranchRecord>()
                });
                ordinal++;
            }

            return(output);
        }
Example #5
0
        private static int Main(string[] args)
        {
            Console.WriteLine();
            Console.WriteLine("Mosa.Tool.Disassembler.Intel.Disassembler [www.mosa-project.org]");
            Console.WriteLine("Copyright 2016. New BSD License.");
            Console.WriteLine("Written by Phil Garcia ([email protected])");
            Console.WriteLine();

            try
            {
                var options = ParseOptions(args);
                if (options == null)
                {
                    return(-1);                    //Commandline errors will be printed by the commandline lib
                }

                // Need a new instance of translator every time as they aren't thread safe
                var translator = new IntelTranslator()
                {
                    // Configure the translator to output instruction addresses and instruction binary as hex
                    IncludeAddress = true,
                    IncludeBinary  = true
                };

                var code2 = File.ReadAllBytes(options.InputFile);

                var code = new byte[code2.Length];

                for (ulong i = options.FileOffset; i < (ulong)code2.Length; i++)
                {
                    code[i - options.FileOffset] = code2[i];
                }

                //using (var disasm = new SharpDisasm.Disassembler(code, ArchitectureMode.x86_32, options.StartingAddress, true, Vendor.Any, options.FileOffset))
                using (var disasm = new SharpDisasm.Disassembler(code, ArchitectureMode.x86_32, options.StartingAddress, true, Vendor.Any))
                {
                    using (var dest = File.CreateText(options.OutputFile))
                    {
                        foreach (var instruction in disasm.Disassemble())
                        {
                            var inst = translator.Translate(instruction);
                            dest.WriteLine(inst);

                            if (options.Length != 0 && instruction.PC > options.StartingAddress + options.Length)
                            {
                                break;
                            }
                        }
                    }
                }

                return(0);
            }
            catch (Exception e)
            {
                Console.Error.WriteLine("Exception: {0}", e.ToString());
                return(-1);
            }
        }
        public string GetInstruction(ulong location)
        {
            //if (simAssemblyCode == null || simAssemblyCode.simCPU != SimCPU)
            //{
            //	simAssemblyCode = new SimAssemblyCode(SimCPU);
            //}

            //var disasm = new Disassembler(simAssemblyCode, ArchitectureMode.x86_32, location, location);

            var disasm = new Disassembler(new SimAssemblyCode(SimCPU, location), ArchitectureMode.x86_32, location);

            var instruction = disasm.NextInstruction();

            return instruction.ToString();
        }
Example #7
0
        private static void OutputAssembly(byte[] codeBuffer, PeFile peFile)
        {
            fileCounter++;
            SharpDisasm.ArchitectureMode mode = SharpDisasm.ArchitectureMode.x86_32;

            // Configure the translator to output instruction addresses and instruction binary as hex
            SharpDisasm.Disassembler.Translator.IncludeAddress = true;
            SharpDisasm.Disassembler.Translator.IncludeBinary  = true;
            // Create the disassembler
            var disasm = new SharpDisasm.Disassembler(
                codeBuffer,
                mode, 0, true);


            using (System.IO.StreamWriter file =
                       new System.IO.StreamWriter("AssemblerOutput" + fileCounter.ToString() + ".txt"))
            {
                SharpDisasm.Instruction instruction = null;
                var instructionEnum = disasm.Disassemble().GetEnumerator();

                foreach (var relocationDirectory in peFile.ImageRelocationDirectory)
                {
                    foreach (var relocationOffset in relocationDirectory.TypeOffsets)
                    {
                        // Disassemble each instruction and output to console
                        while (instructionEnum.MoveNext() &&
                               (instruction = instructionEnum.Current) != null &&
                               !IsOffsetInInstruction(instruction, relocationOffset))
                        {
                            file.WriteLine(instruction.ToString());
                        }
                        if (instruction != null)
                        {
                            file.WriteLine(instruction.ToString() + " Relocation Address: " + relocationOffset.Offset.ToString("X"));
                        }
                    }
                }
            }
        }
Example #8
0
        private void GenerateASMFile()
        {
            // Need a new instance of translator every time as they aren't thread safe
            var translator = new IntelTranslator();

            // Configure the translator to output instruction addresses and instruction binary as hex
            translator.IncludeAddress = true;
            translator.IncludeBinary  = true;

            var asmfile = Path.Combine(Options.DestinationDirectory, Path.GetFileNameWithoutExtension(Options.SourceFile) + ".asm");

            var textSection = Linker.LinkerSections[(int)SectionKind.Text];

            var map = new Dictionary <ulong, string>();

            foreach (var symbol in Linker.Symbols)
            {
                if (map.ContainsKey(symbol.VirtualAddress))
                {
                    continue;
                }

                map.Add(symbol.VirtualAddress, symbol.Name);
            }

            uint  multibootHeaderLength = MultibootHeaderLength;
            ulong startingAddress       = textSection.VirtualAddress + multibootHeaderLength;
            uint  fileOffset            = textSection.FileOffset + multibootHeaderLength;
            uint  length = textSection.Size;

            var code2 = File.ReadAllBytes(CompiledFile);

            var code = new byte[code2.Length];

            for (ulong i = fileOffset; i < (ulong)code2.Length; i++)
            {
                code[i - fileOffset] = code2[i];
            }

            using (var disasm = new SharpDisasm.Disassembler(code, ArchitectureMode.x86_32, startingAddress, true, Vendor.Any))
            {
                using (var dest = File.CreateText(asmfile))
                {
                    if (map.ContainsKey(startingAddress))
                    {
                        dest.WriteLine("; " + map[startingAddress]);
                    }

                    foreach (var instruction in disasm.Disassemble())
                    {
                        var inst = translator.Translate(instruction);
                        dest.WriteLine(inst);

                        if (map.ContainsKey(instruction.PC))
                        {
                            dest.WriteLine("; " + map[instruction.PC]);
                        }

                        if (instruction.PC > startingAddress + length)
                        {
                            break;
                        }
                    }
                }
            }
        }
Example #9
0
        private void GenerateASMFile()
        {
            // Need a new instance of translator every time as they aren't thread safe
            var translator = new IntelTranslator();

            // Configure the translator to output instruction addresses and instruction binary as hex
            translator.IncludeAddress = true;
            translator.IncludeBinary = true;

            var asmfile = Path.Combine(Options.DestinationDirectory, Path.GetFileNameWithoutExtension(Options.SourceFile) + ".asm");

            var textSection = Linker.LinkerSections[(int)SectionKind.Text];

            var map = new Dictionary<ulong, string>();

            foreach (var symbol in Linker.Symbols)
            {
                if (map.ContainsKey(symbol.VirtualAddress))
                    continue;

                map.Add(symbol.VirtualAddress, symbol.Name);
            }

            uint multibootHeaderLength = MultibootHeaderLength;
            ulong startingAddress = textSection.VirtualAddress + multibootHeaderLength;
            uint fileOffset = textSection.FileOffset + multibootHeaderLength;
            uint length = textSection.Size;

            var code2 = File.ReadAllBytes(CompiledFile);

            var code = new byte[code2.Length];

            for (ulong i = fileOffset; i < (ulong)code2.Length; i++)
            {
                code[i - fileOffset] = code2[i];
            }

            using (var disasm = new SharpDisasm.Disassembler(code, ArchitectureMode.x86_32, startingAddress, true, Vendor.Any))
            {
                using (var dest = File.CreateText(asmfile))
                {
                    if (map.ContainsKey(startingAddress))
                    {
                        dest.WriteLine("; " + map[startingAddress]);
                    }

                    foreach (var instruction in disasm.Disassemble())
                    {
                        var inst = translator.Translate(instruction);
                        dest.WriteLine(inst);

                        if (map.ContainsKey(instruction.PC))
                        {
                            dest.WriteLine("; " + map[instruction.PC]);
                        }

                        if (instruction.PC > startingAddress + length)
                            break;
                    }
                }
            }
        }
Example #10
0
 public Disassembler(byte[] code)
 {
     m_code         = code ?? throw new ArgumentNullException(nameof(code));
     m_disassembler = createDisassembler(code);
 }
Example #11
0
        protected override void Run()
        {
            var trace = CreateTraceLog();
            if (!trace.Active)
                return;

            // Determine the architecture mode
            ArchitectureMode mode;
            switch (this.Architecture.MachineType)
            {
                case Compiler.Linker.Elf.MachineType.Intel386:
                    mode = ArchitectureMode.x86_32;
                    break;

                case Compiler.Linker.Elf.MachineType.IA_64:
                    mode = ArchitectureMode.x86_64;
                    break;

                case Compiler.Linker.Elf.MachineType.ARM:
                default:
                    trace.Log($"Unable to disassemble binary for machine type: {this.Architecture.MachineType}");
                    return;
            }

            // Create a byte array from the symbol stream
            var symbol = MethodCompiler.Linker.FindSymbol(MethodCompiler.Method.FullName, SectionKind.Text);
            var stream = symbol.Stream;
            var oldPosition = stream.Position;
            var length = (int)stream.Length;
            var byteArray = new byte[length];

            stream.Position = 0;
            stream.Read(byteArray, 0, length);
            stream.Position = oldPosition;

            try
            {
                // Create the disassembler
                using (var disasm = new Disassembler(byteArray, mode, 0, true))
                {
                    // Need a new instance of translator every time as they aren't thread safe
                    var translator = new SharpDisasm.Translators.IntelTranslator();

                    // Configure the translator to output instruction addresses and instruction binary as hex
                    translator.IncludeAddress = true;
                    translator.IncludeBinary = true;

                    // Disassemble each instruction and output to trace
                    foreach (var instruction in disasm.Disassemble())
                    {
                        var asString = translator.Translate(instruction);
                        trace.Log(asString);
                    }
                }
            }
            catch (Exception e)
            {
                trace.Log($"Unable to continue disassembly, error encountered\r\n{e.ToString()}");
                NewCompilerTraceEvent(CompilerEvent.Error, $"Failed disassembly for method {this.MethodCompiler.Method}");
            }
        }
        /// <summary>
        /// Disassembles the current file to locate the needed .bind DRM information.
        /// </summary>
        /// <param name="offset"></param>
        /// <param name="size"></param>
        /// <param name="xorKey"></param>
        /// <returns></returns>
        private bool DisassembleFile(out int offset, out int size, out int xorKey)
        {
            // Determine the entry offset of the file..
            var entryOffset = this.File.GetFileOffsetFromRva(this.File.NtHeaders.OptionalHeader.AddressOfEntryPoint);

            // Prepare our needed variables..
            Disassembler disasm = null;
            var dataPointer = IntPtr.Zero;
            var structOffset = 0;
            var structSize = 0;
            var structXorKey = 0;

            try
            {
                // Copy the file data to memory for disassembling..
                dataPointer = Marshal.AllocHGlobal(this.File.FileData.Length);
                Marshal.Copy(this.File.FileData, 0, dataPointer, this.File.FileData.Length);

                // Create an offset pointer to our .bind function start..
                var startPointer = IntPtr.Add(dataPointer, (int)entryOffset);

                // Create the disassembler..
                Disassembler.Translator.IncludeAddress = true;
                Disassembler.Translator.IncludeBinary = true;

                disasm = new Disassembler(startPointer, 4096, ArchitectureMode.x86_32, entryOffset);

                // Disassemble our function..
                foreach (var inst in disasm.Disassemble().Where(inst => !inst.Error))
                {
                    // If all values are found, return successfully..
                    if (structOffset > 0 && structSize > 0 && structXorKey > 0)
                    {
                        offset = structOffset;
                        size = structSize;
                        xorKey = structXorKey;
                        return true;
                    }

                    // Looks for: mov dword ptr [value], immediate
                    if (inst.Mnemonic == ud_mnemonic_code.UD_Imov && inst.Operands[0].Type == ud_type.UD_OP_MEM && inst.Operands[1].Type == ud_type.UD_OP_IMM)
                    {
                        if (structOffset == 0)
                            structOffset = inst.Operands[1].LvalSDWord - (int)this.File.NtHeaders.OptionalHeader.ImageBase;
                        else
                            structXorKey = inst.Operands[1].LvalSDWord;
                    }

                    // Looks for: mov reg, immediate
                    if (inst.Mnemonic == ud_mnemonic_code.UD_Imov && inst.Operands[0].Type == ud_type.UD_OP_REG && inst.Operands[1].Type == ud_type.UD_OP_IMM)
                        structSize = inst.Operands[1].LvalSDWord * 4;
                }

                offset = size = xorKey = 0;
                return false;
            }
            catch
            {
                offset = size = xorKey = 0;
                return false;
            }
            finally
            {
                disasm?.Dispose();
                if (dataPointer != IntPtr.Zero)
                    Marshal.FreeHGlobal(dataPointer);
            }
        }