From: Christoph Egger Date: Thu, 19 Feb 2015 15:51:41 +0000 (+0100) Subject: Add basic save support (Infrastructure) X-Git-Tag: v0.1~104 X-Git-Url: https://git.siccegge.de//index.cgi?p=frida%2Ffrida.git;a=commitdiff_plain;h=64cdefa8eebaedef3a852b061d4df431b7e6c654 Add basic save support (Infrastructure) This is some start on save infrastructure. To complete save/load we now need to add all relevant information to the save() function and the implement load(). Also fileformat is not really setteled by now. --- diff --git a/src/core/InformationManager.cxx b/src/core/InformationManager.cxx index f0b6e1e..0907cf9 100644 --- a/src/core/InformationManager.cxx +++ b/src/core/InformationManager.cxx @@ -1,8 +1,49 @@ #include "InformationManager.hxx" #include "disassembler/llvm/LLVMDisassembler.hxx" +#include "gui/qt.hxx" +#include "quazip/quazip.h" +#include "quazip/quazipfile.h" void InformationManager::reset(const std::string& filename) { disassembler.reset(createLLVMDisassembler(filename, this)); if (disassembler.get() != NULL) disassembler.get()->start(); } + +void InformationManager::save(const QString& filename) { + QuaZip zip(filename); + zip.open(QuaZip::mdCreate); + zip.setComment("FRIDA 0.0"); + QuaZipFile outZipFile(&zip); + + for (Function* fun : functions) { + QuaZipNewInfo zipinfo(fun->getName().c_str()); + zipinfo.setPermissions(static_cast(0x6444)); + outZipFile.open(QIODevice::WriteOnly, zipinfo); + QXmlStreamWriter stream(&outZipFile); + stream.setAutoFormatting(true); + stream.setAutoFormattingIndent(-1); + stream.writeStartDocument(); + stream.writeStartElement("function"); + stream.writeAttribute("name", fun->getName().c_str()); + stream.writeAttribute("entry", QString::number(fun->getStartAddress(), 16)); + + for (auto& blockentry : fun->blocks()) { + stream.writeStartElement("block"); + stream.writeAttribute("id", blockentry.second->getName().c_str()); + stream.writeTextElement("start", QString::number(blockentry.second->getStartAddress(), 16)); + stream.writeTextElement("end", QString::number(blockentry.second->getEndAddress(), 16)); + if (0 != blockentry.second->getNextBlock(0)) + stream.writeTextElement("next", QString::number(blockentry.second->getNextBlock(0), 16)); + if (0 != blockentry.second->getNextBlock(1)) + stream.writeTextElement("next", QString::number(blockentry.second->getNextBlock(1), 16)); + stream.writeEndElement(); // "block" + } + + stream.writeEndElement(); // "function" + stream.writeEndDocument(); + outZipFile.close(); + } + + zip.close(); +} diff --git a/src/core/InformationManager.hxx b/src/core/InformationManager.hxx index 9285d5f..4e1b318 100644 --- a/src/core/InformationManager.hxx +++ b/src/core/InformationManager.hxx @@ -4,51 +4,44 @@ #include #include #include +#include class Disassembler; class Function; +class QString; + class InformationManager { public: - boost::signals2::connection - connect_new_function_signal(std::function f) { - return new_function_signal.connect(f); - } - - void signal_new_function(Function* f) { - new_function_signal(f); - } + void reset(const std::string& filename); + void save(const QString& filename); boost::signals2::connection - connect_new_dyn_symbol_signal(std::function f) { - return new_dyn_symbol_signal.connect(f); - } + connect_new_function_signal(std::function f) + { return new_function_signal.connect(f); } - void signal_new_dyn_symbol(const std::string& f) { - new_dyn_symbol_signal(f); - } + void signal_new_function(Function* f) + { functions.insert(f); new_function_signal(f); } boost::signals2::connection - connect_reset_signal(std::function f) { - return reset_signal.connect(f); - } + connect_new_dyn_symbol_signal(std::function f) + { return new_dyn_symbol_signal.connect(f); } - // boost::signals2::connection - // connect_information_added_signal(uint64_t begin, uint64_t end, - // std::function) { + void signal_new_dyn_symbol(const std::string& f) + { new_dyn_symbol_signal(f); } - // } - - Disassembler* getDisassembler() { - return disassembler.get(); - } + boost::signals2::connection + connect_reset_signal(std::function f) + { return reset_signal.connect(f); } - void reset(const std::string& filename); + Disassembler* getDisassembler() + { return disassembler.get(); } private: boost::signals2::signal reset_signal; boost::signals2::signal new_function_signal; boost::signals2::signal new_dyn_symbol_signal; std::unique_ptr disassembler; + std::set functions; }; #endif /* INCLUDE__InformationManager_hxx */ diff --git a/src/disassembler/BasicBlock.hxx b/src/disassembler/BasicBlock.hxx index 6d623d0..b3e5a89 100644 --- a/src/disassembler/BasicBlock.hxx +++ b/src/disassembler/BasicBlock.hxx @@ -2,6 +2,8 @@ #define INCLUDE__BasicBlock_hxx #include +#include +#include class BasicBlock { public: @@ -36,6 +38,12 @@ public: end_address = address; } + std::string getName() { + std::stringstream s; + s << "BLOCK_" << std::hex << start_address << '_' << end_address; + return s.str(); + } + private: uint64_t start_address; uint64_t end_address; diff --git a/src/gui/Mainwindow.cxx b/src/gui/Mainwindow.cxx index 18dcc8b..03910a1 100644 --- a/src/gui/Mainwindow.cxx +++ b/src/gui/Mainwindow.cxx @@ -20,18 +20,19 @@ Mainwindow::Mainwindow(InformationManager* mgr) : manager(mgr) , logger(log4cxx::Logger::getLogger("Mainwindow")) { openAction = new QAction(tr("&Open"), this); - // saveAction = new QAction(tr("&Save"), this); + saveAction = new QAction(tr("&Save"), this); exitAction = new QAction(tr("E&xit"), this); connect(openAction, SIGNAL(triggered()), this, SLOT(open())); - // connect(saveAction, SIGNAL(triggered()), this, SLOT(save())); + connect(saveAction, SIGNAL(triggered()), + this, SLOT(save())); connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit())); fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(openAction); - // fileMenu->addAction(saveAction); + fileMenu->addAction(saveAction); fileMenu->addSeparator(); fileMenu->addAction(exitAction); @@ -94,6 +95,11 @@ void Mainwindow::open() { manager->reset(fileName.toStdString()); } +void Mainwindow::save() { + QString filename = QFileDialog::getSaveFileName(this, tr("Save File"), "", tr("Frida Archives (*.frida)")); + manager->save(filename); +} + void Mainwindow::switchMainPlaneToAddress(uint64_t address) { if (objects_list_by_address.find(address) != objects_list_by_address.end()) { LOG4CXX_DEBUG(logger, "Switching to function " << std::hex << address); diff --git a/src/gui/Mainwindow.hxx b/src/gui/Mainwindow.hxx index 7084e2f..0962efd 100644 --- a/src/gui/Mainwindow.hxx +++ b/src/gui/Mainwindow.hxx @@ -39,6 +39,7 @@ private: QAction *exitAction; QAction *openAction; + QAction *saveAction; std::map blocks; std::map objects_list; @@ -53,6 +54,7 @@ public Q_SLOTS: private Q_SLOTS: void quit(); void open(); + void save(); void switchMainPlane(int); void showListContextMenu(const QPoint&); void requestNewFunction(); diff --git a/src/gui/qt.hxx b/src/gui/qt.hxx index 97a1d28..ae4ef2c 100644 --- a/src/gui/qt.hxx +++ b/src/gui/qt.hxx @@ -25,5 +25,7 @@ #include #include #include +#include +#include #endif /* INCLUDE__qt_hxx_ */