public override ProcedureBase GetTrampolineDestination(ImageReader rdr, IRewriterHost host) { var rw = Architecture.CreateRewriter( rdr, Architecture.CreateProcessorState(), Architecture.CreateFrame(), host); var rtlc = rw.FirstOrDefault(); if (rtlc == null || rtlc.Instructions.Count == 0) return null; var jump = rtlc.Instructions[0] as RtlGoto; if (jump == null) return null; var pc = jump.Target as ProcedureConstant; if (pc != null) return pc.Procedure; var access = jump.Target as MemoryAccess; if (access == null) return null; var addrTarget = access.EffectiveAddress as Address; if (addrTarget == null) { var wAddr = access.EffectiveAddress as Constant; if (wAddr == null) { return null; } addrTarget = MakeAddressFromConstant(wAddr); } ProcedureBase proc = host.GetImportedProcedure(addrTarget, rtlc.Address); if (proc != null) return proc; return host.GetInterceptedCall(addrTarget); }
public IEnumerable<RtlInstructionCluster> CreateRewriter(ImageReader rdr, ProcessorState state, Frame frame, IRewriterHost host) { var linAddr = rdr.Address.ToLinear(); RtlTrace trace; if (!rewriters.Traces.TryGetValue(rdr.Address, out trace)) NUnit.Framework.Assert.Fail(string.Format("Unexpected request for a rewriter at address {0}", rdr.Address)); return trace; }
private void CreateDisassembler16(ImageReader rdr) { dasm = new X86Disassembler( rdr, PrimitiveType.Word16, PrimitiveType.Word16, false); }
public virtual object ReadValue(System.Reflection.FieldInfo f, ImageReader rdr, ReaderContext ctx) { Func<ImageReader, object> fn; if (readers.TryGetValue(f.FieldType, out fn)) { return fn(rdr); } throw new NotSupportedException(string.Format("Field type {0} not supported.", f.FieldType.FullName)); }
public override object ReadValue(FieldInfo f, ImageReader rdr, ReaderContext ctx) { int i = 0; for (; rdr.PeekByte(i) != 0; ++i) { } var s = Encoding.UTF8.GetString(rdr.ReadBytes(i)); rdr.Offset++; return s; }
protected Address ReadSegmentedCodeAddress(int byteSize, ImageReader rdr, ProcessorState state) { if (byteSize == PrimitiveType.Word16.Size) { return Address.SegPtr(state.GetRegister(Registers.cs).ToUInt16(), rdr.ReadLeUInt16()); } else { ushort off = rdr.ReadLeUInt16(); ushort seg = rdr.ReadLeUInt16(); return Address.SegPtr(seg, off); } }
public void Read(ImageReader rdr) { foreach (var f in fields) { var attr = GetFieldAttribute(f); uint alignment = (uint) attr.Align; rdr.Offset = (rdr.Offset + alignment - 1u) & ~(alignment - 1u); Debug.Print("At offset: {0:X8} reading field '{1}.{2}' after alignment of {3}.", rdr.Offset, f.DeclaringType.Name, f.Name, alignment); object value = attr.ReadValue(f, rdr, null); f.SetValue(structure, value); } }
public static Elf64_PHdr Load(ImageReader rdr) { var hdr = new Elf64_PHdr { p_type = (ProgramHeaderType)rdr.ReadUInt32(), p_flags = rdr.ReadUInt32(), p_offset = rdr.ReadUInt64(), p_vaddr = rdr.ReadUInt64(), p_paddr = rdr.ReadUInt64(), p_filesz = rdr.ReadUInt64(), p_pmemsz = rdr.ReadUInt64(), p_align = rdr.ReadUInt64(), }; return hdr; }
public static Elf64_SHdr Load(ImageReader rdr) { return new Elf64_SHdr { sh_name = rdr.ReadUInt32(), sh_type = (SectionHeaderType)rdr.ReadUInt32(), sh_flags = rdr.ReadUInt64(), sh_addr = rdr.ReadUInt64(), // Address sh_offset = rdr.ReadUInt64(), sh_size = rdr.ReadUInt64(), sh_link = rdr.ReadUInt32(), sh_info = rdr.ReadUInt32(), sh_addralign = rdr.ReadUInt64(), sh_entsize = rdr.ReadUInt64(), }; }
public IEnumerable<Address> CreatePointerScanner(ImageMap map, ImageReader rdr, IEnumerable<Address> knownAddresses, PointerScannerFlags flags) { var knownLinAddresses = knownAddresses.Select(a => a.ToUInt32()).ToHashSet(); if (flags != PointerScannerFlags.Calls) throw new NotImplementedException(string.Format("Haven't implemented support for scanning for {0} yet.", flags)); while (rdr.IsValid) { uint linAddrCall = rdr.Address.ToUInt32(); var opcode = rdr.ReadLeUInt32(); if ((opcode & 0x0F000000) == 0x0B000000) // BL { int offset = ((int)opcode << 8) >> 6; uint target = (uint)(linAddrCall + 8 + offset); if (knownLinAddresses.Contains(target)) yield return Address.Ptr32(linAddrCall); } } }
public ushort e_shstrndx; // section name string table index public static Elf32_EHdr Load(ImageReader rdr) { return new Elf32_EHdr { e_type = rdr.ReadUInt16(), e_machine = rdr.ReadUInt16(), e_version = rdr.ReadUInt32(), e_entry = rdr.ReadUInt32(), e_phoff = rdr.ReadUInt32(), e_shoff = rdr.ReadUInt32(), e_flags = rdr.ReadUInt32(), e_ehsize = rdr.ReadUInt16(), e_phentsize = rdr.ReadUInt16(), e_phnum = rdr.ReadUInt16(), e_shentsize = rdr.ReadUInt16(), e_shnum = rdr.ReadUInt16(), e_shstrndx = rdr.ReadUInt16(), }; }
public static object ReadPointer(Type pointerType, int size, ImageReader rdr, ReaderContext ctx) { Debug.Print("Reading pointer at offset {0}, size {1}", rdr.Offset, size); uint newOffset; switch (size) { default: throw new InvalidOperationException("Field size must be > 0."); case 1: newOffset = rdr.ReadByte(); break; case 2: newOffset = rdr.ReadUInt16(); break; case 4: newOffset = rdr.ReadUInt32(); break; } Debug.Print("Structure of type {0} must start at offset {1:X}", pointerType.Name, newOffset); rdr = rdr.Clone(); rdr.Offset = newOffset; var dst = Activator.CreateInstance(pointerType); var sr = new StructureReader(dst); sr.Read(rdr); return dst; }
public Address ReadCodeAddress(int size, ImageReader rdr, ProcessorState state) { throw new NotImplementedException(); }
public IEnumerable<Address> CreatePointerScanner(ImageMap map, ImageReader rdr, IEnumerable<Address> knownAddresses, PointerScannerFlags flags) { throw new NotImplementedException(); }
public IEnumerable<MachineInstruction> CreateDisassembler(ImageReader imageReader) { return new Z80Disassembler(imageReader); }
private MachineOperand AddressRegisterIndirectWithIndex(PrimitiveType dataWidth, ImageReader rdr) { ushort extension = rdr.ReadBeUInt16(); if (EXT_FULL(extension)) { if (M68kDisassembler.EXT_EFFECTIVE_ZERO(extension)) { return new M68kImmediateOperand(Constant.Zero(dataWidth)); } RegisterStorage base_reg = null; RegisterStorage index_reg = null; PrimitiveType index_reg_width = null; int index_scale = 1; Constant @base = null; if (EXT_BASE_DISPLACEMENT_PRESENT(extension)) { @base = rdr.ReadBe(EXT_BASE_DISPLACEMENT_LONG(extension) ? PrimitiveType.Word32: PrimitiveType.Int16); } Constant outer = null; if (EXT_OUTER_DISPLACEMENT_PRESENT(extension)) { outer = rdr.ReadBe(EXT_OUTER_DISPLACEMENT_LONG(extension) ? PrimitiveType.Word32: PrimitiveType.Int16); } if (EXT_BASE_REGISTER_PRESENT(extension)) base_reg = Registers.AddressRegister(opcode & 7); if (EXT_INDEX_REGISTER_PRESENT(extension)) { index_reg = EXT_INDEX_AR(extension) ? Registers.AddressRegister((int) EXT_INDEX_REGISTER(extension)) : Registers.DataRegister((int) EXT_INDEX_REGISTER(extension)); index_reg_width = EXT_INDEX_LONG(extension) ? PrimitiveType.Word32 : PrimitiveType.Word16; if (EXT_INDEX_SCALE(extension) != 0) index_scale = 1 << EXT_INDEX_SCALE(extension); } bool preindex = (extension & 7) > 0 && (extension & 7) < 4; bool postindex = (extension & 7) > 4; return new IndexedOperand(dataWidth, @base, outer, base_reg, index_reg, index_reg_width, index_scale, preindex, postindex); } else { return new IndirectIndexedOperand( EXT_8BIT_DISPLACEMENT(extension), Registers.AddressRegister(opcode & 7), EXT_INDEX_AR(extension) ? Registers.AddressRegister((int)EXT_INDEX_REGISTER(extension)) : Registers.DataRegister((int)EXT_INDEX_REGISTER(extension)), EXT_INDEX_LONG(extension) ? PrimitiveType.Word32 : PrimitiveType.Int16, EXT_INDEX_SCALE(extension)); } }
private MachineOperand ParseSwappedOperand(ushort opcode, int bitOffset, PrimitiveType dataWidth, ImageReader rdr) { opcode >>= bitOffset; byte addressMode = (byte) (opcode & 7); byte operandBits = (byte) ((opcode >> 3) & 7); return ParseOperandInner(addressMode, operandBits, dataWidth, rdr); }
public override ProcedureBase GetTrampolineDestination(ImageReader imageReader, IRewriterHost host) { return null; }
private static M68kImmediateOperand GetImmediate(ImageReader rdr, PrimitiveType type) { if (type.Size == 1) { rdr.ReadByte(); // skip a byte so we get the appropriate lsb byte and align the word stream. } return new M68kImmediateOperand(rdr.ReadBe(type)); }
public override IEnumerable<Address> CreateInstructionScanner(ImageMap map, ImageReader rdr, IEnumerable<Address> knownAddresses, PointerScannerFlags flags) { var knownLinAddresses = knownAddresses.Select(a => (ulong)a.ToLinear()).ToHashSet(); return new X86PointerScanner64(rdr, knownLinAddresses, flags).Select(li => map.MapLinearAddressToAddress(li)); }
private MachineOperand ParseOperandInner(byte addressMode, byte operandBits, PrimitiveType dataWidth, ImageReader rdr) { Constant offset; switch (addressMode) { case 0: // Data register direct. return DataRegisterOperand(operandBits, 0); case 1: // Address register direct return new RegisterOperand(AddressRegister(operandBits, 0)); case 2: // Address register indirect return MemoryOperand.Indirect(dataWidth, AddressRegister(operandBits, 0)); case 3: // Address register indirect with postincrement. return MemoryOperand.PostIncrement(dataWidth, AddressRegister(operandBits, 0)); case 4: // Address register indirect with predecrement. return MemoryOperand.PreDecrement(dataWidth, AddressRegister(operandBits, 0)); case 5: // Address register indirect with displacement. offset = Constant.Int16(rdr.ReadBeInt16()); return MemoryOperand.Indirect(dataWidth, AddressRegister(operandBits, 0), offset); case 6: // Address register indirect with index return AddressRegisterIndirectWithIndex(dataWidth, rdr); case 7: switch (operandBits) { case 0: // Absolute short address return new M68kAddressOperand(rdr.ReadBeUInt16()); case 1: // Absolute long address return new M68kAddressOperand(rdr.ReadBeUInt32()); case 2: // Program counter with displacement var off = rdr.Address - dasm.instr.Address; off += rdr.ReadBeInt16(); return new MemoryOperand(dataWidth, Registers.pc, Constant.Int16((short) off)); case 3: // Program counter with index var addrExt = rdr.Address; ushort extension = rdr.ReadBeUInt16(); if (EXT_FULL(extension)) { if (EXT_EFFECTIVE_ZERO(extension)) { return new M68kImmediateOperand(Constant.Word32(0)); } Constant @base = null; Constant outer = null; if (EXT_BASE_DISPLACEMENT_PRESENT(extension)) @base = EXT_BASE_DISPLACEMENT_LONG(extension) ? rdr.ReadBe(PrimitiveType.Word32) : rdr.ReadBe(PrimitiveType.Int16); if (EXT_OUTER_DISPLACEMENT_PRESENT(extension)) outer = EXT_OUTER_DISPLACEMENT_LONG(extension) ? rdr.ReadBe(PrimitiveType.Word32) : rdr.ReadBe(PrimitiveType.Int16); RegisterStorage base_reg = EXT_BASE_REGISTER_PRESENT(extension) ? Registers.pc : null; RegisterStorage index_reg = null; PrimitiveType index_width = null; int index_scale = 0; if (EXT_INDEX_REGISTER_PRESENT(extension)) { index_reg = EXT_INDEX_AR(extension) ? Registers.AddressRegister((int)EXT_INDEX_REGISTER(extension)) : Registers.DataRegister((int)EXT_INDEX_REGISTER(extension)); index_width = EXT_INDEX_LONG(extension) ? PrimitiveType.Word32 : PrimitiveType.Int16; index_scale = (EXT_INDEX_SCALE(extension) != 0) ? 1 << EXT_INDEX_SCALE(extension) : 0; } return new IndexedOperand(dataWidth, @base, outer, base_reg, index_reg, index_width, index_scale, (extension & 7) > 0 && (extension & 7) < 4, (extension & 7) > 4); } return new IndirectIndexedOperand( EXT_8BIT_DISPLACEMENT(extension), Registers.pc, EXT_INDEX_AR(extension) ? Registers.AddressRegister((int)EXT_INDEX_REGISTER(extension)) : Registers.DataRegister((int)EXT_INDEX_REGISTER(extension)), EXT_INDEX_LONG(extension) ? PrimitiveType.Word32 : PrimitiveType.Int16, 1 << EXT_INDEX_SCALE(extension)); case 4: // Immediate if (dataWidth.Size == 1) // don't want the instruction stream to get misaligned! rdr.ReadByte(); return new M68kImmediateOperand(rdr.ReadBe(dataWidth)); default: throw new NotImplementedException(string.Format("Address mode {0}:{1} not implemented.", addressMode, operandBits)); } default: throw new NotImplementedException(string.Format("Address mode {0:X1} not implemented.", addressMode)); } }
public override X86Disassembler CreateDisassembler(ImageReader rdr) { return new X86Disassembler(rdr, PrimitiveType.Word32, PrimitiveType.Word64, true); }
public MachineOperand GetOperand(ImageReader rdr, string args, PrimitiveType dataWidth) { if (i >= args.Length) return null; for (; ; ) { if (args[i] == ',') ++i; Address addr; switch (args[i++]) { case 'A': // Address register A0-A7 encoded in in instrution return new RegisterOperand(AddressRegister(opcode, GetOpcodeOffset(args[i++]))); case 'c': // CCR register return new RegisterOperand(Registers.ccr); case 'D': // Data register D0-D7 encoded in instruction return DataRegisterOperand(opcode, GetOpcodeOffset(args[i++])); case 'E': // Effective address (EA) return ParseOperand(opcode, GetOpcodeOffset(args[i++]), dataWidth, rdr); case 'e': // Effective address with 3-bit halves swapped return ParseSwappedOperand(opcode, GetOpcodeOffset(args[i++]), dataWidth, rdr); case 'I': // Immediate operand return GetImmediate(rdr, GetSizeType(0, args[i++], dataWidth)); case 'J': // PC Relative jump addr = rdr.Address; int offset = opcode & 0xFF; if (offset == 0xFF) offset = rdr.ReadBeInt32(); else if (offset == 0x00) offset = rdr.ReadBeInt16(); else offset = (sbyte) offset; return new M68kAddressOperand(addr + offset); case 'M': // Register bitset return new RegisterSetOperand(rdr.ReadBeUInt16()); case 'n': // cache bitset bitSet = rdr.ReadBeUInt16(); break; case 'm': // Register bitset reversed return RegisterSetOperand.CreateReversed(bitSet); case 'q': // "Small" quick constant (3-bit part of the opcode) return GetQuickImmediate(GetOpcodeOffset(args[i++]), 0x07, 8, PrimitiveType.Byte); case 'Q': // "Large" quick constant (8-bit part of the opcode) return GetQuickImmediate(GetOpcodeOffset(args[i++]), 0xFF, 0, PrimitiveType.SByte); case 'R': // relative addr = rdr.Address; int relative = 0; switch (args[i++]) { case 'w': relative = rdr.ReadBeInt16(); break; case 'l': relative = rdr.ReadBeInt32(); break; default: throw new NotImplementedException(); } return new M68kAddressOperand(addr + relative); case 's': // SR register return new RegisterOperand(Registers.sr); case '+': // Postincrement operator; following character specifies bit offset of the address register code. return new PostIncrementMemoryOperand(dataWidth, AddressRegister(opcode, GetOpcodeOffset(args[i++]))); case '-': // Predecrement operator; following character specifies bit offset of the address register code. return new PredecrementMemoryOperand(dataWidth, AddressRegister(opcode, GetOpcodeOffset(args[i++]))); default: throw new FormatException(string.Format("Unknown argument type {0}.", args[--i])); } } }
public override Address ReadCodeAddress(int byteSize, ImageReader rdr, ProcessorState state) { return Address.Ptr64(rdr.ReadLeUInt64()); }
public IEnumerable<RtlInstructionCluster> CreateRewriter(ImageReader rdr, ProcessorState state, Frame frame, IRewriterHost host) { return new Z80Rewriter(this, rdr, state, frame, host); }
public abstract IEnumerable<Address> CreateInstructionScanner(ImageMap map, ImageReader rdr, IEnumerable<Address> knownAddresses, PointerScannerFlags flags);
public IEnumerable<RtlInstructionCluster> CreateRewriter(ImageReader rdr, ProcessorState state, Frame frame, IRewriterHost host) { return new Pdp11Rewriter(this, new Pdp11Disassembler(rdr, this), frame); }
public abstract X86Disassembler CreateDisassembler(ImageReader rdr);
public IEnumerable<MachineInstruction> CreateDisassembler(ImageReader rdr) { return new Pdp11Disassembler(rdr, this); }
public abstract Address ReadCodeAddress(int byteSize, ImageReader rdr, ProcessorState state);