/// <summary> /// Generates a stream of <see cref="RtlInstructionCluster"/>s. /// </summary> /// <remarks> /// The default implementation should work for most architectures, but you have the option /// of overriding for specialized testing. /// </remarks> protected virtual IEnumerable <RtlInstructionCluster> GetRtlStream(MemoryArea mem, IStorageBinder binder, IRewriterHost host) { var state = Architecture.CreateProcessorState(); var rdr = Architecture.Endianness.CreateImageReader(mem, 0); return(Architecture.CreateRewriter(rdr, state, binder, host)); }
protected override IEnumerable <RtlInstructionCluster> GetRtlStream(IStorageBinder binder, IRewriterHost host) { return(Architecture.CreateRewriter( new BeImageReader(image, image.BaseAddress), Architecture.CreateProcessorState(), binder, host)); }
protected override IEnumerable <RtlInstructionCluster> GetRtlStream(MemoryArea mem, IStorageBinder binder, IRewriterHost host) { return(Architecture.CreateRewriter( mem.CreateBeReader(mem.BaseAddress), Architecture.CreateProcessorState(), binder, host)); }
public override ProcedureBase GetTrampolineDestination(EndianImageReader 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); } // Match x86 pattern. // jmp [destination] Address addrTarget = null; var jump = rtlc.Instructions[0] as RtlGoto; if (jump != null) { var pc = jump.Target as ProcedureConstant; if (pc != null) { return(pc.Procedure); } var access = jump.Target as MemoryAccess; if (access == null) { return(null); } addrTarget = access.EffectiveAddress as Address; if (addrTarget == null) { var wAddr = access.EffectiveAddress as Constant; if (wAddr == null) { return(null); } addrTarget = MakeAddressFromConstant(wAddr); } } if (addrTarget == null) { return(null); } ProcedureBase proc = host.GetImportedProcedure(addrTarget, rtlc.Address); if (proc != null) { return(proc); } return(host.GetInterceptedCall(addrTarget)); }
/// <summary> /// The sequence /// lui rX,hiword /// lw rY,[rX + loword] /// jr rY /// is treated as a trampoline. /// </summary> /// <param name="imageReader"></param> /// <param name="host"></param> /// <returns></returns> public override ProcedureBase GetTrampolineDestination(ImageReader imageReader, IRewriterHost host) { var rtls = Architecture.CreateRewriter( imageReader, Architecture.CreateProcessorState(), Architecture.CreateFrame(), host) .Take(3) .ToArray(); if (rtls.Length < 3) { return(null); } var instrs = rtls .SelectMany(rtl => rtl.Instructions) .ToArray(); for (int i = 0; i < 3; ++i) { if (!trampPattern[i].Match(instrs[i])) { return(null); } } if (trampPattern[0].CapturedExpressions("r0d") != trampPattern[1].CapturedExpressions("r1s")) { return(null); } if (trampPattern[1].CapturedExpressions("r1d") != trampPattern[2].CapturedExpressions("r2s")) { return(null); } var hi = (Constant)trampPattern[0].CapturedExpressions("hi"); var lo = (Constant)trampPattern[1].CapturedExpressions("lo"); var c = Operator.IAdd.ApplyConstants(hi, lo); var addrTarget = MakeAddressFromConstant(c); ProcedureBase proc = host.GetImportedProcedure(addrTarget, rtls[2].Address); if (proc != null) { return(proc); } return(host.GetInterceptedCall(addrTarget)); }