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);
00028 }
00029
00030 void operator delete(void* p) {
00031 Qt::HANDLE curThreadId = QThread::currentThreadId();
00032 if (curThreadId != threadToCollect)
00033 GC_free(p);
00034 }
00035
00036 void DecompilerThread::run()
00037 {
00038 threadToCollect = QThread::currentThreadId();
00039
00040 Boomerang::get()->setOutputDirectory(".\\output\\");
00041
00042
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
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 }