/// <summary> /// The sequence /// lui rX,hiword /// lw rY,[rX + loword] /// jr rY /// is treated as a trampoline. /// </summary> /// <param name="insts"></param> /// <param name="host"></param> /// <returns></returns> public override ProcedureBase? GetTrampolineDestination(Address addrInstr, IEnumerable<RtlInstruction> rtls, IRewriterHost host) { var instrs = rtls .Take(3) .ToArray(); var addrFrom = addrInstr; if (instrs.Length < 3) return null; 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, false); ProcedureBase? proc = host.GetImportedProcedure(this.Architecture, addrTarget, addrFrom); if (proc != null) return proc; return host.GetInterceptedCall(this.Architecture, addrTarget); }
public ExternalProcedure ImportedProcedure(Address addrInstruction, PrimitiveType addrWidth, MemoryOperand mem) { if (mem != null && addrWidth == PrimitiveType.Word32 && mem.Base == RegisterStorage.None && mem.Index == RegisterStorage.None) { return(host.GetImportedProcedure(Address.Ptr32(mem.Offset.ToUInt32()), addrInstruction)); } return(null); }
public Expression CreateMemoryAccess(X86Instruction instr, MemoryOperand mem, DataType dt, X86State state) { Expression expr = EffectiveAddressExpression(instr, mem, state); //$REVIEW: perhaps the code below could be moved to Scanner since it is arch-independent? if (expr is Address addrThunk) { var exg = host.GetImport(addrThunk, instr.Address); if (exg is ProcedureConstant) { return(exg); } else if (exg != null) { return(new UnaryExpression(Operator.AddrOf, dt, exg)); } var exp = host.GetImportedProcedure(arch, addrThunk, instr.Address); if (exp != null) { return(new ProcedureConstant(arch.PointerType, exp)); } } if (IsSegmentedAccessRequired || (mem.DefaultSegment != Registers.cs && mem.DefaultSegment != Registers.ds && mem.DefaultSegment != Registers.ss)) { Expression seg; if (mem.DefaultSegment == Registers.cs) { seg = Constant.Create(PrimitiveType.SegmentSelector, instr.Address.Selector.Value); } else { seg = AluRegister(mem.DefaultSegment); } return(new SegmentedAccess(MemoryIdentifier.GlobalMemory, seg, expr, dt)); } else { return(new MemoryAccess(MemoryIdentifier.GlobalMemory, expr, dt)); } }
//public override ProcedureBase GetTrampolineDestination(EndianImageReader rdr, IRewriterHost host) //{ // var dasm = new PowerPcDisassembler(this, rdr, WordWidth); // return GetTrampolineDestination(dasm, host); //} /// <summary> /// Detects the presence of a PowerPC trampoline and returns the imported function /// that is actually being requested. /// </summary> /// <remarks> /// A PowerPC trampoline looks like this: /// addis rX,r0,XXXX (or oris rx,r0,XXXX) /// lwz rY,YYYY(rX) /// mtctr rY /// bctr rY /// When loading the ELF binary, we discovered the memory locations /// that will contain pointers to imported functions. If the address /// XXXXYYYY matches one of those memory locations, we have found a /// trampoline. /// </remarks> /// <param name="rdr"></param> /// <param name="host"></param> /// <returns></returns> public ProcedureBase GetTrampolineDestination(IEnumerable <PowerPcInstruction> rdr, IRewriterHost host) { var e = rdr.GetEnumerator(); if (!e.MoveNext() || (e.Current.Opcode != Opcode.addis && e.Current.Opcode != Opcode.oris)) { return(null); } var addrInstr = e.Current.Address; var reg = ((RegisterOperand)e.Current.op1).Register; var uAddr = ((ImmediateOperand)e.Current.op3).Value.ToUInt32() << 16; if (!e.MoveNext() || e.Current.Opcode != Opcode.lwz) { return(null); } var mem = e.Current.op2 as MemoryOperand; if (mem == null) { return(null); } if (mem.BaseRegister != reg) { return(null); } uAddr = (uint)((int)uAddr + mem.Offset.ToInt32()); reg = ((RegisterOperand)e.Current.op1).Register; if (!e.MoveNext() || e.Current.Opcode != Opcode.mtctr) { return(null); } if (((RegisterOperand)e.Current.op1).Register != reg) { return(null); } if (!e.MoveNext() || e.Current.Opcode != Opcode.bcctr) { return(null); } // We saw a thunk! now try to resolve it. var addr = Address.Ptr32(uAddr); var ep = host.GetImportedProcedure(addr, addrInstr); if (ep != null) { return(ep); } return(host.GetInterceptedCall(addr)); }
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)); }
public override ProcedureBase GetTrampolineDestination(IEnumerable <RtlInstructionCluster> rw, IRewriterHost host) { var rtlc = rw.FirstOrDefault(); if (rtlc == null || rtlc.Instructions.Length == 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)); }
public override ProcedureBase GetTrampolineDestination(IEnumerable <RtlInstructionCluster> rw, IRewriterHost host) { var rtlc = rw.FirstOrDefault(); if (rtlc == null || rtlc.Instructions.Length == 0) { return(null); } // Match x86 pattern. // jmp [destination] Address addrTarget = null; if (rtlc.Instructions[0] is RtlGoto jump) { if (jump.Target is ProcedureConstant pc) { return(pc.Procedure); } if (!(jump.Target is MemoryAccess access)) { return(null); } addrTarget = access.EffectiveAddress as Address; if (addrTarget == null) { if (!(access.EffectiveAddress is Constant wAddr)) { return(null); } addrTarget = MakeAddressFromConstant(wAddr, true); } } if (addrTarget == null) { return(null); } var arch = this.Architecture; ProcedureBase proc = host.GetImportedProcedure(arch, addrTarget, rtlc.Address); if (proc != null) { return(proc); } return(host.GetInterceptedCall(arch, addrTarget)); }
public override ProcedureBase GetTrampolineDestination(IEnumerable <RtlInstructionCluster> rdr, IRewriterHost host) { var rtlc = rdr.FirstOrDefault(); if (rtlc == null) { 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(this.Architecture, addrTarget, rtlc.Address); if (proc != null) { return(proc); } return(host.GetInterceptedCall(this.Architecture, 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)); }
public override ProcedureBase?GetTrampolineDestination(Address addrInstr, IEnumerable <RtlInstruction> rw, IRewriterHost host) { var instr = rw.FirstOrDefault(); if (instr == null) { return(null); } if (instr is not RtlGoto jump) { return(null); } if (jump.Target is ProcedureConstant pc) { return(pc.Procedure); } if (jump.Target is not MemoryAccess access) { return(null); } //$REFACTOR: the following code is identical to Win32MipsPlatform / Win32Platform var addrTarget = access.EffectiveAddress as Address; if (addrTarget is null) { if (access.EffectiveAddress is not Constant wAddr) { return(null); } addrTarget = MakeAddressFromConstant(wAddr, false); if (addrTarget is null) { return(null); } } ProcedureBase?proc = host.GetImportedProcedure(this.Architecture, addrTarget, addrInstr); if (proc is not null) { return(proc); } return(host.GetInterceptedCall(this.Architecture, addrTarget)); }
public override ProcedureBase?GetTrampolineDestination(Address addrInstr, IEnumerable <RtlInstruction> instrs, IRewriterHost host) { var target = archHandler.GetTrampolineDestination(addrInstr, instrs, host); if (target is Address addrTarget) { var arch = this.Architecture; ProcedureBase?proc = host.GetImportedProcedure(arch, addrTarget, addrInstr); if (proc != null) { return(proc); } return(host.GetInterceptedCall(arch, addrTarget)); } else { return(null); } }
public override ProcedureBase?GetTrampolineDestination(Address addrInstr, IEnumerable <RtlInstruction> rdr, IRewriterHost host) { var instr = rdr.FirstOrDefault(); if (instr is null) { return(null); } if (instr is not RtlGoto jump) { return(null); } if (jump.Target is ProcedureConstant pc) { return(pc.Procedure); } if (jump.Target is not MemoryAccess access) { return(null); } var addrTarget = access.EffectiveAddress as Address; if (addrTarget is null) { if (access.EffectiveAddress is not Constant wAddr) { return(null); } addrTarget = MakeAddressFromConstant(wAddr, true); if (addrTarget is null) { return(null); } } ProcedureBase?proc = host.GetImportedProcedure(this.Architecture, addrTarget, addrInstr); if (proc is not null) { return(proc); } return(host.GetInterceptedCall(this.Architecture, addrTarget)); }
/// <summary> /// The sequence /// lui rX,hiword /// lw rY,[rX + loword] /// jr rY /// is treated as a trampoline. /// </summary> /// <param name="insts"></param> /// <param name="host"></param> /// <returns></returns> public override ProcedureBase GetTrampolineDestination(IEnumerable <RtlInstructionCluster> rtls, IRewriterHost host) { var instrs = rtls.SelectMany(r => r.Instructions) .Take(3) .ToArray(); var addrFrom = rtls.ElementAt(2).Address; if (instrs.Length < 3) { return(null); } 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(this.Architecture, addrTarget, addrFrom); if (proc != null) { return(proc); } return(host.GetInterceptedCall(this.Architecture, addrTarget)); }
public override ProcedureBase GetTrampolineDestination(Address addrInstr, IEnumerable <RtlInstruction> rw, IRewriterHost host) { var finder = archSpecificFactory.CreateTrampolineDestinationFinder(this.Architecture); var target = finder(Architecture, addrInstr, rw, host); if (target is ProcedureConstant pc) { return(pc.Procedure); } else if (target is Address addrTarget) { var arch = this.Architecture; ProcedureBase proc = host.GetImportedProcedure(arch, addrTarget, addrInstr); if (proc != null) { return(proc); } return(host.GetInterceptedCall(arch, addrTarget)); } else { return(null); } }
//public override ProcedureBase GetTrampolineDestination(ImageReader rdr, IRewriterHost host) //{ // var dasm = new PowerPcDisassembler(this, rdr, WordWidth); // return GetTrampolineDestination(dasm, host); //} /// <summary> /// Detects the presence of a PowerPC trampoline and returns the imported function /// that is actually being requested. /// </summary> /// <remarks> /// A PowerPC trampoline looks like this: /// addis rX,r0,XXXX (or oris rx,r0,XXXX) /// lwz rY,YYYY(rX) /// mtctr rY /// bctr rY /// When loading the ELF binary, we discovered the memory locations /// that will contain pointers to imported functions. If the address /// XXXXYYYY matches one of those memory locations, we have found a /// trampoline. /// </remarks> /// <param name="rdr"></param> /// <param name="host"></param> /// <returns></returns> public ProcedureBase GetTrampolineDestination(IEnumerable<PowerPcInstruction> rdr, IRewriterHost host) { var e = rdr.GetEnumerator(); if (!e.MoveNext() || (e.Current.Opcode != Opcode.addis && e.Current.Opcode != Opcode.oris)) return null; var addrInstr = e.Current.Address; var reg = ((RegisterOperand)e.Current.op1).Register; var uAddr = ((ImmediateOperand)e.Current.op3).Value.ToUInt32() << 16; if (!e.MoveNext() || e.Current.Opcode != Opcode.lwz) return null; var mem = e.Current.op2 as MemoryOperand; if (mem == null) return null; if (mem.BaseRegister != reg) return null; uAddr = (uint)((int)uAddr + mem.Offset.ToInt32()); reg = ((RegisterOperand)e.Current.op1).Register; if (!e.MoveNext() || e.Current.Opcode != Opcode.mtctr) return null; if (((RegisterOperand)e.Current.op1).Register != reg) return null; if (!e.MoveNext() || e.Current.Opcode != Opcode.bcctr) return null; // We saw a thunk! now try to resolve it. var addr = Address.Ptr32(uAddr); var ep = host.GetImportedProcedure(addr, addrInstr); if (ep != null) return ep; return host.GetInterceptedCall(addr); }
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); }
/// <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); }