From d1738ea630d78837497cc7f8b64acc366ded150b Mon Sep 17 00:00:00 2001 From: nemerle Date: Tue, 26 Apr 2016 00:46:56 +0200 Subject: [PATCH] New feature: option to decompile only a specific function. Similar to boomerang's -E option: ``` dcc -E 0x1222 ./TARGET.EXE ``` Will only decompile function at given address. This might help in isolating dcc crashes. --- include/dcc.h | 1 + src/dcc.cpp | 10 +++++++--- src/udm.cpp | 27 ++++++++++++++++++++++++--- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/include/dcc.h b/include/dcc.h index 18e2481..6729e42 100644 --- a/include/dcc.h +++ b/include/dcc.h @@ -39,6 +39,7 @@ typedef struct { /* Command line option flags */ unsigned Interact : 1; /* Interactive mode */ unsigned Calls : 1; /* Follow register indirect calls */ QString filename; /* The input filename */ + uint32_t CustomEntryPoint; } OPTION; extern OPTION option; /* Command line options */ diff --git a/src/dcc.cpp b/src/dcc.cpp index 5be65ff..3c2aefb 100644 --- a/src/dcc.cpp +++ b/src/dcc.cpp @@ -137,14 +137,17 @@ void setupOptions(QCoreApplication &app) { parser.addOption(o); } QCommandLineOption assembly("a", QCoreApplication::translate("main", "Produce assembly"),"assembly_level"); - // A boolean option with multiple names (-f, --force) - //QCommandLineOption forceOption(QStringList() << "f" << "force", "Overwrite existing files."); - // An option with a value QCommandLineOption targetFileOption(QStringList() << "o" << "output", QCoreApplication::translate("main", "Place output into ."), QCoreApplication::translate("main", "file")); + QCommandLineOption entryPointOption(QStringList() << "E", + QCoreApplication::translate("main", "Custom entry point as hex"), + QCoreApplication::translate("main", "offset"), + "0" + ); parser.addOption(targetFileOption); parser.addOption(assembly); + parser.addOption(entryPointOption); //parser.addOption(forceOption); // Process the actual command line arguments given by the user parser.addPositionalArgument("source", QCoreApplication::translate("main", "Dos Executable file to decompile.")); @@ -166,6 +169,7 @@ void setupOptions(QCoreApplication &app) { option.Interact = false; option.Calls = parser.isSet(boolOpts[2]); option.filename = args.first(); + option.CustomEntryPoint = parser.value(entryPointOption).toUInt(0,16); if(parser.isSet(targetFileOption)) asm1_name = asm2_name = parser.value(targetFileOption); else if(option.asm1 or option.asm2) { diff --git a/src/udm.cpp b/src/udm.cpp index 12c8fec..dc569e0 100644 --- a/src/udm.cpp +++ b/src/udm.cpp @@ -12,6 +12,7 @@ #include #include #include +#include extern Project g_proj; //static void displayCFG(Function * pProc); //static void displayDfs(BB * pBB); @@ -75,9 +76,16 @@ void udm(void) /* Build the control flow graph, find idioms, and convert low-level * icodes to high-level ones */ + Project *proj = Project::get(); Disassembler ds(2); - for (auto iter = Project::get()->pProcList.rbegin(); iter!=Project::get()->pProcList.rend(); ++iter) + for (auto iter = proj->pProcList.rbegin(); iter!=proj->pProcList.rend(); ++iter) { + Function &f(*iter); + if(option.CustomEntryPoint) { + if(f.procEntry!=option.CustomEntryPoint) { + continue; + } + } iter->buildCFG(ds); } if (option.asm2) @@ -88,10 +96,23 @@ void udm(void) * and intermediate instructions. Find expressions by forward * substitution algorithm */ LivenessSet live_regs; - Project::get()->pProcList.front().dataFlow (live_regs); + if(option.CustomEntryPoint) { + ilFunction iter = proj->findByEntry(option.CustomEntryPoint); + if(iter==proj->pProcList.end()) { + qCritical()<< "No function found at entry point" << QString::number(option.CustomEntryPoint,16); + return; + } + iter->dataFlow(live_regs); + iter->controlFlowAnalysis(); + delete proj->callGraph; + proj->callGraph = new CALL_GRAPH; + proj->callGraph->proc = iter; + return; + } + proj->pProcList.front().dataFlow (live_regs); /* Control flow analysis - structuring algorithm */ - for (auto iter = Project::get()->pProcList.rbegin(); iter!=Project::get()->pProcList.rend(); ++iter) + for (auto iter = proj->pProcList.rbegin(); iter!=proj->pProcList.rend(); ++iter) { iter->controlFlowAnalysis(); }