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
00054
00055
00056
00057
00058
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 ¶ms)
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
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
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"
00823 #endif
00824
00825 void MainWindow::on_actionBoomerang_Website_activated()
00826 {
00827
00828 #ifdef Q_WS_WIN
00829 ShellExecuteA(NULL, "open", "http://boomerang.sourceforge.net/", NULL, NULL, SW_SHOW);
00830 #else
00831
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 }