private static int CalcAsmLength(Assembler asm) { var stream = new MemoryStream(); asm.Assemble(new StreamCodeWriter(stream), 0); // Disassemble the result stream.Position = 0; var reader = new StreamCodeReader(stream); var decoder = Decoder.Create(64, reader); return(decoder.Select(i => i.Length).Sum()); }
public RealModeMemoryCore(ushort heapBaseSegment, ILogger logger) : base(logger) { _heapBaseSegment = heapBaseSegment; _codeReader = new(_memory); _decoder = Decoder.Create(16, _codeReader); // fill with halt instructions Array.Fill(_memory, (byte)0); // set alignment to 16 so that all allocations return a clean segment (which are 16 bytes) _memoryAllocator = new MemoryAllocator(logger, new FarPtr(_heapBaseSegment, 0), HEAP_MAX_SIZE, alignment: 16); }
void Decode_enumerator_empty() { var data = Array.Empty <byte>(); var decoder = Decoder.Create(64, data); var list = EnumeratorDecode(decoder); Assert.Equal(0, list.Count); decoder = Decoder.Create(64, data); var array = decoder.ToArray(); Assert.Equal(list, array); }
Decoder CreateDecoder(int bitness, byte[] hexBytes, DecoderOptions options) { var codeReader = new ByteArrayCodeReader(hexBytes); var decoder = Decoder.Create(bitness, codeReader, options); decoder.IP = bitness switch { 16 => DecoderConstants.DEFAULT_IP16, 32 => DecoderConstants.DEFAULT_IP32, 64 => DecoderConstants.DEFAULT_IP64, _ => throw new ArgumentOutOfRangeException(nameof(bitness)), }; Assert.Equal(bitness, decoder.Bitness); return(decoder); }
void Decode_enumerator_one() { var data = new byte[] { 0x00, 0xCE }; var decoder = Decoder.Create(64, data); var list = EnumeratorDecode(decoder); Assert.Equal(1, list.Count); Assert.Equal(Code.Add_rm8_r8, list[0].Code); decoder = Decoder.Create(64, data); var array = decoder.ToArray(); Assert.Equal(list, array); }
void Test_Decoder_Create_throws() { foreach (var bitness in BitnessUtils.GetInvalidBitnessValues()) { Assert.Throws <ArgumentOutOfRangeException>(() => Decoder.Create(bitness, new ByteArrayCodeReader("90"), DecoderOptions.None)); Assert.Throws <ArgumentOutOfRangeException>(() => Decoder.Create(bitness, new byte[] { 0x90 }, DecoderOptions.None)); } foreach (var bitness in new[] { 16, 32, 64 }) { Assert.Throws <ArgumentNullException>(() => Decoder.Create(bitness, (CodeReader)null, DecoderOptions.None)); Assert.Throws <ArgumentNullException>(() => Decoder.Create(bitness, (byte[])null, DecoderOptions.None)); } }
void Decode_enumerator_incomplete_instruction_one() { var data = new byte[] { 0x66 }; var decoder = Decoder.Create(64, data); var list = EnumeratorDecode(decoder); Assert.Equal(1, list.Count); Assert.Equal(Code.INVALID, list[0].Code); decoder = Decoder.Create(64, data); var array = decoder.ToArray(); Assert.Equal(list, array); }
public unsafe static InstructionList AssembleToList(this Assembler Assembler, ulong RIP) { var CWBuffer = new MemoryCodeWriter(); Assembler.Assemble(CWBuffer, RIP); var Buffer = CWBuffer.ToArray(); fixed(void *pBuffer = &Buffer[0]) { using (var Reader = new MemoryCodeReader(pBuffer, (uint)Buffer.Length)) { var AsmDecoder = Decoder.Create(Assembler.Bitness, Reader); return(AsmDecoder.DecodeAmount((uint)Assembler.Instructions.Count)); } } }
void Decode_enumerator_incomplete_instruction_two() { var data = new byte[] { 0x00, 0xCE, 0x66, 0x09 }; var decoder = Decoder.Create(64, data); var list = EnumeratorDecode(decoder); Assert.Equal(2, list.Count); Assert.Equal(Code.Add_rm8_r8, list[0].Code); Assert.Equal(Code.INVALID, list[1].Code); decoder = Decoder.Create(64, data); var array = decoder.ToArray(); Assert.Equal(list, array); }
void Encode_MOV_CR8_in_64bit_mode_does_not_add_LOCK(string hexBytes, Code code, string encodedBytes) { var decoder = Decoder.Create(64, new ByteArrayCodeReader(hexBytes)); decoder.Decode(out var instr); Assert.Equal(code, instr.Code); var writer = new CodeWriterImpl(); var encoder = decoder.CreateEncoder(writer); encoder.Encode(ref instr, 0); var expectedBytes = HexUtils.ToByteArray(encodedBytes); var actualBytes = writer.ToArray(); Assert.Equal(expectedBytes, actualBytes); }
internal static unsafe Decoder DecoderForAddress(IntPtr codeStart, int lengthLimit = 1000) { if (codeStart == IntPtr.Zero) { throw new NullReferenceException(nameof(codeStart)); } var stream = new UnmanagedMemoryStream((byte *)codeStart, lengthLimit, lengthLimit, FileAccess.Read); var codeReader = new StreamCodeReader(stream); var decoder = Decoder.Create(IntPtr.Size * 8, codeReader); decoder.IP = (ulong)codeStart; return(decoder); }
void Decode_with_too_few_bytes_left() { foreach (var tc in DecoderTestUtils.GetDecoderTests(includeOtherTests: true, includeInvalid: false)) { var bytes = HexUtils.ToByteArray(tc.HexBytes); for (int i = 0; i + 1 < bytes.Length; i++) { var decoder = Decoder.Create(tc.Bitness, new ByteArrayCodeReader(bytes, 0, i), tc.Options); decoder.IP = 0x1000; decoder.Decode(out var instr); Assert.Equal(0x1000UL + (ulong)i, decoder.IP); Assert.Equal(Code.INVALID, instr.Code); Assert.Equal(DecoderError.NoMoreBytes, decoder.LastError); } } }
protected void CreateCodeSegment(ReadOnlySpan <byte> byteCode, ushort segmentOrdinal = 1) { //Decode the Segment var instructionList = new InstructionList(); var codeReader = new ByteArrayCodeReader(byteCode.ToArray()); var decoder = Decoder.Create(16, codeReader); decoder.IP = 0x0; while (decoder.IP < (ulong)byteCode.Length) { decoder.Decode(out instructionList.AllocUninitializedElement()); } mbbsEmuMemoryCore.AddSegment(segmentOrdinal, instructionList); }
private static void CreateCodeSegment(ReadOnlySpan <byte> byteCode, ushort segmentOrdinal = 1) { //Decode the Segment var instructionList = new InstructionList(); var codeReader = new ByteArrayCodeReader(byteCode.ToArray()); var decoder = Decoder.Create(16, codeReader); decoder.IP = 0x0; while (decoder.IP < (ulong)byteCode.Length) { decoder.Decode(out instructionList.AllocUninitializedElement()); } CreateCodeSegment(instructionList, segmentOrdinal); }
private InstructionList DisassembleMethodInstructions(long methodOffset) { const int NativeBitness = 64; const int MaxMethodLength = 0xFFFF; var codeReader = new ByteArrayCodeReader(NativeDllCode, (int)methodOffset, (int)Math.Min(MaxMethodLength, NativeDllCode.Length - methodOffset)); var decoder = Decoder.Create(NativeBitness, codeReader); decoder.InstructionPointer = 0; ulong endRip = decoder.InstructionPointer + MaxMethodLength; var instructions = new InstructionList(); int int3count = 0; while (decoder.InstructionPointer < endRip) { if (decoder.InstructionPointer > 0) { long currentOffset = methodOffset + (long)decoder.InstructionPointer; if (Offsets.MethodsFromOffsets.ContainsKey(currentOffset)) { break; } } decoder.Decode(out Instruction instruction); if (instruction.Code == Code.INVALID) { break; } else if (instruction.Code == Code.Int3) { int3count++; if (int3count >= 2) { break; } } else { int3count = 0; } instructions.Add(instruction); } return(instructions); }
/// <summary> /// Returns a set of instructions represented by the prologue this type was instantiated with. /// </summary> private IList <Instruction> DecodePrologue() { var codeReader = new ByteArrayCodeReader(_bytes); var decoder = Decoder.Create(_bitness, codeReader); decoder.IP = _originalFunctionAddress; ulong endRip = decoder.IP + (uint)_bytes.Length; var instructions = new InstructionList(); while (decoder.IP < endRip) { decoder.Decode(out instructions.AllocUninitializedElement()); } return(instructions); }
void Prevent_VEX2_encoding(string hexBytes, string expectedBytes, Code code, bool preventVEX2) { var decoder = Decoder.Create(64, new ByteArrayCodeReader(hexBytes)); decoder.IP = DecoderConstants.DEFAULT_IP64; decoder.Decode(out var instr); Assert.Equal(code, instr.Code); var codeWriter = new CodeWriterImpl(); var encoder = decoder.CreateEncoder(codeWriter); encoder.PreventVEX2 = preventVEX2; encoder.Encode(ref instr, DecoderConstants.DEFAULT_IP64); var encodedBytes = codeWriter.ToArray(); var expectedBytesArray = HexUtils.ToByteArray(expectedBytes); Assert.Equal(expectedBytesArray, encodedBytes); }
internal static Instruction[] Decode(int bitness, ulong rip, byte[] data, DecoderOptions options) { var decoder = Decoder.Create(bitness, new ByteArrayCodeReader(data), options); decoder.IP = rip; var list = new List <Instruction>(); while ((decoder.IP - rip) < (uint)data.Length) { list.Add(decoder.Decode()); } if (decoder.IP - rip != (uint)data.Length) { throw new InvalidOperationException(); } return(list.ToArray()); }
void FormatMnemonicOptions(string hexBytes, Code code, int bitness, string formattedString, FormatMnemonicOptions options) { var decoder = Decoder.Create(bitness, new ByteArrayCodeReader(hexBytes)); decoder.Decode(out var instruction); Assert.Equal(code, instruction.Code); var formatter = FormatterFactory.Create(); var output = new StringOutput(); formatter.FormatMnemonic(instruction, 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 }
public static void Main(string[] args) { var code = File.ReadAllBytes(args[0]); var reader = new ByteArrayCodeReader(code); var decoder = Decoder.Create(64, reader); decoder.InstructionPointer = 0x00007FFAC46ACDA4; var end = decoder.InstructionPointer + (uint)code.Length; var instructions = new InstructionList(); while (decoder.InstructionPointer < end) { decoder.Decode(out instructions.AllocUninitializedElement()); } }
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 }
void Decode_ctor_with_byte_array_arg() { var decoder = Decoder.Create(16, new byte[] { 0x01, 0xCE }, DecoderOptions.None); Assert.Equal(16, decoder.Bitness); decoder.Decode(out var instr); Assert.Equal(Code.Add_rm16_r16, instr.Code); decoder = Decoder.Create(32, new byte[] { 0x01, 0xCE }, DecoderOptions.None); Assert.Equal(32, decoder.Bitness); decoder.Decode(out instr); Assert.Equal(Code.Add_rm32_r32, instr.Code); decoder = Decoder.Create(64, new byte[] { 0x48, 0x01, 0xCE }, DecoderOptions.None); Assert.Equal(64, decoder.Bitness); decoder.Decode(out instr); Assert.Equal(Code.Add_rm64_r64, instr.Code); }
void Test_EVEX_WIG_LIG(string hexBytes, string expectedBytes, Code code, uint wig, uint lig) { var decoder = Decoder.Create(64, new ByteArrayCodeReader(hexBytes)); decoder.IP = DecoderConstants.DEFAULT_IP64; decoder.Decode(out var instruction); Assert.Equal(code, instruction.Code); var codeWriter = new CodeWriterImpl(); var encoder = Encoder.Create(decoder.Bitness, codeWriter); encoder.EVEX_WIG = wig; encoder.EVEX_LIG = lig; encoder.Encode(instruction, DecoderConstants.DEFAULT_IP64); var encodedBytes = codeWriter.ToArray(); var expectedBytesArray = HexUtils.ToByteArray(expectedBytes); Assert.Equal(expectedBytesArray, encodedBytes); }
public override Sound LoadSound(Stream stream, AudioFormat format) { using var decoder = Decoder.Create(stream, format); var sound = new ALSound(); try { decoder.Load(sound.buffer); } catch { sound.Dispose(); throw; } return(sound); }
void VATests(VirtualAddressTestCase tc) { var decoder = Decoder.Create(tc.Bitness, new ByteArrayCodeReader(tc.HexBytes), tc.DecoderOptions); decoder.IP = tc.Bitness switch { 16 => DecoderConstants.DEFAULT_IP16, 32 => DecoderConstants.DEFAULT_IP32, 64 => DecoderConstants.DEFAULT_IP64, _ => throw new InvalidOperationException(), }; var instruction = decoder.Decode(); var getRegValue = new VARegisterValueProviderImpl(tc.RegisterValues); var getRegValueFail = new VARegisterValueProviderImpl(Array.Empty <(Register register, int elementIndex, int elementSize, ulong value)>()); var factory = new InstructionInfoFactory(); var info = factory.GetInfo(instruction); var usedMem = info.GetUsedMemory().Skip(tc.UsedMemIndex).First(); bool b1 = usedMem.TryGetVirtualAddress(tc.ElementIndex, getRegValue, out ulong value1); Assert.True(b1); Assert.Equal(tc.ExpectedValue, value1); bool b2 = usedMem.TryGetVirtualAddress(tc.ElementIndex, out ulong value2, (Register register, int elementIndex, int elementSize, out ulong value) => getRegValue.TryGetRegisterValue(register, elementIndex, elementSize, out value)); Assert.True(b2); Assert.Equal(tc.ExpectedValue, value2); ulong value3 = usedMem.GetVirtualAddress(tc.ElementIndex, getRegValue); Assert.Equal(tc.ExpectedValue, value3); ulong value4 = usedMem.GetVirtualAddress(tc.ElementIndex, (register, elementIndex2, elementSize) => getRegValue.GetRegisterValue(register, elementIndex2, elementSize)); Assert.Equal(tc.ExpectedValue, value4); Assert.False(usedMem.TryGetVirtualAddress(tc.ElementIndex, out ulong value5, (Register register, int elementIndex, int elementSize, out ulong value) => { value = 0; return(false); })); Assert.Equal(0UL, value5); Assert.False(usedMem.TryGetVirtualAddress(tc.ElementIndex, getRegValueFail, out ulong value6)); Assert.Equal(0UL, value6); }
void Decode_multiple_instrs_with_one_instance() { var reader16 = new DecodeMultipleCodeReader(); var reader32 = new DecodeMultipleCodeReader(); var reader64 = new DecodeMultipleCodeReader(); var decoderAll16 = Decoder.Create16(reader16); var decoderAll32 = Decoder.Create32(reader32); var decoderAll64 = Decoder.Create64(reader64); foreach (var info in DecoderTestUtils.GetDecoderTests(needHexBytes: true, includeOtherTests: false)) { var data = HexUtils.ToByteArray(info.HexBytes); var decoder = Decoder.Create(info.Bitness, new ByteArrayCodeReader(data)); Decoder decoderAll; switch (info.Bitness) { case 16: decoder.InstructionPointer = DecoderConstants.DEFAULT_IP16; reader16.SetArray(data); decoderAll = decoderAll16; break; case 32: decoder.InstructionPointer = DecoderConstants.DEFAULT_IP32; reader32.SetArray(data); decoderAll = decoderAll32; break; case 64: decoder.InstructionPointer = DecoderConstants.DEFAULT_IP64; reader64.SetArray(data); decoderAll = decoderAll64; break; default: throw new InvalidOperationException(); } decoderAll.InstructionPointer = decoder.InstructionPointer; var instr1 = decoder.Decode(); var instr2 = decoderAll.Decode(); Assert.Equal(info.Code, instr1.Code); Assert.True(Instruction.TEST_BitByBitEquals(ref instr1, ref instr2)); } }
private protected void TestBase(int bitness, string hexBytes, int operand, int elementIndex, ulong expectedValue, VARegisterValueProviderImpl getRegValue) { var decoder = Decoder.Create(bitness, new ByteArrayCodeReader(hexBytes)); decoder.IP = bitness switch { 16 => DecoderConstants.DEFAULT_IP16, 32 => DecoderConstants.DEFAULT_IP32, 64 => DecoderConstants.DEFAULT_IP64, _ => throw new InvalidOperationException(), }; var instruction = decoder.Decode(); ulong value1 = instruction.GetVirtualAddress(operand, elementIndex, getRegValue); Assert.Equal(expectedValue, value1); ulong value2 = instruction.GetVirtualAddress(operand, elementIndex, (register, elementIndex2, elementSize) => getRegValue.GetRegisterValue(register, elementIndex2, elementSize)); Assert.Equal(expectedValue, value2); }
void VATests(VirtualAddressTestCase tc) { var decoder = Decoder.Create(tc.Bitness, new ByteArrayCodeReader(tc.HexBytes)); decoder.IP = tc.Bitness switch { 16 => DecoderConstants.DEFAULT_IP16, 32 => DecoderConstants.DEFAULT_IP32, 64 => DecoderConstants.DEFAULT_IP64, _ => throw new InvalidOperationException(), }; var instruction = decoder.Decode(); var getRegValue = new VARegisterValueProviderImpl(tc.RegisterValues); ulong value1 = instruction.GetVirtualAddress(tc.Operand, tc.ElementIndex, getRegValue); Assert.Equal(tc.ExpectedValue, value1); ulong value2 = instruction.GetVirtualAddress(tc.Operand, tc.ElementIndex, (register, elementIndex2, elementSize) => getRegValue.GetRegisterValue(register, elementIndex2, elementSize)); Assert.Equal(tc.ExpectedValue, value2); }
/// <summary> /// Creates a new wrapper around a raw stream containing x86 code. /// </summary> /// <param name="architecture">The x86 architecture.</param> /// <param name="inputStream">The raw code stream.</param> /// <param name="bitness">The bitness of the x86 code. This value must be either 16, 32 or 64.</param> /// <param name="baseAddress">The base address of the code stream.</param> /// <param name="decoderOptions">Additional decoder options that need to be passed onto the Iced decoder.</param> public X86DecoderInstructionProvider( IInstructionSetArchitecture <Instruction> architecture, Stream inputStream, int bitness, ulong baseAddress, DecoderOptions decoderOptions) { _inputStream = inputStream ?? throw new ArgumentNullException(nameof(inputStream)); if (!inputStream.CanRead) { throw new ArgumentException("Input stream must be readable."); } if (!inputStream.CanSeek) { throw new ArgumentException("Input stream must be seekable."); } _decoder = Decoder.Create(bitness, new StreamCodeReader(inputStream), decoderOptions); Architecture = architecture; BaseAddress = baseAddress; }
// TODO: Extract all AMD64-related logics to other helper class public static unsafe void HijackManagedMethod(MethodInfo target, MethodInfo hook, HijackContextBase context) { // Make sure method is jitted already. RuntimeHelpers.PrepareMethod(hook.MethodHandle); Byte *pTargetMethod = (Byte *)target.MethodHandle.GetFunctionPointer(); // TODO: make allocation free way to allocate decoder. Decoder d = Decoder.Create(64, new BytePtrCodeReader(pTargetMethod)); Instruction inst = d.Decode(); switch (inst.Code) { case Code.Jmp_rel32_64: pTargetMethod += inst.Immediate32to64; break; } HijackUnmanagedMethod(pTargetMethod, hook, context); }