DecompilerThread.cpp

Go to the documentation of this file.
00001 
00002 #include <QtGui>
00003 
00004 #include "DecompilerThread.h"
00005 
00006 #include "gc.h"
00007 
00008 #include "boomerang.h"
00009 #include "log.h"
00010 #include "prog.h"
00011 #include "frontend.h"
00012 #include "proc.h"
00013 #include "signature.h"
00014 #include "cluster.h"
00015 #include <sstream>
00016 
00017 #undef NO_ADDRESS
00018 #define NO_ADDRESS ((ADDRESS)-1)
00019 
00020 Qt::HANDLE threadToCollect = 0;
00021 
00022 void* operator new(size_t n) {
00023     Qt::HANDLE curThreadId = QThread::currentThreadId();
00024     if (curThreadId == threadToCollect)
00025         return GC_malloc(n);
00026     else
00027         return GC_malloc_uncollectable(n);  // Don't collect, but mark
00028 }
00029 
00030 void operator delete(void* p) {
00031     Qt::HANDLE curThreadId = QThread::currentThreadId();
00032     if (curThreadId != threadToCollect)
00033         GC_free(p); // Important to call this if you call GC_malloc_uncollectable
00034 }
00035 
00036 void DecompilerThread::run()
00037 {
00038     threadToCollect = QThread::currentThreadId();
00039 
00040     Boomerang::get()->setOutputDirectory(".\\output\\");
00041     //Boomerang::get()->vFlag = true;
00042     //Boomerang::get()->traceDecoder = true;
00043 
00044     decompiler = new Decompiler();
00045     decompiler->moveToThread(this);
00046 
00047     Boomerang::get()->addWatcher(decompiler);
00048 
00049     this->setPriority(QThread::LowPriority);
00050 
00051     exec();
00052 }
00053 
00054 Decompiler *DecompilerThread::getDecompiler()
00055 {
00056     while (decompiler == NULL)
00057         msleep(10);
00058     return decompiler;
00059 }
00060 
00061 void Decompiler::setUseDFTA(bool d) {
00062     Boomerang::get()->dfaTypeAnalysis = d;
00063 }
00064 
00065 void Decompiler::setNoDecodeChildren(bool d) {
00066     Boomerang::get()->noDecodeChildren = d;
00067 }
00068 
00069 void Decompiler::addEntryPoint(ADDRESS a, const char *nam) {
00070     user_entrypoints.push_back(a);
00071     fe->AddSymbol(a, nam);
00072 }
00073 
00074 void Decompiler::removeEntryPoint(ADDRESS a) {
00075     for (std::vector<ADDRESS>::iterator it = user_entrypoints.begin(); it != user_entrypoints.end(); it++)
00076         if (*it == a) {
00077             user_entrypoints.erase(it);
00078             break;
00079         }
00080 }
00081 
00082 void Decompiler::changeInputFile(const QString &f) 
00083 {
00084     filename = f;
00085 }
00086 
00087 void Decompiler::changeOutputPath(const QString &path)
00088 {
00089     Boomerang::get()->setOutputDirectory((const char *)path.toAscii());
00090 }
00091 
00092 void Decompiler::load()
00093 {
00094     emit loading();
00095 
00096     prog = new Prog();
00097     fe = FrontEnd::Load(strdup(filename.toAscii()), prog);
00098     if (fe == NULL) {
00099         emit machineType(QString("unavailable: Load Failed!"));
00100         return;
00101     }
00102     prog->setFrontEnd(fe);
00103     fe->readLibraryCatalog();
00104 
00105     switch(prog->getMachine()) {
00106         case MACHINE_PENTIUM:
00107             emit machineType(QString("pentium"));
00108             break;
00109         case MACHINE_SPARC:
00110             emit machineType(QString("sparc"));
00111             break;
00112         case MACHINE_HPRISC:
00113             emit machineType(QString("hprisc"));
00114             break;
00115         case MACHINE_PALM:
00116             emit machineType(QString("palm"));
00117             break;
00118         case MACHINE_PPC:
00119             emit machineType(QString("ppc"));
00120             break;
00121         case MACHINE_ST20:
00122             emit machineType(QString("st20"));
00123             break;
00124     }
00125 
00126     QStringList entrypointStrings;
00127     std::vector<ADDRESS> entrypoints = fe->getEntryPoints();
00128     for (unsigned int i = 0; i < entrypoints.size(); i++) {
00129         user_entrypoints.push_back(entrypoints[i]);
00130         emit newEntrypoint(entrypoints[i], fe->getBinaryFile()->SymbolByAddress(entrypoints[i]));
00131     }
00132 
00133     for (int i = 1; i < fe->getBinaryFile()->GetNumSections(); i++) {
00134         PSectionInfo section = fe->getBinaryFile()->GetSectionInfo(i);
00135         emit newSection(section->pSectionName, section->uNativeAddr, section->uNativeAddr + section->uSectionSize);
00136     }
00137 
00138     emit loadCompleted();
00139 }
00140 
00141 void Decompiler::decode()
00142 {
00143     emit decoding();
00144 
00145     bool gotMain;
00146     ADDRESS a = fe->getMainEntryPoint(gotMain);
00147     for (unsigned int i = 0; i < user_entrypoints.size(); i++) 
00148         if (user_entrypoints[i] == a) {
00149             fe->decode(prog, true, NULL);
00150             break;
00151         }
00152 
00153     for (unsigned int i = 0; i < user_entrypoints.size(); i++) {
00154         prog->decodeEntryPoint(user_entrypoints[i]);
00155     }
00156 
00157     if (!Boomerang::get()->noDecodeChildren) {
00158         // decode anything undecoded
00159         fe->decode(prog, NO_ADDRESS);
00160     }
00161 
00162     prog->finishDecode();
00163 
00164     emit decodeCompleted();
00165 }
00166 
00167 void Decompiler::decompile()
00168 {
00169     emit decompiling();
00170 
00171     prog->decompile();
00172 
00173     emit decompileCompleted();
00174 }
00175 
00176 void Decompiler::emitClusterAndChildren(Cluster *root)
00177 {
00178     emit newCluster(QString(root->getName()));
00179     for (unsigned int i = 0; i < root->getNumChildren(); i++)
00180         emitClusterAndChildren(root->getChild(i));
00181 }
00182 
00183 void Decompiler::generateCode()
00184 {
00185     emit generatingCode();
00186 
00187     prog->generateCode();
00188 
00189     Cluster *root = prog->getRootCluster();
00190     if (root)
00191         emitClusterAndChildren(root);
00192     std::list<Proc*>::iterator it;
00193     for (UserProc *p = prog->getFirstUserProc(it); p; p = prog->getNextUserProc(it)) {
00194         emit newProcInCluster(QString(p->getName()), QString(p->getCluster()->getName()));
00195     }
00196 
00197     emit generateCodeCompleted();
00198 }
00199 
00200 const char *Decompiler::procStatus(UserProc *p)
00201 {
00202     switch(p->getStatus()) {
00203     case PROC_UNDECODED:
00204         return "undecoded";
00205     case PROC_DECODED:
00206         return "decoded";
00207     case PROC_SORTED:
00208         return "sorted";
00209     case PROC_VISITED:
00210         return "visited";
00211     case PROC_INCYCLE:
00212         return "in cycle";
00213     case PROC_PRESERVEDS:
00214         return "preserveds";
00215     case PROC_EARLYDONE:
00216         return "early done";
00217     case PROC_FINAL:
00218         return "final";
00219     case PROC_CODE_GENERATED:
00220         return "code generated";
00221     }
00222     return "unknown";
00223 }
00224 
00225 void Decompiler::alert_considering(Proc *parent, Proc *p)
00226 {
00227     emit consideringProc(QString(parent ? parent->getName() : ""), QString(p->getName()));
00228 }
00229 
00230 void Decompiler::alert_decompiling(UserProc *p)
00231 {
00232     emit decompilingProc(QString(p->getName()));
00233 }
00234 
00235 void Decompiler::alert_new(Proc *p)
00236 {
00237     if (p->isLib()) {
00238         QString params;
00239         if (p->getSignature() == NULL || p->getSignature()->isUnknown())
00240             params = "<unknown>";
00241         else {
00242             for (unsigned int i = 0; i < p->getSignature()->getNumParams(); i++) {
00243                 Type *ty = p->getSignature()->getParamType(i);
00244                 params.append(ty->getCtype());
00245                 params.append(" ");
00246                 params.append(p->getSignature()->getParamName(i));
00247                 if (i != p->getSignature()->getNumParams()-1)
00248                     params.append(", ");
00249             }
00250         }
00251         emit newLibProc(QString(p->getName()), params);
00252     } else {
00253         emit newUserProc(QString(p->getName()), p->getNativeAddress());
00254     }
00255 }
00256 
00257 void Decompiler::alert_remove(Proc *p)
00258 {
00259     if (p->isLib()) {
00260         emit removeLibProc(QString(p->getName()));
00261     } else {
00262         emit removeUserProc(QString(p->getName()), p->getNativeAddress());
00263     }
00264 }
00265 
00266 void Decompiler::alert_update_signature(Proc *p)
00267 {
00268     alert_new(p);
00269 }
00270 
00271 
00272 bool Decompiler::getRtlForProc(const QString &name, QString &rtl)
00273 {
00274     Proc *p = prog->findProc((const char *)name.toAscii());
00275     if (p->isLib())
00276         return false;
00277     UserProc *up = (UserProc*)p;
00278     std::ostringstream os;
00279     up->print(os, true);
00280     rtl = os.str().c_str();
00281     return true;
00282 }
00283 
00284 void Decompiler::alert_decompile_debug_point(UserProc *p, const char *description)
00285 {
00286     LOG << p->getName() << ": " << description << "\n";
00287     if (debugging) {
00288         waiting = true;
00289         emit debuggingPoint(QString(p->getName()), QString(description));
00290         while (waiting) {
00291             thread()->wait(10);
00292         }       
00293     }
00294 }
00295 
00296 void Decompiler::stopWaiting()
00297 {
00298     waiting = false;
00299 }
00300 
00301 const char *Decompiler::getSigFile(const QString &name)
00302 {
00303     Proc *p = prog->findProc((const char *)name.toAscii());
00304     if (p == NULL || !p->isLib() || p->getSignature() == NULL)
00305         return NULL;
00306     return p->getSignature()->getSigFile();
00307 }
00308 
00309 const char *Decompiler::getClusterFile(const QString &name)
00310 {
00311     Cluster *c = prog->findCluster((const char *)name.toAscii());
00312     if (c == NULL)
00313         return NULL;
00314     return c->getOutPath("c");
00315 }
00316 
00317 void Decompiler::rereadLibSignatures()
00318 {
00319     prog->rereadLibSignatures();
00320 }
00321 
00322 void Decompiler::renameProc(const QString &oldName, const QString &newName)
00323 {
00324     Proc *p = prog->findProc((const char *)oldName.toAscii());
00325     if (p)
00326         p->setName((const char *)newName.toAscii());
00327 }
00328 
00329 void Decompiler::getCompoundMembers(const QString &name, QTableWidget *tbl)
00330 {
00331     Type *ty = NamedType::getNamedType((const char *)name.toAscii());
00332     tbl->setRowCount(0);
00333     if (ty == NULL || !ty->resolvesToCompound())
00334         return;
00335     CompoundType *c = ty->asCompound();
00336     for (unsigned int i = 0; i < c->getNumTypes(); i++) {
00337         tbl->setRowCount(tbl->rowCount() + 1);
00338         tbl->setItem(tbl->rowCount() - 1, 0, new QTableWidgetItem(tr("%1").arg(c->getOffsetTo(i))));
00339         tbl->setItem(tbl->rowCount() - 1, 1, new QTableWidgetItem(tr("%1").arg(c->getOffsetTo(i) / 8)));
00340         tbl->setItem(tbl->rowCount() - 1, 2, new QTableWidgetItem(QString(c->getName(i))));
00341         tbl->setItem(tbl->rowCount() - 1, 3, new QTableWidgetItem(tr("%1").arg(c->getType(i)->getSize())));
00342     }
00343 }

Generated on Tue Sep 19 21:18:18 2006 for Boomerang by  doxygen 1.4.6