private void OnMemoryMapChanged() { //var tlSvc = Services.RequireService<ITypeLibraryLoaderService>(); var tser = new TypeLibraryDeserializer(this, true, Metadata); var sser = new ProcedureSerializer(this, tser, DefaultCallingConvention); var disps = new Dictionary <Address, DispatchProcedure>(); foreach (var callable in this.MemoryMap.Segments.SelectMany(s => s.Procedures)) { if (callable is DispatchProcedure_v1 sDisp) { if (sDisp.Services == null) { continue; } var svcs = sDisp.Services .Where(s => s.SyscallInfo != null) .Select(s => ( s.SyscallInfo.Build(this), new ExternalProcedure( s.Name, sser.Deserialize(s.Signature, Architecture.CreateFrame())))) .ToList(); if (Architecture.TryParseAddress(sDisp.Address, out var addr)) { var disp = new DispatchProcedure( sDisp.Name, svcs); disps.Add(addr, disp); } } } this.dispatchProcedures = disps; }
private Dictionary <int, SystemService> LoadLibraryDef(string lib_name, int version, TypeLibrary libDst) { var tlSvc = Services.RequireService <ITypeLibraryLoaderService>(); var fsSvc = Services.RequireService <IFileSystemService>(); var tser = new TypeLibraryDeserializer(this, true, libDst); var sser = new ProcedureSerializer(this, tser, DefaultCallingConvention); using (var rdr = new StreamReader(fsSvc.CreateFileStream(tlSvc.InstalledFileLocation(lib_name + ".funcs"), FileMode.Open, FileAccess.Read))) { var fpp = new FuncsFileParser((M68kArchitecture)this.Architecture, rdr); fpp.Parse(); return(fpp.FunctionsByLibBaseOffset.Values .Select(amiSvc => new SystemService { Name = amiSvc.Name, SyscallInfo = new SyscallInfo { Vector = amiSvc.Offset, }, Signature = sser.Deserialize(amiSvc.Signature, Architecture.CreateFrame()), //$BUGBUG: catch dupes? Characteristics = new ProcedureCharacteristics { } }) .ToDictionary(de => de.SyscallInfo.Vector, de => de)); }; }
private Dictionary <int, SystemService> LoadFuncs() { var fsSvc = Services.RequireService <IFileSystemService>(); var sser = Architecture.CreateProcedureSerializer( new TypeLibraryLoader(Architecture, true), DefaultCallingConvention); using (var rdr = new StreamReader(fsSvc.CreateFileStream("exec.funcs", FileMode.Open, FileAccess.Read))) { var fpp = new FuncsFileParser((M68kArchitecture)this.Architecture, rdr); fpp.Parse(); return(fpp.FunctionsByA6Offset.Values .Select(amiSvc => new SystemService { Name = amiSvc.Name, SyscallInfo = new SyscallInfo { Vector = amiSvc.Offset, }, Signature = sser.Deserialize(amiSvc.Signature, Architecture.CreateFrame()), //$BUGBUG: catch dupes? Characteristics = new ProcedureCharacteristics { } }) .ToDictionary(de => de.SyscallInfo.Vector, de => de)); }; }
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)); }
protected void AssertCode(params string[] expected) { int i = 0; var frame = Architecture.CreateFrame(); var host = CreateRewriterHost(); var rewriter = GetInstructionStream(frame, host).GetEnumerator(); while (i < expected.Length && rewriter.MoveNext()) { Assert.AreEqual(expected[i], string.Format("{0}|{1}|{2}", i, RtlInstruction.FormatClass(rewriter.Current.Class), rewriter.Current)); ++i; var ee = rewriter.Current.Instructions.OfType <RtlInstruction>().GetEnumerator(); while (i < expected.Length && ee.MoveNext()) { Assert.AreEqual(expected[i], string.Format("{0}|{1}|{2}", i, RtlInstruction.FormatClass(ee.Current.Class), ee.Current)); ++i; } } Assert.AreEqual(expected.Length, i, "Expected " + expected.Length + " instructions."); Assert.IsFalse(rewriter.MoveNext(), "More instructions were emitted than were expected."); }