public DisassemblyResult DisassembleReachable(Stream data, int start, int length) { data.Seek(start, SeekOrigin.Begin); var ret = new DisassemblyResult(); int readingLeft = length; var starts = new LinkedList <int>(); starts.AddFirst(start); bool continueAfterCurrent = true; do { var du = TryDisassembleInstruction(data, readingLeft); if (du != null) { ret.AddInstruction(du); readingLeft -= (int)du.Format; if (Instruction.IsJump(du.Operation)) { var jumpTarget = du.Operands[0].Value.Value; var flags = du.Flags; if (flags.HasFlag(InstructionFlags.P)) { jumpTarget += (int)data.Position; } Debug.WriteLine($"Adding new start: {jumpTarget:x}"); starts.AddLast(jumpTarget); if (du.Operation == Instruction.Mnemonic.J) { continueAfterCurrent = false; } } } if (!continueAfterCurrent) { int newStart; do { if (starts.Count == 0) { Debug.WriteLine("No more disassembly starts. Exiting."); return(ret); } newStart = starts.First.Value; starts.RemoveFirst(); Debug.WriteLine($"Removed next start: {newStart:x}..."); // If instruction at 'newStart' has already been disassembled, discard this start and grab another. }while (ret.FindInstruction(newStart, out _)); Debug.WriteLine($"Using start: {newStart:x}..."); data.Seek(newStart, SeekOrigin.Begin); } } while (readingLeft > 0); // (starts.Count > 0); return(ret); }
//public DisassemblyResult DisassembleWithContinue(byte[] data, int offset, int length) //{ // return DisassembleWithContinue(new MemoryStream(data, offset, length), 0, length); //} /// <summary> /// Disassembles the data stream in the specified region, continuing on error until the next valid instruction is found. /// </summary> /// <param name="data"></param> /// <param name="offset">The index in the stream to begin reading.</param> /// <param name="length">The maximum number of bytes to read from the stream.</param> /// <returns></returns> public DisassemblyResult DisassembleWithContinue(Stream data, int offset, int length) { data.Seek(offset, SeekOrigin.Begin); var ret = new DisassemblyResult(); Instruction nextInstr; while (data.Position < offset + length) { nextInstr = TryDisassembleInstruction(data, length); if (nextInstr != null) { ret.AddInstruction(nextInstr); } } return(ret); }
//public DisassemblyResult Disassemble(byte[] data, int offset, int length) //{ // return Disassemble(new MemoryStream(data, offset, length), 0, length); //} /// <summary> /// Disassembles the data stream in the specified region, stopping if an invalid instruction is hit. /// </summary> /// <param name="data"></param> /// <param name="offset">The index in the stream to begin reading.</param> /// <param name="length">The maximum number of bytes to read from the stream.</param> /// <returns></returns> public DisassemblyResult Disassemble(Stream data, int offset, int length) { data.Seek(offset, SeekOrigin.Begin); var ret = new DisassemblyResult(); int successBytes = 0; Instruction nextInstr; while (successBytes < offset + length) { nextInstr = TryDisassembleInstruction(data, length); if (nextInstr == null) { return(ret); } ret.AddInstruction(nextInstr); successBytes += (int)nextInstr.Format; } return(ret); }