mainwindow.cpp

Go to the documentation of this file.
00001 
00002 
00003 #include <QtGui>
00004 
00005 #include "mainwindow.h"
00006 #include "DecompilerThread.h"
00007 #include "rtleditor.h"
00008 
00009 MainWindow::MainWindow(QWidget *parent) : 
00010     QMainWindow(parent), 
00011     decompilerThread(NULL),
00012     step(NULL)
00013 {
00014     ui.setupUi(this);
00015 
00016     decompilerThread = new DecompilerThread();
00017     decompilerThread->start();
00018     Decompiler *d = decompilerThread->getDecompiler();
00019     connect(d, SIGNAL(newCluster(const QString &)), this, SLOT(showNewCluster(const QString &)));
00020     connect(d, SIGNAL(newProcInCluster(const QString &, const QString &)), this, SLOT(showNewProcInCluster(
00021         const QString &, const QString &)));
00022     connect(d, SIGNAL(debuggingPoint(const QString &, const QString &)), this, SLOT(showDebuggingPoint(
00023         const QString &, const QString &)));
00024     connect(d, SIGNAL(loading()), this, SLOT(showLoadPage()));
00025     connect(d, SIGNAL(decoding()), this, SLOT(showDecodePage()));
00026     connect(d, SIGNAL(decompiling()), this, SLOT(showDecompilePage()));
00027     connect(d, SIGNAL(generatingCode()), this, SLOT(showGenerateCodePage()));
00028     connect(d, SIGNAL(loadCompleted()), this, SLOT(loadComplete()));
00029     connect(d, SIGNAL(machineType(const QString &)), this, SLOT(showMachineType(const QString &)));
00030     connect(d, SIGNAL(newEntrypoint(unsigned int, const QString &)), this, SLOT(showNewEntrypoint(
00031         unsigned int, const QString &)));
00032     connect(d, SIGNAL(decodeCompleted()), this, SLOT(decodeComplete()));
00033     connect(d, SIGNAL(decompileCompleted()), this, SLOT(decompileComplete()));
00034     connect(d, SIGNAL(generateCodeCompleted()), this, SLOT(generateCodeComplete()));
00035     connect(d, SIGNAL(changeProcedureState(const QString &, const QString &)), this, SLOT(changeProcedureState(
00036         const QString &, const QString &)));
00037     connect(d, SIGNAL(consideringProc(const QString &, const QString &)), this, SLOT(showConsideringProc(
00038         const QString &, const QString &)));
00039     connect(d, SIGNAL(decompilingProc(const QString &)), this, SLOT(showDecompilingProc(const QString &)));
00040     connect(d, SIGNAL(newUserProc(const QString &, unsigned int)), this, SLOT(showNewUserProc(
00041         const QString &, unsigned int)));
00042     connect(d, SIGNAL(newLibProc(const QString &, const QString &)), this, SLOT(showNewLibProc(
00043         const QString &, const QString &)));
00044     connect(d, SIGNAL(removeUserProc(const QString &, unsigned int)), this, SLOT(showRemoveUserProc(
00045         const QString &, unsigned int)));
00046     connect(d, SIGNAL(removeLibProc(const QString &)), this, SLOT(showRemoveLibProc(const QString &)));
00047     connect(d, SIGNAL(newSection(const QString &, unsigned int, unsigned int)), this, SLOT(showNewSection(
00048         const QString &, unsigned int, unsigned int)));
00049     connect(ui.toLoadButton, SIGNAL(clicked()), d, SLOT(load()));
00050     connect(ui.toDecodeButton, SIGNAL(clicked()), d, SLOT(decode()));
00051     connect(ui.toDecompileButton, SIGNAL(clicked()), d, SLOT(decompile()));
00052     connect(ui.toGenerateCodeButton, SIGNAL(clicked()), d, SLOT(generateCode()));
00053     //connect(ui.inputFileComboBox, SIGNAL(editTextChanged(const QString &)), d,  SLOT(
00054     //  changeInputFile(const QString &)));
00055     //connect(ui.outputPathComboBox, SIGNAL(editTextChanged(const QString &)), d,  SLOT(
00056     //  changeOutputPath(const QString &)));
00057     //connect(ui.inputFileBrowseButton, SIGNAL(clicked()), this, SLOT(browseForInputFile()));
00058     //connect(ui.outputPathBrowseButton, SIGNAL(clicked()), this, SLOT(browseForOutputPath()));
00059 
00060     ui.userProcs->horizontalHeader()->disconnect(SIGNAL(sectionClicked(int)));
00061     connect(ui.userProcs->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(
00062         on_userProcs_horizontalHeader_sectionClicked(int)));
00063 
00064     ui.userProcs->verticalHeader()->hide();
00065     ui.libProcs->verticalHeader()->hide();
00066     ui.sections->verticalHeader()->hide();
00067     ui.entrypoints->verticalHeader()->hide();
00068     ui.structMembers->verticalHeader()->hide();
00069 
00070     QPushButton *closeButton = new QPushButton(QIcon("closetab.bmp"), "", ui.tabWidget);
00071     closeButton->setFixedSize(closeButton->iconSize());
00072     ui.tabWidget->setCornerWidget(closeButton);
00073     ui.tabWidget->cornerWidget()->show();
00074     connect(closeButton, SIGNAL(clicked()), this, SLOT(closeCurrentTab()));
00075 
00076     structs = ui.tabWidget->widget(1);
00077     ui.tabWidget->removeTab(1);
00078 
00079     showInitPage();
00080     setWindowTitle("Boomerang");
00081 
00082     loadingSettings = true;
00083     QSettings settings("Boomerang", "Boomerang");
00084     QStringList inputfiles = settings.value("inputfiles").toStringList();
00085     for (int n = 0; n < inputfiles.count(); n++) {
00086         if (ui.inputFileComboBox->findText(inputfiles.at(n)) == -1)
00087             ui.inputFileComboBox->addItem(inputfiles.at(n));
00088     }
00089     QString inputfile = settings.value("inputfile").toString();
00090     int i = ui.inputFileComboBox->findText(inputfile);
00091     if (i != -1)
00092         ui.inputFileComboBox->setCurrentIndex(i);
00093     QStringList outputpaths = settings.value("outputpaths").toStringList();
00094     for (int n = 0; n < outputpaths.count(); n++) {
00095         if (ui.outputPathComboBox->findText(outputpaths.at(n)) == -1)
00096             ui.outputPathComboBox->addItem(outputpaths.at(n));
00097     }
00098     i = ui.outputPathComboBox->findText(settings.value("outputpath").toString());
00099     ui.outputPathComboBox->setCurrentIndex(i);
00100     if (!ui.inputFileComboBox->currentText().isEmpty()) {
00101         d->changeInputFile(ui.inputFileComboBox->currentText());
00102         ui.toLoadButton->setDisabled(false);
00103     }
00104     loadingSettings = false;
00105 }
00106 
00107 void MainWindow::saveSettings()
00108 {
00109     if (loadingSettings)
00110         return;
00111     QSettings settings("Boomerang", "Boomerang");           
00112     QStringList inputfiles;
00113     for (int n = 0; n < ui.inputFileComboBox->count(); n++) {
00114         inputfiles.append(ui.inputFileComboBox->itemText(n));
00115     }
00116     settings.setValue("inputfiles", inputfiles);
00117     settings.setValue("inputfile", ui.inputFileComboBox->itemText(ui.inputFileComboBox->currentIndex()));
00118     QStringList outputPaths;
00119     for (int n = 0; n < ui.outputPathComboBox->count(); n++) {
00120         outputPaths.append(ui.outputPathComboBox->itemText(n));
00121     }
00122     settings.setValue("outputpaths", outputPaths);
00123     settings.setValue("outputpath", ui.outputPathComboBox->itemText(ui.outputPathComboBox->currentIndex()));
00124 }
00125 
00126 void MainWindow::on_inputFileBrowseButton_clicked()
00127 {
00128     QString s = QFileDialog::getOpenFileName(this, tr("Select a file to decompile..."), "test", "Windows Binaries (*.exe *.dll *.scr *.sys);;Other Binaries (*.*)");
00129     if (!s.isEmpty()) {
00130         if (ui.inputFileComboBox->findText(s) == -1) {
00131             ui.inputFileComboBox->addItem(s);
00132             ui.inputFileComboBox->setCurrentIndex(ui.inputFileComboBox->findText(s));
00133             saveSettings();
00134         }
00135         decompilerThread->getDecompiler()->changeInputFile(s);
00136         if (!ui.outputPathComboBox->currentText().isEmpty())
00137             ui.toLoadButton->setDisabled(false);
00138     }
00139 }
00140 
00141 void MainWindow::on_outputPathBrowseButton_clicked()
00142 {
00143     QString s = QFileDialog::getExistingDirectory(this, tr("Select a location to write output..."), "output");
00144     if (!s.isEmpty()) {
00145         if (ui.outputPathComboBox->findText(s) == -1) {
00146             ui.outputPathComboBox->addItem(s);
00147             saveSettings();
00148         }
00149         ui.outputPathComboBox->setEditText(s);
00150         if (!ui.inputFileComboBox->currentText().isEmpty())
00151             ui.toLoadButton->setDisabled(false);
00152     }
00153 }
00154 
00155 void MainWindow::on_inputFileComboBox_editTextChanged(const QString &text)
00156 {
00157     decompilerThread->getDecompiler()->changeInputFile(text);
00158     if (ui.inputFileComboBox->findText(text) == -1) {
00159         ui.inputFileComboBox->addItem(text);
00160         ui.inputFileComboBox->setCurrentIndex(ui.inputFileComboBox->findText(text));
00161         saveSettings();
00162     }
00163     if (!ui.outputPathComboBox->currentText().isEmpty())
00164         ui.toLoadButton->setDisabled(false);
00165 }
00166 
00167 void MainWindow::on_inputFileComboBox_currentIndexChanged(const QString &text)
00168 {
00169     decompilerThread->getDecompiler()->changeInputFile(text);
00170     saveSettings();
00171 }
00172 
00173 void MainWindow::on_outputPathComboBox_editTextChanged(QString &text)
00174 {
00175     decompilerThread->getDecompiler()->changeOutputPath(text);
00176     ui.outputPathComboBox->addItem(text);
00177     saveSettings();
00178     if (!ui.inputFileComboBox->currentText().isEmpty())
00179         ui.toLoadButton->setDisabled(false);
00180 }
00181 
00182 void MainWindow::closeCurrentTab()
00183 {
00184     if (openFiles.find(ui.tabWidget->currentWidget()) != openFiles.end())
00185         on_actionClose_activated();
00186     else if (ui.tabWidget->currentIndex() != 0)
00187         ui.tabWidget->removeTab(ui.tabWidget->currentIndex());
00188 }
00189 
00190 void MainWindow::currentTabTextChanged()
00191 {
00192     QString text = ui.tabWidget->tabText(ui.tabWidget->currentIndex());
00193     if (text.right(1) != "*")
00194         ui.tabWidget->setTabText(ui.tabWidget->currentIndex(), text.append("*"));
00195 }
00196 
00197 void MainWindow::on_actionOpen_activated()
00198 {
00199     QString filename = QFileDialog::getOpenFileName(this, tr("Select a file to open..."));
00200     if (!filename.isEmpty()) {
00201         QTextEdit *n = new QTextEdit();
00202         QFile file(filename);
00203         if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
00204             return;
00205         QTextStream in(&file);
00206         QString contents = in.readAll();
00207         file.close();
00208         n->insertPlainText(contents);
00209         openFiles[n] = filename;
00210         if (filename.endsWith(".h"))
00211             signatureFiles.insert(n);
00212         connect(n, SIGNAL(textChanged()), this, SLOT(currentTabTextChanged()));
00213         QString name = filename; 
00214         name = name.right(name.length() - filename.lastIndexOf(QRegExp("[/\\\\]")) - 1);
00215         ui.tabWidget->addTab(n, name);
00216         ui.tabWidget->setCurrentWidget(n);
00217     }
00218 }
00219 
00220 void MainWindow::on_actionSave_activated()
00221 {
00222     if (openFiles.find(ui.tabWidget->currentWidget()) != openFiles.end()) {
00223         QString filename = openFiles[ui.tabWidget->currentWidget()];
00224         QFile file(filename);
00225         if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate))
00226             return;
00227         QTextEdit *edit = (QTextEdit*)ui.tabWidget->currentWidget();
00228         file.write(edit->toPlainText().toAscii());
00229         file.close();
00230         QString text = ui.tabWidget->tabText(ui.tabWidget->currentIndex());
00231         if (text.right(1) == "*")
00232             ui.tabWidget->setTabText(ui.tabWidget->currentIndex(), text.left(text.length()-1));
00233         if (signatureFiles.find(ui.tabWidget->currentWidget()) != signatureFiles.end()) {
00234             decompilerThread->getDecompiler()->rereadLibSignatures();
00235         }
00236     }
00237 }
00238 
00239 void MainWindow::on_actionClose_activated()
00240 {
00241     if (openFiles.find(ui.tabWidget->currentWidget()) != openFiles.end()) {
00242         on_actionSave_activated();
00243         openFiles.erase(ui.tabWidget->currentWidget());
00244         signatureFiles.erase(ui.tabWidget->currentWidget());
00245         ui.tabWidget->removeTab(ui.tabWidget->currentIndex());
00246     }
00247 }
00248 
00249 void MainWindow::on_tabWidget_currentChanged(int index)
00250 {
00251     ui.actionSave->setEnabled(openFiles.find(ui.tabWidget->widget(index)) != openFiles.end());
00252     ui.actionClose->setEnabled(openFiles.find(ui.tabWidget->widget(index)) != openFiles.end());
00253 }
00254 
00255 void MainWindow::errorLoadingFile()
00256 {
00257 }
00258 
00259 void MainWindow::showInitPage()
00260 {
00261     ui.toLoadButton->setDisabled(true);
00262     ui.loadButton->setDisabled(true);
00263     ui.decodeButton->setDisabled(true);
00264     ui.decompileButton->setDisabled(true);
00265     ui.generateCodeButton->setDisabled(true);
00266     ui.toDecodeButton->setDisabled(true);
00267     ui.toDecompileButton->setDisabled(true);
00268     ui.toGenerateCodeButton->setDisabled(true);
00269     ui.stackedWidget->setCurrentIndex(0);
00270     ui.entrypoints->setRowCount(0);
00271     ui.userProcs->setRowCount(0);
00272     ui.libProcs->setRowCount(0);
00273     ui.decompileProcsTreeWidget->clear();
00274     decompiledCount = 0;
00275     ui.clusters->clear();
00276     codeGenCount = 0;
00277     ui.actionLoad->setDisabled(true);
00278     ui.actionDecode->setDisabled(true);
00279     ui.actionDecompile->setDisabled(true);
00280     ui.actionGenerate_Code->setDisabled(true);
00281 }
00282 
00283 void MainWindow::showLoadPage()
00284 {
00285     ui.toLoadButton->setDisabled(true);
00286     ui.loadButton->setDisabled(false);
00287     ui.decodeButton->setDisabled(true);
00288     ui.decompileButton->setDisabled(true);
00289     ui.generateCodeButton->setDisabled(true);
00290     ui.toLoadButton->setDisabled(true);
00291     ui.stackedWidget->setCurrentIndex(1);
00292     ui.actionLoad->setDisabled(false);
00293 }
00294 
00295 void MainWindow::showDecodePage()
00296 {
00297     ui.toLoadButton->setDisabled(true);
00298     ui.loadButton->setDisabled(true);
00299     ui.decodeButton->setDisabled(false);
00300     ui.decompileButton->setDisabled(true);
00301     ui.generateCodeButton->setDisabled(true);
00302     ui.toDecodeButton->setDisabled(true);
00303     ui.stackedWidget->setCurrentIndex(2);
00304 
00305     if (!ui.actionEnable->isChecked()) {
00306         ui.userProcs->removeColumn(2);
00307     } else {
00308         ui.userProcs->setColumnCount(3);
00309         ui.userProcs->setHorizontalHeaderItem(2, new QTableWidgetItem(tr("Debug")));
00310     }
00311 
00312     ui.actionDecode->setDisabled(false);
00313 }
00314 
00315 void MainWindow::showDecompilePage()
00316 {
00317     ui.toLoadButton->setDisabled(true);
00318     ui.loadButton->setDisabled(true);
00319     ui.decodeButton->setDisabled(true);
00320     ui.decompileButton->setDisabled(false);
00321     ui.generateCodeButton->setDisabled(true);
00322     ui.toDecompileButton->setDisabled(true);
00323     ui.stackedWidget->setCurrentIndex(3);
00324 
00325     ui.actionDecompile->setDisabled(false);
00326 }
00327 
00328 void MainWindow::showGenerateCodePage()
00329 {
00330     ui.toLoadButton->setDisabled(true);
00331     ui.loadButton->setDisabled(true);
00332     ui.decodeButton->setDisabled(true);
00333     ui.decompileButton->setDisabled(true);
00334     ui.generateCodeButton->setDisabled(false);
00335     ui.toGenerateCodeButton->setDisabled(true);
00336     ui.stackedWidget->setCurrentIndex(4);
00337     ui.actionGenerate_Code->setDisabled(false);
00338 }
00339 
00340 void MainWindow::loadComplete()
00341 {
00342     ui.toLoadButton->setDisabled(true);
00343     ui.loadButton->setDisabled(false);
00344     ui.decodeButton->setDisabled(true);
00345     ui.decompileButton->setDisabled(true);
00346     ui.generateCodeButton->setDisabled(true);
00347     ui.toDecodeButton->setDisabled(false);
00348     ui.toDecompileButton->setDisabled(true);
00349     ui.toGenerateCodeButton->setDisabled(true);
00350     ui.stackedWidget->setCurrentIndex(1);
00351 }
00352 
00353 void MainWindow::showMachineType(const QString &machine)
00354 {
00355     ui.machineTypeLabel->setText(machine);
00356 }
00357 
00358 void MainWindow::showNewEntrypoint(unsigned int addr, const QString &name)
00359 {
00360     int nrows = ui.entrypoints->rowCount();
00361     ui.entrypoints->setRowCount(nrows + 1);
00362     ui.entrypoints->setItem(nrows, 0, new QTableWidgetItem(tr("%1").arg(addr, 8, 16, QChar('0'))));
00363     ui.entrypoints->setItem(nrows, 1, new QTableWidgetItem(name));
00364     ui.entrypoints->resizeColumnsToContents();
00365     ui.entrypoints->resizeRowsToContents();
00366 }
00367 
00368 void MainWindow::decodeComplete()
00369 {
00370     ui.toLoadButton->setDisabled(true);
00371     ui.loadButton->setDisabled(true);
00372     ui.decodeButton->setDisabled(false);
00373     ui.decompileButton->setDisabled(true);
00374     ui.generateCodeButton->setDisabled(true);
00375     ui.toDecodeButton->setDisabled(true);
00376     ui.toDecompileButton->setDisabled(false);
00377     ui.toGenerateCodeButton->setDisabled(true);
00378     ui.stackedWidget->setCurrentIndex(2);
00379 }
00380 
00381 void MainWindow::decompileComplete()
00382 {
00383     ui.toLoadButton->setDisabled(true);
00384     ui.loadButton->setDisabled(true);
00385     ui.decodeButton->setDisabled(true);
00386     ui.decompileButton->setDisabled(false);
00387     ui.generateCodeButton->setDisabled(true);
00388     ui.toDecodeButton->setDisabled(true);
00389     ui.toDecompileButton->setDisabled(true);
00390     ui.toGenerateCodeButton->setDisabled(false);
00391     ui.stackedWidget->setCurrentIndex(3);
00392 }
00393 
00394 void MainWindow::generateCodeComplete()
00395 {
00396     ui.toLoadButton->setDisabled(true);
00397     ui.loadButton->setDisabled(true);
00398     ui.decodeButton->setDisabled(true);
00399     ui.decompileButton->setDisabled(true);
00400     ui.generateCodeButton->setDisabled(true);
00401     ui.toDecodeButton->setDisabled(true);
00402     ui.toDecompileButton->setDisabled(true);
00403     ui.toGenerateCodeButton->setDisabled(true);
00404     ui.stackedWidget->setCurrentIndex(4);
00405 }
00406 
00407 void MainWindow::showConsideringProc(const QString &parent, const QString &name)
00408 {
00409     QList<QTreeWidgetItem *> foundit = ui.decompileProcsTreeWidget->findItems(name, Qt::MatchExactly | Qt::MatchRecursive);
00410     if (foundit.isEmpty()) {
00411         QStringList texts(name);
00412         if (parent.isEmpty()) {
00413             ui.decompileProcsTreeWidget->addTopLevelItem(new QTreeWidgetItem(texts));
00414         } else {
00415             QList<QTreeWidgetItem *> found = ui.decompileProcsTreeWidget->findItems(parent, Qt::MatchExactly | Qt::MatchRecursive);
00416             if (!found.isEmpty()) {
00417                 QTreeWidgetItem *n = new QTreeWidgetItem(found.first(), texts);
00418                 n->setData(0, 1, name);
00419                 ui.decompileProcsTreeWidget->expandItem(found.first());
00420                 ui.decompileProcsTreeWidget->scrollToItem(n);
00421                 ui.decompileProcsTreeWidget->setCurrentItem(n, 0);              
00422             }
00423         }
00424     }
00425 }
00426 
00427 void MainWindow::showDecompilingProc(const QString &name)
00428 {
00429     QList<QTreeWidgetItem *> foundit = ui.decompileProcsTreeWidget->findItems(name, Qt::MatchExactly | Qt::MatchRecursive);
00430     if (!foundit.isEmpty()) {
00431         ui.decompileProcsTreeWidget->setCurrentItem(foundit.first(), 0);
00432         foundit.first()->setTextColor(0, QColor("blue"));
00433         decompiledCount++;
00434     }
00435     ui.progressDecompile->setRange(0, ui.userProcs->rowCount());
00436     ui.progressDecompile->setValue(decompiledCount);
00437 }
00438 
00439 void MainWindow::showNewUserProc(const QString &name, unsigned int addr)
00440 {
00441     QString s = tr("%1").arg(addr, 8, 16, QChar('0'));
00442     int nrows = ui.userProcs->rowCount();
00443     for (int i = 0; i < nrows; i++)
00444         if (ui.userProcs->item(i, 1)->text() == name)
00445             return;
00446     for (int i = 0; i < nrows; i++)
00447         if (ui.userProcs->item(i, 0)->text() == s)
00448             return;
00449     ui.userProcs->setRowCount(nrows + 1);
00450     ui.userProcs->setItem(nrows, 0, new QTableWidgetItem(tr("%1").arg(addr, 8, 16, QChar('0'))));
00451     ui.userProcs->setItem(nrows, 1, new QTableWidgetItem(name));
00452     ui.userProcs->item(nrows, 1)->setData(1, name);
00453     if (ui.actionEnable->isChecked()) {
00454         QTableWidgetItem *d = new QTableWidgetItem("");
00455         d->setCheckState(Qt::Checked);
00456         ui.userProcs->setItem(nrows, 2, d);
00457     }
00458     ui.userProcs->resizeColumnsToContents();
00459     ui.userProcs->resizeRowsToContents();
00460 }
00461 
00462 void MainWindow::showNewLibProc(const QString &name, const QString &params)
00463 {
00464     int nrows = ui.libProcs->rowCount();
00465     for (int i = 0; i < nrows; i++)
00466         if (ui.libProcs->item(i, 0)->text() == name) {
00467             ui.libProcs->item(i, 1)->setText(params);
00468             return;
00469         }
00470     ui.libProcs->setRowCount(nrows + 1);
00471     ui.libProcs->setItem(nrows, 0, new QTableWidgetItem(name));
00472     ui.libProcs->setItem(nrows, 1, new QTableWidgetItem(params));
00473     ui.libProcs->resizeColumnsToContents();
00474     ui.libProcs->resizeRowsToContents();
00475 }
00476 
00477 void MainWindow::showRemoveUserProc(const QString &name, unsigned int addr)
00478 {
00479     QString s = tr("%1").arg(addr, 8, 16, QChar('0'));
00480     int nrows = ui.userProcs->rowCount();
00481     for (int i = 0; i < nrows; i++)
00482         if (ui.userProcs->item(i, 0)->text() == s) {
00483             ui.userProcs->removeRow(i);
00484             break;
00485         }
00486     ui.userProcs->resizeColumnsToContents();
00487     ui.userProcs->resizeRowsToContents();
00488 }
00489 
00490 void MainWindow::showRemoveLibProc(const QString &name)
00491 {
00492     int nrows = ui.libProcs->rowCount();
00493     for (int i = 0; i < nrows; i++)
00494         if (ui.libProcs->item(i, 0)->text() == name) {
00495             ui.libProcs->removeRow(i);
00496             break;
00497         }
00498     ui.libProcs->resizeColumnsToContents();
00499     ui.libProcs->resizeRowsToContents();
00500 }
00501 
00502 void MainWindow::showNewSection(const QString &name, unsigned int start, unsigned int end)
00503 {
00504     int nrows = ui.sections->rowCount();
00505     ui.sections->setRowCount(nrows + 1);
00506     ui.sections->setItem(nrows, 0, new QTableWidgetItem(name));
00507     ui.sections->setItem(nrows, 1, new QTableWidgetItem(tr("%1").arg(start, 8, 16, QChar('0'))));
00508     ui.sections->setItem(nrows, 2, new QTableWidgetItem(tr("%1").arg(end, 8, 16, QChar('0'))));
00509     ui.sections->sortItems(1, Qt::AscendingOrder);
00510     ui.sections->resizeColumnsToContents();
00511     ui.sections->resizeRowsToContents();
00512 }
00513 
00514 void MainWindow::showNewCluster(const QString &name)
00515 {
00516     QString cname = name;
00517     cname = cname.append(".c");
00518     QTreeWidgetItem *n = new QTreeWidgetItem(QStringList(cname));
00519     ui.clusters->addTopLevelItem(n);
00520     ui.clusters->expandItem(n);
00521 }
00522 
00523 void MainWindow::showNewProcInCluster(const QString &name, const QString &cluster)
00524 {
00525     QString cname = cluster;
00526     cname = cname.append(".c");
00527     QList<QTreeWidgetItem *> found = ui.clusters->findItems(cname, Qt::MatchExactly);
00528     if (!found.isEmpty()) {
00529         QTreeWidgetItem *n = new QTreeWidgetItem(found.first(), QStringList(name));
00530         ui.clusters->scrollToItem(n);
00531         ui.clusters->setCurrentItem(n, 0);
00532         ui.clusters->expandItem(found.first());
00533         codeGenCount++;
00534     }
00535     ui.progressGenerateCode->setRange(0, ui.userProcs->rowCount());
00536     ui.progressGenerateCode->setValue(codeGenCount);
00537 }
00538 
00539 void MainWindow::showDebuggingPoint(const QString &name, const QString &description)
00540 {
00541     QString msg = "debugging ";
00542     msg.append(name);
00543     msg.append(": ");
00544     msg.append(description);
00545     statusBar()->showMessage(msg);
00546     ui.actionStep->setEnabled(true);
00547 
00548     for (int i = 0; i < ui.userProcs->rowCount(); i++)
00549         if (ui.userProcs->item(i, 1)->text() == name && ui.userProcs->item(i, 2)->checkState() != Qt::Checked) {
00550             on_actionStep_activated();
00551             return;
00552         }
00553 
00554     showRTLEditor(name);
00555 }
00556 
00557 void MainWindow::showRTLEditor(const QString &name)
00558 {
00559     RTLEditor *n = NULL;
00560     for (int i = 0; i < ui.tabWidget->count(); i++)
00561         if (ui.tabWidget->tabText(i) == name) {
00562             n = dynamic_cast<RTLEditor*>(ui.tabWidget->widget(i));
00563             break;
00564         }
00565     if (n == NULL) {
00566         n = new RTLEditor(decompilerThread->getDecompiler(), name);
00567         ui.tabWidget->addTab(n, name);
00568     } else
00569         n->updateContents();
00570     ui.tabWidget->setCurrentWidget(n);
00571 }
00572 
00573 void MainWindow::on_userProcs_cellDoubleClicked(int row, int column)
00574 {
00575     showRTLEditor(ui.userProcs->item(row, 1)->text());
00576 }
00577 
00578 void MainWindow::on_userProcs_cellChanged(int row, int column)
00579 {
00580     if (column == 0) {
00581         // TODO: should we allow the user to change the address of a proc?
00582     }
00583     if (column == 1) {
00584         QString old_name = ui.userProcs->item(row, 1)->data(1).toString();
00585         decompilerThread->getDecompiler()->renameProc(old_name, ui.userProcs->item(row, 1)->text());
00586         ui.userProcs->item(row, 1)->setData(1, ui.userProcs->item(row, 1)->text());     
00587     }
00588 }
00589 
00590 void MainWindow::on_clusters_itemDoubleClicked(QTreeWidgetItem *item, int column)
00591 {
00592     QTreeWidgetItem *top = item;
00593     while (top->parent())
00594         top = top->parent();
00595     QTextEdit *n = NULL;
00596     for (int i = 0; i < ui.tabWidget->count(); i++)
00597         if (ui.tabWidget->tabText(i) == top->text(0)) {
00598             n = dynamic_cast<QTextEdit*>(ui.tabWidget->widget(i));
00599             break;
00600         }
00601     if (n == NULL) {
00602         n = new QTextEdit();    
00603         QString name = top->text(0);
00604         name = name.left(name.lastIndexOf("."));
00605         QString filename = decompilerThread->getDecompiler()->getClusterFile(name);
00606         QFile file(filename);
00607         if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
00608             return;
00609         QTextStream in(&file);
00610         QString contents = in.readAll();
00611         file.close();
00612         n->insertPlainText(contents);
00613         openFiles[n] = filename;
00614         connect(n, SIGNAL(textChanged()), this, SLOT(currentTabTextChanged()));
00615         ui.tabWidget->addTab(n, top->text(0));
00616     }
00617     ui.tabWidget->setCurrentWidget(n);
00618 }
00619 
00620 void MainWindow::on_decompileProcsTreeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column)
00621 {
00622     showRTLEditor(item->text(0));
00623 }
00624 
00625 void MainWindow::on_actionEnable_toggled(bool b)
00626 {
00627     decompilerThread->getDecompiler()->setDebugging(b);
00628     decompilerThread->getDecompiler()->stopWaiting();
00629     if (b) {
00630         statusBar()->show();
00631         if (step == NULL) {
00632             step = new QToolButton();
00633             step->setToolButtonStyle(Qt::ToolButtonTextOnly);
00634             step->setText("Step");
00635             step->setDefaultAction(ui.actionStep);
00636         }
00637         statusBar()->addPermanentWidget(step);
00638     } else {
00639         if (step)
00640             statusBar()->removeWidget(step);
00641         statusBar()->hide();
00642     }
00643     
00644 }
00645 
00646 void MainWindow::on_actionStep_activated()
00647 {
00648     ui.actionStep->setEnabled(false);
00649     decompilerThread->getDecompiler()->stopWaiting();
00650 }
00651 
00652 void MainWindow::on_userProcs_horizontalHeader_sectionClicked(int logicalIndex)
00653 {
00654     if (logicalIndex == 2) {
00655         for (int i = 0; i < ui.userProcs->rowCount(); i++) {
00656             if (ui.userProcs->item(i, 2) == NULL) {
00657                 ui.userProcs->setItem(i, 2, new QTableWidgetItem(""));
00658             }
00659             Qt::CheckState state = ui.userProcs->item(i, 2)->checkState();
00660             ui.userProcs->item(i, 2)->setCheckState(state == Qt::Checked ? Qt::Unchecked : Qt::Checked);
00661         }
00662     }
00663 }
00664 
00665 void MainWindow::on_libProcs_cellDoubleClicked(int row, int column)
00666 {
00667     QString name = "";
00668     QString sigFile;
00669     QString params = ui.libProcs->item(row, 1)->text();
00670     bool existing = true;
00671     if (params == "<unknown>") {
00672         existing = false;
00673         // uhh, time to guess?
00674         for (int i = row; i >= 0; i--) {
00675             params = ui.libProcs->item(i, 1)->text();
00676             if (params != "<unknown>") {
00677                 name = ui.libProcs->item(i, 0)->text();
00678                 break;
00679             }
00680         }
00681         if (name.isEmpty())
00682             return;
00683     } else
00684         name = ui.libProcs->item(row, 0)->text();
00685 
00686     sigFile = decompilerThread->getDecompiler()->getSigFile(name);
00687     QString filename = sigFile;
00688 
00689     int pos = sigFile.lastIndexOf(QRegExp("[/\\\\]"));
00690     if (pos != -1)
00691         sigFile = sigFile.right(sigFile.length() - pos - 1);
00692     QString sigFileStar = sigFile;
00693     sigFileStar.append("*");
00694 
00695     QTextEdit *n = NULL;
00696     for (int i = 0; i < ui.tabWidget->count(); i++)
00697         if (ui.tabWidget->tabText(i) == sigFile || ui.tabWidget->tabText(i) == sigFileStar) {
00698             n = dynamic_cast<QTextEdit*>(ui.tabWidget->widget(i));
00699             break;
00700         }
00701     if (n == NULL) {
00702         n = new QTextEdit();
00703         QFile file(filename);
00704         if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
00705             return;
00706         QTextStream in(&file);
00707         QString contents = in.readAll();
00708         file.close();
00709         n->insertPlainText(contents);
00710         openFiles[n] = filename;
00711         signatureFiles.insert(n);
00712         connect(n, SIGNAL(textChanged()), this, SLOT(currentTabTextChanged()));
00713         ui.tabWidget->addTab(n, sigFile);
00714     }
00715     ui.tabWidget->setCurrentWidget(n);
00716     if (existing)
00717         n->find(name, QTextDocument::FindBackward | QTextDocument::FindCaseSensitively | QTextDocument::FindWholeWords);
00718     else {
00719         QTextCursor cursor = n->textCursor();
00720         cursor.clearSelection();
00721         cursor.movePosition(QTextCursor::End);
00722         n->setTextCursor(cursor);
00723         QString comment = "// unknown library proc: ";
00724         comment.append(ui.libProcs->item(row, 0)->text());
00725         comment.append("\n");
00726         n->insertPlainText(comment);
00727     }
00728 }
00729 
00730 void MainWindow::on_actionCut_activated()
00731 {
00732     if (ui.tabWidget->currentIndex() != 0) {
00733         QTextEdit *n = dynamic_cast<QTextEdit*>(ui.tabWidget->currentWidget());
00734         if (n)
00735             n->cut();
00736     }
00737 }
00738 
00739 void MainWindow::on_actionCopy_activated()
00740 {
00741     if (ui.tabWidget->currentIndex() != 0) {
00742         QTextEdit *n = dynamic_cast<QTextEdit*>(ui.tabWidget->currentWidget());
00743         if (n)
00744             n->copy();
00745     }
00746 }
00747 
00748 void MainWindow::on_actionPaste_activated()
00749 {
00750     if (ui.tabWidget->currentIndex() != 0) {
00751         QTextEdit *n = dynamic_cast<QTextEdit*>(ui.tabWidget->currentWidget());
00752         if (n)
00753             n->paste();
00754     }
00755 }
00756 
00757 void MainWindow::on_actionDelete_activated()
00758 {
00759     if (ui.tabWidget->currentIndex() != 0) {
00760         QTextEdit *n = dynamic_cast<QTextEdit*>(ui.tabWidget->currentWidget());
00761         if (n)
00762             n->textCursor().removeSelectedText();
00763     }
00764 }
00765 
00766 void MainWindow::on_actionFind_activated()
00767 {
00768 }
00769 
00770 void MainWindow::on_actionFind_Next_activated()
00771 {
00772 }
00773 
00774 void MainWindow::on_actionGo_To_activated()
00775 {
00776 }
00777 
00778 void MainWindow::on_actionSelect_All_activated()
00779 {
00780     if (ui.tabWidget->currentIndex() != 0) {
00781         QTextEdit *n = dynamic_cast<QTextEdit*>(ui.tabWidget->currentWidget());
00782         if (n)
00783             n->selectAll();
00784     }
00785 }
00786 
00787 void MainWindow::on_actionLoad_activated()
00788 {
00789     showLoadPage();
00790 }
00791 
00792 void MainWindow::on_actionDecode_activated()
00793 {
00794     showDecodePage();
00795 }
00796 
00797 void MainWindow::on_actionDecompile_activated()
00798 {
00799     showDecompilePage();
00800 }
00801 
00802 void MainWindow::on_actionGenerate_Code_activated()
00803 {
00804     showGenerateCodePage();
00805 }
00806 
00807 void MainWindow::on_actionStructs_activated()
00808 {
00809     for (int i = 0; i < ui.tabWidget->count(); i++)
00810         if (ui.tabWidget->widget(i) == structs)
00811             return;
00812     ui.tabWidget->addTab(structs, "Structs");
00813     ui.tabWidget->setCurrentWidget(structs);
00814 }
00815 
00816 void MainWindow::on_structName_returnPressed()
00817 {
00818     decompilerThread->getDecompiler()->getCompoundMembers(ui.structName->text(), ui.structMembers);
00819 }
00820 
00821 #ifdef Q_WS_WIN
00822 #include "windows.h"        // For the windows specific code below (ShellExecuteA)
00823 #endif
00824 
00825 void MainWindow::on_actionBoomerang_Website_activated()
00826 {
00827     // This should be a whole lot easier and more portable!
00828 #ifdef Q_WS_WIN
00829     ShellExecuteA(NULL, "open", "http://boomerang.sourceforge.net/", NULL, NULL, SW_SHOW);
00830 #else
00831     // From a web search:
00832     QProcess *browser = new QProcess( this );
00833     browser->start("firefox http://boomerang.sourceforge.net");
00834     if (browser->state() == QProcess::NotRunning)
00835     {
00836         QMessageBox::critical(this, "Critical!","Firefox reports error!",
00837             QMessageBox::Ok | QMessageBox::Default, QMessageBox::NoButton);
00838     }
00839 #endif
00840 }
00841 
00842 void MainWindow::on_actionAbout_activated()
00843 {
00844     QDialog *dlg = new QDialog;
00845     Ui::AboutDialog ui;
00846     ui.setupUi(dlg);
00847     ui.VersionLabel->setText(QString("<h3>").append(Boomerang::getVersionStr()).append("</h3>"));
00848     dlg->show();
00849 }
00850 
00851 void MainWindow::on_actionAboutQt_activated()
00852 {
00853     QApplication::aboutQt();
00854 }
00855 
00856 void MainWindow::on_enableDFTAcheckBox_toggled(bool b)
00857 {
00858     decompilerThread->getDecompiler()->setUseDFTA(b);
00859 }
00860 
00861 void MainWindow::on_enableNoDecodeChildren_toggled(bool b)
00862 {
00863     decompilerThread->getDecompiler()->setNoDecodeChildren(b);
00864 }
00865 
00866 void MainWindow::on_entrypoints_currentItemChanged(QTableWidgetItem *current, QTableWidgetItem *previous)
00867 {
00868     ui.removeButton->setEnabled(true);
00869 }
00870 
00871 void MainWindow::on_addButton_pressed()
00872 {
00873     if (ui.addressEdit->text() == "" || ui.nameEdit->text() == "")
00874         return;
00875     bool ok;
00876     ADDRESS a = ui.addressEdit->text().toInt(&ok, 16);
00877     if (!ok)
00878         return;
00879     decompilerThread->getDecompiler()->addEntryPoint(a, (const char *)ui.nameEdit->text().toAscii());
00880     int nrows = ui.entrypoints->rowCount();
00881     ui.entrypoints->setRowCount(nrows + 1);
00882     ui.entrypoints->setItem(nrows, 0, new QTableWidgetItem(ui.addressEdit->text()));
00883     ui.entrypoints->setItem(nrows, 1, new QTableWidgetItem(ui.nameEdit->text()));
00884     ui.addressEdit->clear();
00885     ui.nameEdit->clear();
00886 }
00887 
00888 void MainWindow::on_removeButton_pressed()
00889 {
00890     bool ok;
00891     ADDRESS a = ui.entrypoints->item(ui.entrypoints->currentRow(), 0)->text().toInt(&ok, 16);
00892     if (!ok)
00893         return;
00894     decompilerThread->getDecompiler()->removeEntryPoint(a);
00895     ui.entrypoints->removeRow(ui.entrypoints->currentRow());
00896 }

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