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.
This commit is contained in:
nemerle 2016-04-26 00:46:56 +02:00
parent 5f39236ba2
commit d1738ea630
3 changed files with 32 additions and 6 deletions

View File

@ -39,6 +39,7 @@ typedef struct { /* Command line option flags */
unsigned Interact : 1; /* Interactive mode */ unsigned Interact : 1; /* Interactive mode */
unsigned Calls : 1; /* Follow register indirect calls */ unsigned Calls : 1; /* Follow register indirect calls */
QString filename; /* The input filename */ QString filename; /* The input filename */
uint32_t CustomEntryPoint;
} OPTION; } OPTION;
extern OPTION option; /* Command line options */ extern OPTION option; /* Command line options */

View File

@ -137,14 +137,17 @@ void setupOptions(QCoreApplication &app) {
parser.addOption(o); parser.addOption(o);
} }
QCommandLineOption assembly("a", QCoreApplication::translate("main", "Produce assembly"),"assembly_level"); 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", QCommandLineOption targetFileOption(QStringList() << "o" << "output",
QCoreApplication::translate("main", "Place output into <file>."), QCoreApplication::translate("main", "Place output into <file>."),
QCoreApplication::translate("main", "file")); 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(targetFileOption);
parser.addOption(assembly); parser.addOption(assembly);
parser.addOption(entryPointOption);
//parser.addOption(forceOption); //parser.addOption(forceOption);
// Process the actual command line arguments given by the user // Process the actual command line arguments given by the user
parser.addPositionalArgument("source", QCoreApplication::translate("main", "Dos Executable file to decompile.")); parser.addPositionalArgument("source", QCoreApplication::translate("main", "Dos Executable file to decompile."));
@ -166,6 +169,7 @@ void setupOptions(QCoreApplication &app) {
option.Interact = false; option.Interact = false;
option.Calls = parser.isSet(boolOpts[2]); option.Calls = parser.isSet(boolOpts[2]);
option.filename = args.first(); option.filename = args.first();
option.CustomEntryPoint = parser.value(entryPointOption).toUInt(0,16);
if(parser.isSet(targetFileOption)) if(parser.isSet(targetFileOption))
asm1_name = asm2_name = parser.value(targetFileOption); asm1_name = asm2_name = parser.value(targetFileOption);
else if(option.asm1 or option.asm2) { else if(option.asm1 or option.asm2) {

View File

@ -12,6 +12,7 @@
#include <list> #include <list>
#include <cassert> #include <cassert>
#include <stdio.h> #include <stdio.h>
#include <CallGraph.h>
extern Project g_proj; extern Project g_proj;
//static void displayCFG(Function * pProc); //static void displayCFG(Function * pProc);
//static void displayDfs(BB * pBB); //static void displayDfs(BB * pBB);
@ -75,9 +76,16 @@ void udm(void)
/* Build the control flow graph, find idioms, and convert low-level /* Build the control flow graph, find idioms, and convert low-level
* icodes to high-level ones */ * icodes to high-level ones */
Project *proj = Project::get();
Disassembler ds(2); 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); iter->buildCFG(ds);
} }
if (option.asm2) if (option.asm2)
@ -88,10 +96,23 @@ void udm(void)
* and intermediate instructions. Find expressions by forward * and intermediate instructions. Find expressions by forward
* substitution algorithm */ * substitution algorithm */
LivenessSet live_regs; 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 */ /* 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(); iter->controlFlowAnalysis();
} }