From d119a3304a4625429c36e672379da73e3ecdecbd Mon Sep 17 00:00:00 2001 From: hasherezade Date: Fri, 5 Jan 2024 23:16:35 +0100 Subject: [PATCH] [FEATURE] Allow to save content of headers --- bearparser | 2 +- pe-bear/PEDockedWidget.cpp | 64 ++++++++++++++++++++++++------ pe-bear/PEDockedWidget.h | 3 ++ pe-bear/gui/windows/MainWindow.cpp | 8 +++- 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/bearparser b/bearparser index 35f41a1..8c5b2c5 160000 --- a/bearparser +++ b/bearparser @@ -1 +1 @@ -Subproject commit 35f41a1284cfb0929f25e66ccff83eeb691c1c2b +Subproject commit 8c5b2c58fa680fd2b58c25a10a7debe036582cbb diff --git a/pe-bear/PEDockedWidget.cpp b/pe-bear/PEDockedWidget.cpp index 553c877..b1e0e3b 100644 --- a/pe-bear/PEDockedWidget.cpp +++ b/pe-bear/PEDockedWidget.cpp @@ -275,7 +275,8 @@ void PEDockedWidget::goToAddress(bool isRaw) SectionMenu::SectionMenu(MainSettings &settings, QWidget *parent) : QMenu(parent), - mainSettings(settings), peHndl(NULL), selectedSection(NULL) + mainSettings(settings), + peHndl(NULL), selectedSection(NULL), selectedWrapper(NULL) { createActions(); } @@ -303,19 +304,43 @@ void SectionMenu::createActions() addAction(this->dumpDisasmAction); } +void SectionMenu::enableSecActions(bool actionsEnabled) +{ + if (this->clearSelSecAction) this->clearSelSecAction->setVisible(actionsEnabled); + if (this->dumpDisasmAction) this->dumpDisasmAction->setVisible(actionsEnabled); + if (this->loadSelSecAction) this->loadSelSecAction->setVisible(actionsEnabled); +} + +void SectionMenu::wrapperSelected(PeHandler *pe, ExeElementWrapper* wrapper) +{ + this->peHndl = pe; + this->selectedSection = nullptr; + this->selectedWrapper = wrapper; + bool isEnabled = (pe && wrapper) ? true : false; + + this->setEnabled(isEnabled); + this->setTitle(tr("No wrapper selected")); + if (!isEnabled) { + return; + } + this->setTitle(wrapper->getName()); + enableSecActions(false); +} + void SectionMenu::sectionSelected(PeHandler *pe, SectionHdrWrapper *sec) { this->peHndl = pe; this->selectedSection = sec; - bool isEnabled = sec != NULL ? true : false; - if (!pe) isEnabled = false; + this->selectedWrapper = nullptr; + bool isEnabled = (pe && sec) ? true : false; this->setEnabled(isEnabled); this->setTitle(tr("No section selected")); - - if (!isEnabled) return; - + if (!isEnabled) { + return; + } this->setTitle(tr("Section: [") + sec->mappedName + "]"); + enableSecActions(true); } void SectionMenu::dumpSelectedSection() @@ -323,20 +348,35 @@ void SectionMenu::dumpSelectedSection() if (!peHndl) return; PEFile *pe = peHndl->getPe(); if (!pe) return; - if (!selectedSection) return; + if (!selectedSection && !selectedWrapper) return; QString outDir = mainSettings.dirDump; if (outDir == "") outDir = peHndl->getDirPath(); + + QString mappedName = (selectedSection) ? selectedSection->mappedName : selectedWrapper->getName(); - QString defaultPath = outDir + QDir::separator() + peHndl->getShortName() + "[" + selectedSection->mappedName + "]"; + QString defaultPath = outDir + QDir::separator() + peHndl->getShortName() + "[" + mappedName + "]"; QString path = QFileDialog::getSaveFileName(this, tr("Save as..."), defaultPath); if (path.size() == 0) return; + if (selectedSection) { + if (pe->dumpSection(selectedSection, path)) { + QMessageBox::information(this, tr("Done!"), tr("Dumped section: ") + mappedName +"\n"+ tr("into: ") + path); + return; + } else { + QMessageBox::warning(this, tr("Error"), tr("Dumping section failed!")); + } + } + if (selectedWrapper) { + size_t wSize = selectedWrapper->getContentSize(); + BufferView wView(selectedWrapper, 0, wSize); - if (pe->dumpSection(selectedSection, path)) { - QMessageBox::information(this, tr("Done!"), tr("Dumped section: ")+ selectedSection->mappedName +"\n"+ tr("into: ") + path); - return; + bufsize_t dumpedSize = FileBuffer::dump(path, wView, false); + if (dumpedSize) { + QMessageBox::information(this, tr("Done!"), tr("Dumped wrapper: ") + mappedName +"\n"+ tr("into: ") + path); + } else { + QMessageBox::warning(this, tr("Error"), tr("Dumping wrapper failed!")); + } } - QMessageBox::warning(this, tr("Error"), tr("Dumping section failed!")); } void SectionMenu::exportSectionDisasm() diff --git a/pe-bear/PEDockedWidget.h b/pe-bear/PEDockedWidget.h index 3625dd7..97fc0ee 100644 --- a/pe-bear/PEDockedWidget.h +++ b/pe-bear/PEDockedWidget.h @@ -107,6 +107,7 @@ public: public slots: void sectionSelected(PeHandler *pe, SectionHdrWrapper *sec); + void wrapperSelected(PeHandler *pe, ExeElementWrapper* wrapper); void dumpSelectedSection(); void clearSelectedSection(); @@ -115,10 +116,12 @@ public slots: protected: void createActions(); + void enableSecActions(bool enable); MainSettings &mainSettings; PeHandler *peHndl; SectionHdrWrapper *selectedSection; + ExeElementWrapper* selectedWrapper; QAction *dumpSecAction, *dumpSelSecAction, *clearSelSecAction, diff --git a/pe-bear/gui/windows/MainWindow.cpp b/pe-bear/gui/windows/MainWindow.cpp index 63a1172..173d220 100644 --- a/pe-bear/gui/windows/MainWindow.cpp +++ b/pe-bear/gui/windows/MainWindow.cpp @@ -472,9 +472,13 @@ void MainWindow::onHandlerSelected(PeHandler* peHndl) this->unloadAction->setEnabled(isPe); const offset_t offset = (peHndl) ? peHndl->getDisplayedOffset() : INVALID_ADDR; - SectionHdrWrapper* sec = (peHndl) ? pePtr->getSecHdrAtOffset(offset, Executable::RAW) : NULL; - + SectionHdrWrapper* sec = (peHndl) ? pePtr->getSecHdrAtOffset(offset, Executable::RAW) : nullptr; this->sectionMenu.sectionSelected(peHndl, sec); + + if (!sec) { + ExeElementWrapper* selectedWrapper = (peHndl) ? pePtr->getWrapperContaining(offset) : nullptr; + this->sectionMenu.wrapperSelected(peHndl, selectedWrapper); + } if (!isPe) { this->setWindowTitle(this->winDesc);