00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef BOOMERANG_H
00033 #define BOOMERANG_H
00034
00035
00036 #define USE_DOMINANCE_NUMS 1 // Set true to store a statement number that has dominance properties
00037
00038 #include <iostream>
00039 #include <string>
00040 #include <set>
00041 #include <vector>
00042 #include <map>
00043
00044 #include "types.h"
00045
00046 class Log;
00047 class Prog;
00048 class Proc;
00049 class UserProc;
00050 class HLLCode;
00051 class ObjcModule;
00052
00053 #define LOG Boomerang::get()->log()
00054 #define LOGTAIL Boomerang::get()->logTail()
00055
00056 #define DEBUG_RANGE_ANALYSIS 0
00057
00058
00059 class Watcher {
00060 public:
00061 Watcher() { }
00062 virtual ~Watcher() { };
00063
00064 virtual void alert_complete() { }
00065 virtual void alert_new(Proc *p) { }
00066 virtual void alert_remove(Proc *p) { }
00067 virtual void alert_update_signature(Proc *p) { }
00068 virtual void alert_decode(ADDRESS pc, int nBytes) { }
00069 virtual void alert_baddecode(ADDRESS pc) { }
00070 virtual void alert_start_decode(ADDRESS start, int nBytes) { }
00071 virtual void alert_end_decode() { }
00072 virtual void alert_decode(Proc *p, ADDRESS pc, ADDRESS last, int nBytes) { }
00073 virtual void alert_start_decompile(UserProc *p) { }
00074 virtual void alert_proc_status_change(UserProc *p) { }
00075 virtual void alert_decompile_SSADepth(UserProc *p, int depth) { }
00076 virtual void alert_decompile_beforePropagate(UserProc *p, int depth) { }
00077 virtual void alert_decompile_afterPropagate(UserProc *p, int depth) { }
00078 virtual void alert_decompile_afterRemoveStmts(UserProc *p, int depth) { }
00079 virtual void alert_end_decompile(UserProc *p) { }
00080 virtual void alert_load(Proc *p) { }
00081 virtual void alert_considering(Proc *parent, Proc *p) { }
00082 virtual void alert_decompiling(UserProc *p) { }
00083 virtual void alert_decompile_debug_point(UserProc *p, const char *description) { }
00084 };
00085
00086
00087
00088
00089
00090 class Boomerang {
00091 private:
00092 static Boomerang *boomerang;
00093
00094 std::string progPath;
00095
00096 std::string outputPath;
00097
00098 Log *logger;
00099
00100 std::set<Watcher*> watchers;
00101
00102
00103
00104
00105
00106
00107 void usage();
00108 void help();
00109 void helpcmd();
00110 int splitLine(char *line, char ***pargv);
00111 int parseCmd(int argc, const char **argv);
00112 int cmdLine();
00113
00114
00115 Boomerang();
00116
00117 virtual ~Boomerang() {}
00118 public:
00119
00120
00121
00122 static Boomerang *get() {
00123 if (!boomerang) boomerang = new Boomerang();
00124 return boomerang;
00125 }
00126
00127 static char* getVersionStr();
00128 Log &log();
00129 void setLogger(Log *l) { logger = l; }
00130 bool setOutputDirectory(const char *path);
00131
00132
00133 HLLCode *getHLLCode(UserProc *p = NULL);
00134
00135 int commandLine(int argc, const char **argv);
00136
00137 void setProgPath(const char* p) { progPath = p; }
00138
00139 const std::string& getProgPath() { return progPath; }
00140
00141 void setOutputPath(const char* p) { outputPath = p; }
00142
00143 const std::string& getOutputPath() { return outputPath; }
00144
00145 Prog *loadAndDecode(const char *fname, const char *pname = NULL);
00146 int decompile(const char *fname, const char *pname = NULL);
00147
00148 void addWatcher(Watcher *watcher) { watchers.insert(watcher); }
00149 void persistToXML(Prog *prog);
00150 Prog *loadFromXML(const char *fname);
00151
00152 void objcDecode(std::map<std::string, ObjcModule> &modules, Prog *prog);
00153
00154
00155 void alert_complete() {
00156 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00157 (*it)->alert_complete();
00158 }
00159
00160 void alert_new(Proc *p) {
00161 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00162 (*it)->alert_new(p);
00163 }
00164
00165 void alert_remove(Proc *p) {
00166 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00167 (*it)->alert_remove(p);
00168 }
00169
00170 void alert_update_signature(Proc *p) {
00171 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00172 (*it)->alert_update_signature(p);
00173 }
00174
00175 void alert_decode(ADDRESS pc, int nBytes) {
00176 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00177 (*it)->alert_decode(pc, nBytes);
00178 }
00179
00180 void alert_baddecode(ADDRESS pc) {
00181 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00182 (*it)->alert_baddecode(pc);
00183 }
00184
00185 void alert_decode(Proc *p, ADDRESS pc, ADDRESS last, int nBytes) {
00186 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00187 (*it)->alert_decode(p, pc, last, nBytes);
00188 }
00189
00190 void alert_load(Proc *p) {
00191 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00192 (*it)->alert_load(p);
00193 }
00194
00195 void alert_start_decode(ADDRESS start, int nBytes) {
00196 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00197 (*it)->alert_start_decode(start, nBytes);
00198 }
00199
00200 void alert_end_decode() {
00201 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00202 (*it)->alert_end_decode();
00203 }
00204 virtual void alert_start_decompile(UserProc *p) {
00205 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00206 (*it)->alert_start_decompile(p);
00207 }
00208 virtual void alert_proc_status_change(UserProc *p) {
00209 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00210 (*it)->alert_proc_status_change(p);
00211 }
00212 virtual void alert_decompile_SSADepth(UserProc *p, int depth) {
00213 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00214 (*it)->alert_decompile_SSADepth(p, depth);
00215 }
00216 virtual void alert_decompile_beforePropagate(UserProc *p, int depth) {
00217 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00218 (*it)->alert_decompile_beforePropagate(p, depth);
00219 }
00220 virtual void alert_decompile_afterPropagate(UserProc *p, int depth) {
00221 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00222 (*it)->alert_decompile_afterPropagate(p, depth);
00223 }
00224 virtual void alert_decompile_afterRemoveStmts(UserProc *p, int depth) {
00225 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00226 (*it)->alert_decompile_afterRemoveStmts(p, depth);
00227 }
00228 virtual void alert_end_decompile(UserProc *p) {
00229 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00230 (*it)->alert_end_decompile(p);
00231 }
00232 virtual void alert_considering(Proc *parent, Proc *p) {
00233 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00234 (*it)->alert_considering(parent, p);
00235 }
00236 virtual void alert_decompiling(UserProc *p) {
00237 for (std::set<Watcher*>::iterator it = watchers.begin(); it != watchers.end(); it++)
00238 (*it)->alert_decompiling(p);
00239 }
00240 virtual void alert_decompile_debug_point(UserProc *p, const char *description);
00241
00242 void logTail();
00243
00244
00245 bool vFlag;
00246 bool printRtl;
00247 bool noBranchSimplify;
00248 bool noRemoveNull;
00249 bool noLocals;
00250 bool noRemoveLabels;
00251 bool noDataflow;
00252 bool noDecompile;
00253 bool stopBeforeDecompile;
00254 bool traceDecoder;
00255
00256 const char *dotFile;
00257 int numToPropagate;
00258 bool noPromote;
00259 bool propOnlyToAll;
00260 bool debugGen;
00261 int maxMemDepth;
00262 bool debugSwitch;
00263 bool noParameterNames;
00264 bool debugLiveness;
00265 bool stopAtDebugPoints;
00266 bool debugTA;
00267
00268 std::vector<ADDRESS> entrypoints;
00269
00270 std::vector<std::string> symbolFiles;
00271
00272 std::map<ADDRESS, std::string> symbols;
00273
00274
00275 bool decodeMain;
00276 bool printAST;
00277 bool dumpXML;
00278 bool noRemoveReturns;
00279 bool debugDecoder;
00280 bool decodeThruIndCall;
00281 std::ofstream* ofsIndCallReport;
00282 bool noDecodeChildren;
00283 bool debugProof;
00284 bool debugUnused;
00285 bool loadBeforeDecompile;
00286 bool saveBeforeDecompile;
00287 bool noProve;
00288 bool noChangeSignatures;
00289 bool conTypeAnalysis;
00290 bool dfaTypeAnalysis;
00291 int propMaxDepth;
00292 bool generateCallGraph;
00293 bool generateSymbols;
00294 bool noGlobals;
00295 bool assumeABI;
00296 bool experimental;
00297 int minsToStopAfter;
00298 };
00299
00300 #define VERBOSE (Boomerang::get()->vFlag)
00301 #define DEBUG_TA (Boomerang::get()->debugTA)
00302 #define DEBUG_PROOF (Boomerang::get()->debugProof)
00303 #define DEBUG_UNUSED (Boomerang::get()->debugUnused)
00304 #define DEBUG_LIVENESS (Boomerang::get()->debugLiveness)
00305 #define DFA_TYPE_ANALYSIS (Boomerang::get()->dfaTypeAnalysis)
00306 #define CON_TYPE_ANALYSIS (Boomerang::get()->conTypeAnalysis)
00307 #define ADHOC_TYPE_ANALYSIS (!Boomerang::get()->dfaTypeAnalysis && !Boomerang::get()->conTypeAnalysis)
00308 #define DEBUG_GEN (Boomerang::get()->debugGen)
00309 #define DUMP_XML (Boomerang::get()->dumpXML)
00310 #define DEBUG_SWITCH (Boomerang::get()->debugSwitch)
00311 #define EXPERIMENTAL (Boomerang::get()->experimental)
00312
00313
00314
00315 #endif