/// <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); }
/// <summary> /// Main entry point of the decompiler. Decompiles, and outputs the results. /// </summary> public void Decompile() { try { ExtractResources(); ScanPrograms(); AnalyzeDataFlow(); ReconstructTypes(); StructureProgram(); WriteDecompilerProducts(); } catch (Exception ex) { eventListener.Error( new NullCodeLocation(""), ex, "An internal error occurred while decompiling."); } finally { eventListener.ShowStatus("Decompilation finished."); } }
/// <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); // Re-enable this for debugging 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); }
/// <summary> /// Finds all interprocedural register dependencies (in- and out-parameters) and /// abstracts them away by rewriting as calls. /// </summary> /// <returns>A RegisterLiveness object that summarizes the interprocedural register /// liveness analysis. This information can be used to generate SSA form. /// </returns> public void UntangleProcedures() { eventListener.ShowStatus("Eliminating intra-block dead registers."); IntraBlockDeadRegisters.Apply(program); eventListener.ShowStatus("Finding terminating procedures."); var term = new TerminationAnalysis(flow); term.Analyze(program); eventListener.ShowStatus("Finding trashed registers."); var trf = new TrashedRegisterFinder(program, program.Procedures.Values, flow, eventListener); trf.Compute(); eventListener.ShowStatus("Rewriting affine expressions."); trf.RewriteBasicBlocks(); eventListener.ShowStatus("Computing register liveness."); var rl = RegisterLiveness.Compute(program, flow, eventListener); eventListener.ShowStatus("Rewriting calls."); GlobalCallRewriter.Rewrite(program, flow); }
/// <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, 0, false); 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, eventListener); ppr.ReplaceAll(); }); Time("Transforming data types", trans.Transform); Time("Renaming data types", () => ctn.RenameAllTypes(store)); Time("Rewriting program with type information", () => ter.RewriteProgram(program)); }
/// <summary> /// Finds all interprocedural register dependencies (in- and out-parameters) and /// abstracts them away by rewriting as calls. /// </summary> /// <returns>A RegisterLiveness object that summarizes the interprocedural register /// liveness analysis. This information can be used to generate SSA form. /// </returns> public void UntangleProcedures() { eventListener.ShowStatus("Eliminating intra-block dead registers."); var usb = new UserSignatureBuilder(program); usb.BuildSignatures(eventListener); CallRewriter.Rewrite(program, eventListener); IntraBlockDeadRegisters.Apply(program, eventListener); AdjacentBranchCollector.Transform(program, eventListener); eventListener.ShowStatus("Finding terminating procedures."); var term = new TerminationAnalysis(flow, eventListener); term.Analyze(program); eventListener.ShowStatus("Finding trashed registers."); var trf = new TrashedRegisterFinder(program, program.Procedures.Values, flow, eventListener); trf.Compute(); eventListener.ShowStatus("Rewriting affine expressions."); trf.RewriteBasicBlocks(); eventListener.ShowStatus("Computing register liveness."); RegisterLiveness.Compute(program, flow, eventListener); eventListener.ShowStatus("Rewriting calls."); GlobalCallRewriter.Rewrite(program, flow, eventListener); }
/// <summary> /// Main entry point of the decompiler. Loads, decompiles, and outputs the results. /// </summary> public void Decompile(string filename, string loader = null) { try { Load(filename, loader); ScanPrograms(); AnalyzeDataFlow(); ReconstructTypes(); StructureProgram(); WriteDecompilerProducts(); } catch (Exception ex) { eventListener.Error( new NullCodeLocation(filename), ex, "An internal error occurred while decompiling."); } finally { eventListener.ShowStatus("Decompilation finished."); } }