public void GcrStackArguments() { Frame f = program.Architecture.CreateFrame(); f.ReturnAddressKnown = true; f.ReturnAddressSize = PrimitiveType.Word16.Size; var uses = new List <KeyValuePair <Storage, BitRange> > { new KeyValuePair <Storage, BitRange>(new StackArgumentStorage(8, PrimitiveType.Word16), new BitRange(0, 16)), new KeyValuePair <Storage, BitRange>(new StackArgumentStorage(6, PrimitiveType.Word16), new BitRange(0, 16)), new KeyValuePair <Storage, BitRange>(new StackArgumentStorage(0xE, PrimitiveType.Word32), new BitRange(0, 32)) }; CallRewriter gcr = new CallRewriter(null, null, new FakeDecompilerEventListener()); using (FileUnitTester fut = new FileUnitTester("Analysis/GcrStackParameters.txt")) { foreach ((int, Identifier)de in gcr.GetSortedStackArguments(f, uses)) { fut.TextWriter.Write("{0:X4} ", de.Item1); de.Item2.Write(true, fut.TextWriter); fut.TextWriter.WriteLine(); } fut.AssertFilesEqual(); } }
public void CrwMakeSig_Sequence_InArg() { flow.BitsUsed.Add(new SequenceStorage(Registers.edx, Registers.eax), new BitRange(0, 64)); var crw = new CallRewriter(program.Platform, new ProgramDataFlow(), eventListener); var sig = crw.MakeSignature(new SsaState(proc), proc.Frame, flow); Assert.AreEqual("(fn void (word64))", sig.ToString()); }
private CallRewriter When_CallRewriterCreated() { var program = pb.BuildProgram(); var flow = new ProgramDataFlow(program); var crw = new CallRewriter( program.Platform, flow, new FakeDecompilerEventListener()); return(crw); }
public void Setup() { program = new Program(); program.Architecture = new X86ArchitectureFlat32("x86-protected-32"); program.Platform = new DefaultPlatform(null, program.Architecture); crw = new CallRewriter(program.Platform, new ProgramDataFlow(), new FakeDecompilerEventListener()); proc = new Procedure(program.Architecture, "foo", Address.Ptr32(0x00123400), program.Architecture.CreateFrame()); flow = new ProcedureFlow(proc); ssa = new SsaState(proc); pb = new ProgramBuilder(); ssaStates = new List <SsaState>(); eventListener = new FakeDecompilerEventListener(); }
public void CrwSinglePredecessorToExitBlock() { var m = new ProcedureBuilder("CrwSinglePredecessorToExitBlock"); var eax = m.Frame.EnsureRegister(Registers.eax); m.Assign(eax, m.Mem32(eax)); m.Return(); var flow = new ProgramDataFlow(program); var sst = new SsaTransform(program, m.Procedure, new HashSet <Procedure>(), null, new ProgramDataFlow()); sst.Transform(); sst.AddUsesToExitBlock(); sst.SsaState.Procedure.Signature = FunctionType.Func( new Identifier("", PrimitiveType.Word32, Registers.eax), new Identifier("eax", PrimitiveType.Word32, Registers.eax)); var crw = new CallRewriter(this.platform, flow, new FakeDecompilerEventListener()); crw.RewriteReturns(sst.SsaState); crw.RemoveStatementsFromExitBlock(sst.SsaState); var sExp = #region Expected @"eax:eax def: def eax uses: eax_3 = Mem0[eax:word32] Mem0:Mem def: def Mem0 uses: eax_3 = Mem0[eax:word32] eax_3: orig: eax def: eax_3 = Mem0[eax:word32] uses: return eax_3 // CrwSinglePredecessorToExitBlock // Return size: 0 word32 CrwSinglePredecessorToExitBlock(word32 eax) CrwSinglePredecessorToExitBlock_entry: def eax def Mem0 // succ: l1 l1: eax_3 = Mem0[eax:word32] return eax_3 // succ: CrwSinglePredecessorToExitBlock_exit CrwSinglePredecessorToExitBlock_exit: "; #endregion AssertExpected(sExp, sst.SsaState); }
public void Setup() { program = new Program(); sc = new ServiceContainer(); program.Architecture = new X86ArchitectureFlat32(sc, "x86-protected-32", new Dictionary <string, object>()); program.Platform = new DefaultPlatform(sc, program.Architecture); crw = new CallRewriter(program.Platform, new ProgramDataFlow(), new FakeDecompilerEventListener()); proc = new Procedure(program.Architecture, "foo", Address.Ptr32(0x00123400), program.Architecture.CreateFrame()); flow = new ProcedureFlow(proc); ssa = new SsaState(proc); pb = new ProgramBuilder(); ssaStates = new List <SsaState>(); eventListener = new FakeDecompilerEventListener(); sc.AddService <DecompilerEventListener>(eventListener); }
protected override void RunTest(Program program, TextWriter writer) { var dynamicLinker = new Mock <IDynamicLinker>(); dfa = new DataFlowAnalysis(program, dynamicLinker.Object, sc); var ssts = dfa.RewriteProceduresToSsa(); // Discover ssaId's that are live out at each call site. // Delete all others. var uvr = new UnusedOutValuesRemover( program, ssts.Select(sst => sst.SsaState), dfa.ProgramDataFlow, dynamicLinker.Object, eventListener); uvr.Transform(); foreach (var p in program.Procedures.Values) { p.Dump(true); Debug.Print("===="); } // At this point, the exit blocks contain only live out registers. // We can create signatures from that. CallRewriter.Rewrite(program.Platform, ssts, dfa.ProgramDataFlow, eventListener); foreach (var proc in program.Procedures.Values) { var flow = dfa.ProgramDataFlow[proc]; proc.Signature.Emit(proc.Name, FunctionType.EmitFlags.ArgumentKind, new TextFormatter(writer)); writer.WriteLine(); flow.Emit(program.Architecture, writer); proc.Write(true, writer); writer.Flush(); } ssts.ForEach(sst => sst.SsaState.Validate(s => Assert.Fail(s))); }
public void CrwManyPredecessorsToExitBlock() { var m = new ProcedureBuilder("CrwManyPredecessorsToExitBlock"); var eax = m.Frame.EnsureRegister(Registers.eax); m.BranchIf(m.Ge0(eax), "m2Ge"); m.Label("m1Lt"); m.Assign(eax, -1); m.Return(); m.Label("m2Ge"); m.BranchIf(m.Ne0(eax), "m4Gt"); m.Label("m3Eq"); m.Return(); m.Label("m4Gt"); m.Assign(eax, 1); m.Return(); var flow = new ProgramDataFlow(program); var sst = new SsaTransform(program, m.Procedure, new HashSet <Procedure>(), null, new ProgramDataFlow()); sst.Transform(); sst.AddUsesToExitBlock(); sst.SsaState.Procedure.Signature = FunctionType.Func( new Identifier("", PrimitiveType.Word32, Registers.eax), new Identifier("eax", PrimitiveType.Word32, Registers.eax)); var crw = new CallRewriter(this.platform, flow, new FakeDecompilerEventListener()); crw.RewriteReturns(sst.SsaState); crw.RemoveStatementsFromExitBlock(sst.SsaState); var sExp = #region Expected @"eax:eax def: def eax uses: branch eax >= 0<32> m2Ge branch eax != 0<32> m4Gt return eax eax_2: orig: eax def: eax_2 = 1<32> uses: return eax_2 eax_3: orig: eax def: eax_3 = 0xFFFFFFFF<32> uses: return eax_3 eax_4: orig: eax // CrwManyPredecessorsToExitBlock // Return size: 0 word32 CrwManyPredecessorsToExitBlock(word32 eax) CrwManyPredecessorsToExitBlock_entry: def eax // succ: l1 l1: branch eax >= 0<32> m2Ge // succ: m1Lt m2Ge m1Lt: eax_3 = 0xFFFFFFFF<32> return eax_3 // succ: CrwManyPredecessorsToExitBlock_exit m2Ge: branch eax != 0<32> m4Gt // succ: m3Eq m4Gt m3Eq: return eax // succ: CrwManyPredecessorsToExitBlock_exit m4Gt: eax_2 = 1<32> return eax_2 // succ: CrwManyPredecessorsToExitBlock_exit CrwManyPredecessorsToExitBlock_exit: "; #endregion AssertExpected(sExp, sst.SsaState); }