Пример #1
0
        /// <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);
        }
Пример #2
0
 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);
 }
Пример #3
0
        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));
            }
        }
Пример #4
0
        //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));
        }
Пример #5
0
        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));
        }
Пример #6
0
        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));
        }
Пример #7
0
        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));
        }
Пример #8
0
        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));
        }
Пример #9
0
        /// <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));
        }
Пример #10
0
        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));
        }
Пример #11
0
        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);
            }
        }
Пример #12
0
        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));
        }
Пример #13
0
        /// <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));
        }
Пример #14
0
        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);
            }
        }
Пример #15
0
        //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);
        }
Пример #16
0
 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);
 }
Пример #17
0
        /// <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);
        }