protected override void RunTest(Program program, string outputFile) { var eventListener = new FakeDecompilerEventListener(); using (FileUnitTester fut = new FileUnitTester(outputFile)) { fut.TextWriter.WriteLine("// Before ///////"); DumpProgram(program, fut.TextWriter); SetupPreStages(program); aen.Transform(program); eqb.Build(program); var coll = new TypeCollector(program.TypeFactory, program.TypeStore, program,eventListener); coll.CollectTypes(); program.TypeStore.BuildEquivalenceClassDataTypes(program.TypeFactory); tvr.ReplaceTypeVariables(); trans.Transform(); ctn.RenameAllTypes(program.TypeStore); ter = new TypedExpressionRewriter(program, eventListener); try { ter.RewriteProgram(program); } catch (Exception ex) { fut.TextWriter.WriteLine("** Exception **"); fut.TextWriter.WriteLine(ex); } finally { fut.TextWriter.WriteLine("// After ///////"); DumpProgAndStore(program, fut); } } }
/// <summary> /// Performs type analysis and rewrites program based on the inferred /// information. /// </summary> /// <remarks> /// For instance, all MemoryAccesses will be converted to structure /// field accesses or array accesses as appropriate. /// </remarks> /// <param name="program"></param> public void RewriteProgram(Program program) { factory = program.TypeFactory; store = program.TypeStore; aen = new ExpressionNormalizer(program.Platform.PointerType); eqb = new EquivalenceClassBuilder(factory, store, eventListener); tyco = new TypeCollector( program.TypeFactory, program.TypeStore, program, eventListener); //dpa = new DerivedPointerAnalysis(factory, store, program.Architecture); tvr = new TypeVariableReplacer(store); trans = new TypeTransformer(factory, store,program, eventListener); ctn = new ComplexTypeNamer(); ter = new TypedExpressionRewriter(program, eventListener); // RestrictProcedures(program, 0, 60, true); // Re-enable this for debugging aen.Transform(program); eqb.Build(program); tyco.CollectTypes(); store.BuildEquivalenceClassDataTypes(factory); //dpa.FollowConstantPointers(prog); tvr.ReplaceTypeVariables(); eventListener.ShowStatus("Transforming datatypes."); var ppr = new PtrPrimitiveReplacer(factory, store, program); ppr.ReplaceAll(eventListener); trans.Transform(); ctn.RenameAllTypes(store); ter.RewriteProgram(program); }
public void Tmer_PointerToSingleItem() { var ptr = new Identifier("ptr", PrimitiveType.Word32, null); CreateTv(ptr, new Pointer(point, 4), new Pointer(point, 4)); var tmer = new TypedExpressionRewriter(program, null); var access = CreateTv(m.LoadDw(m.IAdd(ptr, 0))); Expression e = access.Accept(tmer); Assert.AreEqual("ptr->dw0000", e.ToString()); }
public void Tmer_PointerToSecondItemOfPoint() { Identifier ptr = new Identifier("ptr", PrimitiveType.Word32, null); store.EnsureExpressionTypeVariable(factory, ptr); EquivalenceClass eqPtr = new EquivalenceClass(ptr.TypeVariable); eqPtr.DataType = point; ptr.TypeVariable.OriginalDataType = new Pointer(point, 4); ptr.TypeVariable.DataType = new Pointer(eqPtr, 4); var c = Wrap(Constant.Word32(4)); var bin = Wrap(new BinaryExpression(BinaryOperator.IAdd, PrimitiveType.Word32, ptr, c)); var mem = Wrap(new MemoryAccess(bin, PrimitiveType.Word32)); var tmer = new TypedExpressionRewriter(program); Expression e = mem.Accept(tmer); Assert.AreEqual("ptr->dw0004", e.ToString()); }
/// <summary> /// Performs type analysis and rewrites program based on the inferred information. /// </summary> /// <remarks> /// For instance, all MemoryAccesses will be converted to structure field /// accesses or array accesses as appropriate. /// </remarks> /// <param name="program"></param> public void RewriteProgram(Program program) { factory = program.TypeFactory; store = program.TypeStore; aen = new ExpressionNormalizer(program.Platform.PointerType); eqb = new EquivalenceClassBuilder(factory, store); #if OLD dtb = new DataTypeBuilder(factory, store, program.Platform); trco = new TraitCollector(factory, store, dtb, program); #else tyco = new TypeCollector(program.TypeFactory, program.TypeStore, program); #endif //dpa = new DerivedPointerAnalysis(factory, store, program.Architecture); tvr = new TypeVariableReplacer(store); trans = new TypeTransformer(factory, store, program, eventListener); ctn = new ComplexTypeNamer(); ter = new TypedExpressionRewriter(program); // RestrictProcedures(program, 0, 1, true); // Re-enable this for debugging eventListener.ShowStatus("Gathering primitive datatypes from instructions."); aen.Transform(program); eqb.Build(program); #if OLD eventListener.ShowStatus("Collecting datatype usage traits."); trco.CollectProgramTraits(program); eventListener.ShowStatus("Building equivalence classes."); dtb.BuildEquivalenceClassDataTypes(); #else eventListener.ShowStatus("Collecting data types"); tyco.CollectTypes(); store.BuildEquivalenceClassDataTypes(factory); #endif //dpa.FollowConstantPointers(prog); tvr.ReplaceTypeVariables(); eventListener.ShowStatus("Transforming datatypes."); var ppr = new PtrPrimitiveReplacer(factory, store, program); ppr.ReplaceAll(); trans.Transform(); ctn.RenameAllTypes(store); store.Dump(); eventListener.ShowStatus("Rewriting expressions."); ter.RewriteProgram(program); }
public Expression VisitArrayAccess(ArrayAccess acc) { var ter = new TypedExpressionRewriter(prog); var arr = acc.Array.Accept(ter); var idx = acc.Index.Accept(ter); var ceb = new ComplexExpressionBuilder( acc.TypeVariable.DataType, acc.Array.TypeVariable.DataType, acc.Array.TypeVariable.OriginalDataType, basePointer, arr, idx, 0); ceb.Dereferenced = true; return(ceb.BuildComplex()); }
public Expression VisitMkSequence(MkSequence seq) { var ter = new TypedExpressionRewriter(prog); //$TODO: identical to TypedExpressionRewriter except for the ceb.Dereferenced statements. How to combine? var head = seq.Head.Accept(ter); var tail = seq.Tail.Accept(ter); Constant c = tail as Constant; var ptHead = head.TypeVariable.DataType as PrimitiveType; if (head.TypeVariable.DataType is Pointer || (ptHead != null && ptHead.Domain == Domain.Selector)) { if (c != null) { ComplexExpressionBuilder ceb = new ComplexExpressionBuilder( seq.TypeVariable.DataType, head.DataType, head.TypeVariable.OriginalDataType, null, head, null, StructureField.ToOffset(c)); ceb.Dereferenced = true; return(ceb.BuildComplex()); } else { var ceb = new ComplexExpressionBuilder( seq.TypeVariable.DataType, seq.TypeVariable.DataType, seq.TypeVariable.OriginalDataType, head, tail, null, 0); ceb.Dereferenced = true; return(ceb.BuildComplex()); } } else { } return(new MkSequence(seq.DataType, head, tail)); }
public Expression RewriteArrayAccess(TypeVariable typeVariable, Expression arr, Expression idx) { var ter = new TypedExpressionRewriter(prog); basePointer = null; dtResult = new Pointer(typeVariable.DataType, platform.PointerType.Size); var dtElement = Dereference(arr.TypeVariable.DataType); var dtElementOrig = Dereference(arr.TypeVariable.OriginalDataType); arr = arr.Accept(ter); idx = idx.Accept(ter); idx = RescaleIndex(idx, dtElement); var ceb = new ComplexExpressionBuilder( dtResult, dtElement, dtElementOrig, basePointer, new ArrayAccess(dtElement, arr, idx), null, 0); ceb.Dereferenced = true; return(ceb.BuildComplex()); }
/// <summary> /// Performs type analysis and rewrites program based on the inferred /// information. /// </summary> /// <remarks> /// For instance, all MemoryAccesses will be converted to structure /// field accesses or array accesses as appropriate. /// </remarks> /// <param name="program"></param> public void RewriteProgram(Program program) { factory = program.TypeFactory; store = program.TypeStore; var timer = new Stopwatch(); aen = new ExpressionNormalizer(program.Platform.PointerType); eqb = new EquivalenceClassBuilder(factory, store, eventListener); tyco = new TypeCollector( program.TypeFactory, program.TypeStore, program, eventListener); //dpa = new DerivedPointerAnalysis(factory, store, program.Architecture); tvr = new TypeVariableReplacer(store); trans = new TypeTransformer(factory, store, program, eventListener); ctn = new ComplexTypeNamer(); ter = new TypedExpressionRewriter(program, eventListener); // RestrictProcedures(program, 0, 60, true); // Re-enable this for debugging Time("Normalizing expressions", () => aen.Transform(program)); Time("Building equivalence classes", () => eqb.Build(program)); Time("Collecting data types", tyco.CollectTypes); Time("Build eq. class data types", () => store.BuildEquivalenceClassDataTypes(factory)); //dpa.FollowConstantPointers(program); Time("Replacing type variables", tvr.ReplaceTypeVariables); eventListener.ShowStatus("Transforming datatypes."); Time("Replace primitive types", () => { var ppr = new PtrPrimitiveReplacer(factory, store, program); ppr.ReplaceAll(eventListener); }); Time("Transforming data types", trans.Transform); Time("Renaming data types", () => ctn.RenameAllTypes(store)); Time("Rewriting program with type information", () => ter.RewriteProgram(program)); }
/// <summary> /// Performs type analysis and rewrites program based on the inferred /// information. /// </summary> /// <remarks> /// For instance, all MemoryAccesses will be converted to structure /// field accesses or array accesses as appropriate. /// </remarks> /// <param name="program"></param> public void RewriteProgram(Program program) { factory = program.TypeFactory; store = program.TypeStore; aen = new ExpressionNormalizer(program.Platform.PointerType); eqb = new EquivalenceClassBuilder(factory, store); tyco = new TypeCollector( program.TypeFactory, program.TypeStore, program, eventListener); //dpa = new DerivedPointerAnalysis(factory, store, program.Architecture); tvr = new TypeVariableReplacer(store); trans = new TypeTransformer(factory, store,program, eventListener); ctn = new ComplexTypeNamer(); ter = new TypedExpressionRewriter(program, eventListener); // RestrictProcedures(program, 0, 60, true); // Re-enable this for debugging eventListener.ShowStatus("Gathering primitive datatypes from instructions."); aen.Transform(program); eqb.Build(program); eventListener.ShowStatus("Collecting data types"); tyco.CollectTypes(); store.BuildEquivalenceClassDataTypes(factory); //dpa.FollowConstantPointers(prog); tvr.ReplaceTypeVariables(); eventListener.ShowStatus("Transforming datatypes."); var ppr = new PtrPrimitiveReplacer(factory, store, program); ppr.ReplaceAll(eventListener); trans.Transform(); ctn.RenameAllTypes(store); eventListener.ShowStatus("Rewriting expressions."); ter.RewriteProgram(program); }
/// <summary> /// Performs type analysis and rewrites program based on the inferred information. /// </summary> /// <remarks> /// For instance, all MemoryAccesses will be converted to structure field /// accesses or array accesses as appropriate. /// </remarks> /// <param name="prog"></param> public void RewriteProgram(Program prog) { factory = prog.TypeFactory; store = prog.TypeStore; aen = new ExpressionNormalizer(prog.Platform.PointerType); eqb = new EquivalenceClassBuilder(factory, store); dtb = new DataTypeBuilder(factory, store, prog.Platform); trco = new TraitCollector(factory, store, dtb, prog); //dpa = new DerivedPointerAnalysis(factory, store, prog.Architecture); tvr = new TypeVariableReplacer(store); trans = new TypeTransformer(factory, store,prog, eventListener); ctn = new ComplexTypeNamer(); ter = new TypedExpressionRewriter(prog); // RestrictProcedures(prog, 0, 1, true); //$DEBUG eventListener.ShowStatus("Gathering primitive datatypes from instructions."); aen.Transform(prog); eqb.Build(prog); eventListener.ShowStatus("Collecting datatype usage traits."); trco.CollectProgramTraits(prog); eventListener.ShowStatus("Building equivalence classes."); dtb.BuildEquivalenceClassDataTypes(); //dpa.FollowConstantPointers(prog); tvr.ReplaceTypeVariables(); eventListener.ShowStatus("Transforming datatypes."); var ppr = new PtrPrimitiveReplacer(factory, store, prog); ppr.ReplaceAll(); trans.Transform(); ctn.RenameAllTypes(store); store.Dump(); eventListener.ShowStatus("Rewriting expressions."); ter.RewriteProgram(prog); }
public void TerConstants() { var arch = new FakeArchitecture(); Program program = new Program( new SegmentMap(Address.Ptr32(0x10000)), arch, new DefaultPlatform(null, arch)); SetupPreStages(program); Constant r = Constant.Real32(3.0F); Constant i = Constant.Int32(1); Identifier x = new Identifier("x", PrimitiveType.Word32, null); Assignment ass = new Assignment(x, r); TypeVariable tvR = r.TypeVariable = program.TypeFactory.CreateTypeVariable(); TypeVariable tvI = i.TypeVariable = program.TypeFactory.CreateTypeVariable(); TypeVariable tvX = x.TypeVariable = program.TypeFactory.CreateTypeVariable(); program.TypeStore.TypeVariables.AddRange(new TypeVariable[] { tvR, tvI, tvX }); UnionType u = program.TypeFactory.CreateUnionType(null, null, new DataType[] { r.DataType, i.DataType }); tvR.OriginalDataType = r.DataType; tvI.OriginalDataType = i.DataType; tvX.OriginalDataType = x.DataType; tvR.DataType = u; tvI.DataType = u; tvX.DataType = u; ctn.RenameAllTypes(program.TypeStore); var ter = new TypedExpressionRewriter(program, null); Instruction instr = ter.TransformAssignment(ass); Assert.AreEqual("x.u0 = 3.0F", instr.ToString()); }
public void TerComplex() { Program program = new Program(); program.SegmentMap = new SegmentMap(Address.Ptr32(0x0010000)); program.Architecture = new FakeArchitecture(); program.Platform = new DefaultPlatform(null, program.Architecture); SetupPreStages(program); Identifier id = new Identifier("v0", PrimitiveType.Word32, null); Expression cmp = MemLoad(id, 4, PrimitiveType.Word32); program.Globals.Accept(eqb); cmp.Accept(aen); cmp.Accept(eqb); coll = new TraitCollector(program.TypeFactory, program.TypeStore, dtb, program); cmp.Accept(coll); dtb.BuildEquivalenceClassDataTypes(); tvr.ReplaceTypeVariables(); trans.Transform(); ctn.RenameAllTypes(program.TypeStore); ter = new TypedExpressionRewriter(program, null); cmp = cmp.Accept(ter); Assert.AreEqual("v0->dw0004", cmp.ToString()); }
protected void RunStringTest(Program program, string expectedOutput) { var sw = new StringWriter(); sw.WriteLine("// Before ///////"); DumpProgram(program, sw); var eventListener = new FakeDecompilerEventListener(); SetupPreStages(program); aen.Transform(program); eqb.Build(program); #if OLD coll = new TraitCollector(program.TypeFactory, program.TypeStore, dtb, program); coll.CollectProgramTraits(program); #else var coll = new TypeCollector(program.TypeFactory, program.TypeStore, program, eventListener); coll.CollectTypes(); #endif program.TypeStore.BuildEquivalenceClassDataTypes(program.TypeFactory); tvr.ReplaceTypeVariables(); trans.Transform(); ctn.RenameAllTypes(program.TypeStore); var ter = new TypedExpressionRewriter(program, eventListener); try { ter.RewriteProgram(program); } catch (Exception ex) { sw.WriteLine("** Exception **"); sw.WriteLine(ex); throw; } finally { sw.WriteLine("// After ///////"); DumpProgram(program, sw); } var sActual = sw.ToString(); if (expectedOutput != sActual) { Debug.Print(sActual); Assert.AreEqual(expectedOutput, sActual); } }
public void Tmer_PointerToSingleItem() { var ptr = new Identifier("ptr", PrimitiveType.Word32, null); var tv = store.EnsureExpressionTypeVariable(factory, ptr); tv.OriginalDataType = new Pointer(point, 4); var eq = new EquivalenceClass(tv); eq.DataType = point; tv.DataType = new Pointer(eq, 4); TypedExpressionRewriter tmer = new TypedExpressionRewriter(program); var access = Wrap(new MemoryAccess(ptr, PrimitiveType.Word32)); TypeVariable tvAccess = access.TypeVariable; tvAccess.DataType = PrimitiveType.Word32; Expression e = access.Accept(tmer); Assert.AreEqual("ptr->dw0000", e.ToString()); }
public Expression VisitBinaryExpression(BinaryExpression binExp) { Expression left = binExp.Left; Expression right = binExp.Right; TypeVariable tvLeft = left.TypeVariable; TypeVariable tvRight = right.TypeVariable; if (!tvLeft.DataType.IsComplex) { if (!tvRight.DataType.IsComplex) { throw new NotImplementedException(string.Format("Neither subexpression is complex in {0}: [[{1}]] and [[{2}]]", binExp, tvLeft.DataType, tvRight.DataType)); } return(VisitBinaryExpression(binExp.Commute())); } else if (tvRight.DataType.IsComplex) { throw new TypeInferenceException("Both subexpressions are complex in {0}. Left type: {1}, right type {2}", binExp, tvLeft.DataType, tvRight.DataType); } var ter = new TypedExpressionRewriter(prog); ComplexExpressionBuilder ceb; Constant cLeft = left as Constant; if (cLeft != null) { binExp.Right = binExp.Right.Accept(ter); if (basePointer == null) { basePointer = globals; } ceb = new ComplexExpressionBuilder( dtResult, basePointer.TypeVariable.DataType, basePointer.TypeVariable.OriginalDataType, null, basePointer, binExp.Right, StructureField.ToOffset(cLeft)); } else { var binLeft = binExp.Left.Accept(ter); var binRight = binExp.Right.Accept(ter); var cRight = binRight as Constant; ceb = new ComplexExpressionBuilder( binExp.DataType, tvLeft.DataType, tvLeft.OriginalDataType, basePointer, binLeft, cRight != null ? null : binRight, StructureField.ToOffset(binRight as Constant)); } ceb.Dereferenced = true; return(ceb.BuildComplex()); }