From 546b89382dd61b664c216ad7668ec783f0ad094c Mon Sep 17 00:00:00 2001 From: Christoph Egger Date: Mon, 16 Mar 2015 16:40:18 +0100 Subject: [PATCH] Restructure InformationManager - Signals now all use Event objects to communicate information and all share a common sane interface - Organize signals consistently and grup by signal name - Dynamic and local functions are now handled almost the same - Changes all over the place to fix users for these changes - proper iterator access for the maps so one can actually iterate over all functions (for example a script) - ignore these iterators where they would be most usefuill (scripting) untill I figure out how to make SWIG compile them properly --- CMakeLists.txt | 1 + src/bindings/guile/frida.i | 11 +++- src/core/Comment.hxx | 10 +++- src/core/Function.cxx | 3 +- src/core/Function.hxx | 16 +++--- src/core/InformationManager.cxx | 33 ++++++++---- src/core/InformationManager.hxx | 61 +++++++++++++--------- src/disassembler/llvm/LLVMDisassembler.cxx | 6 ++- src/gui/Mainwindow.cxx | 15 ++++-- src/gui/widgets/BasicBlockWidget.cxx | 2 +- 10 files changed, 103 insertions(+), 55 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c178ba..51f9689 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,6 +48,7 @@ SWIG_LINK_LIBRARIES(frida-guile ${GUILE_LDFLAGS}) SET(frida_SOURCES src/core/InformationManager.cxx src/core/BasicBlock.cxx + src/core/Comment.cxx src/core/Function.cxx src/gui/Mainwindow.cxx src/gui/widgets/BasicBlockWidget.cxx diff --git a/src/bindings/guile/frida.i b/src/bindings/guile/frida.i index 03069b9..c8b80b6 100644 --- a/src/bindings/guile/frida.i +++ b/src/bindings/guile/frida.i @@ -6,6 +6,13 @@ %include %include %include +%include + + // noone knows how to get these working +%ignore beginFunctions(); +%ignore endFunctions(); +%ignore beginBasicBlocks(); +%ignore endBasicBlocks(); %{ #include "core/Function.hxx" @@ -17,7 +24,9 @@ %} namespace std { - %template(map_uint64t_BasicBlock) map; + %template(BasicBlockMap) map; + %template(FunctionMap) map; + %template(InterpreterMap) map; } %inline %{ diff --git a/src/core/Comment.hxx b/src/core/Comment.hxx index e151f5a..b07f13a 100644 --- a/src/core/Comment.hxx +++ b/src/core/Comment.hxx @@ -4,18 +4,24 @@ #include class Function; +class InformationManager; class Comment { public: bool isLocal() const {return location == NULL;} + void setText(const std::string& text); + uint64_t getAddress(); private: - Comment(uint64_t address); - Comment(uint64_t address, Function* location); + Comment(uint64_t address, InformationManager* manager); + Comment(uint64_t address, Function* location, InformationManager* manager); uint64_t address; Function* location; + InformationManager* manager; std::string text; + + friend class InformationManager; }; #endif /* INCLUDE__Comment_hxx */ diff --git a/src/core/Function.cxx b/src/core/Function.cxx index c4dc985..e31bce4 100644 --- a/src/core/Function.cxx +++ b/src/core/Function.cxx @@ -4,8 +4,9 @@ #include "InformationManager.hxx" #include "gui/qt.hxx" -Function::Function(uint64_t start_address, InformationManager* manager) +Function::Function(uint64_t start_address, bool dynamic, InformationManager* manager) : start_address(start_address) + , dynamic(dynamic) , manager(manager) {} diff --git a/src/core/Function.hxx b/src/core/Function.hxx index 75b38c2..ab8c0c9 100644 --- a/src/core/Function.hxx +++ b/src/core/Function.hxx @@ -9,17 +9,14 @@ class QXmlStreamWriter; class Function { public: - uint64_t getStartAddress() const { - return start_address; - } + uint64_t getStartAddress() const { return start_address; } - std::string getName() const - { return name; } + std::string getName() const { return name; } void setName(const std::string& new_name); - InformationManager* getManager() const { - return manager; - } + InformationManager* getManager() const { return manager; } + + bool isDynamic() const { return dynamic; } void addBasicBlock(BasicBlock* block) { _blocks.insert(std::make_pair(block->getStartAddress(), block)); @@ -33,10 +30,11 @@ public: static Function* deserialize(QXmlStreamReader& stream, InformationManager* manager); private: - Function(uint64_t start_address, InformationManager* manager); + Function(uint64_t start_address, bool dynamic, InformationManager* manager); std::string name; uint64_t start_address; + bool dynamic; InformationManager * manager; std::map _blocks; diff --git a/src/core/InformationManager.cxx b/src/core/InformationManager.cxx index 5a70dee..e157189 100644 --- a/src/core/InformationManager.cxx +++ b/src/core/InformationManager.cxx @@ -4,6 +4,7 @@ #include "core/Function.hxx" #include "core/BasicBlock.hxx" #include "core/Comment.hxx" +#include "core/events/NewFunctionEvent.hxx" #include "gui/qt.hxx" #include @@ -119,10 +120,6 @@ void InformationManager::save(const std::string& filename) { zip.close(); } -void InformationManager::signal_new_function(Function* fun) { -} - - /* ******************************* * Accessors for the Functions map @@ -189,7 +186,13 @@ std::map::const_iterator InformationManager::endInter */ Function* InformationManager::newFunction(uint64_t address) { - Function* fun = new Function(address, this); + Function* fun = new Function(address, false, this); + functions.insert(std::make_pair(address, fun)); + return fun; +} + +Function* InformationManager::newDynamicFunction(uint64_t address) { + Function* fun = new Function(address, true, this); functions.insert(std::make_pair(address, fun)); return fun; } @@ -201,11 +204,15 @@ BasicBlock* InformationManager::newBasicBlock(uint64_t address) { } Comment* InformationManager::newGlobalComment(uint64_t address) { - return NULL; + Comment* comment = new Comment(address, this); + comments.insert(std::make_pair(address, comment)); + return comment; } Comment* InformationManager::newLocalComment(uint64_t address, Function* f) { - return NULL; + Comment* comment = new Comment(address, this); + comments.insert(std::make_pair(address, comment)); + return comment; } void InformationManager::finishFunction(Function* fun) { @@ -214,10 +221,11 @@ void InformationManager::finishFunction(Function* fun) { BasicBlock* bl = b.second; blocks.insert(std::make_pair(bl->getStartAddress(), bl)); } - new_function_signal(fun); + NewFunctionEvent event(fun->getStartAddress(), fun); + dispatch(&event); } -void InformationManager::finishBasicBlock(BasicBlock* b) { +void InformationManager::finishBasicBlock(BasicBlock*) { } void InformationManager::finnishComment(Comment* c) { @@ -234,5 +242,12 @@ void InformationManager::deleteBasicBlock(BasicBlock* b) { } void InformationManager::deleteComment(Comment* c) { + auto range = comments.equal_range(c->getAddress()); + for (auto it = range.first; it != range.second; ++it) { + if (it->second == c) { + comments.erase(it); + break; + } + } delete c; } diff --git a/src/core/InformationManager.hxx b/src/core/InformationManager.hxx index 610ece5..bb37a1e 100644 --- a/src/core/InformationManager.hxx +++ b/src/core/InformationManager.hxx @@ -17,11 +17,15 @@ class BasicBlock; class Comment; class RenameFunctionEvent; +class NewFunctionEvent; +class ChangeCommentEvent; class QString; class QTemporaryFile; class QPluginLoader; +using boost::signals2::connection; + class InformationManager { public: InformationManager(); @@ -31,32 +35,32 @@ public: void load(const std::string& filename); void save(const std::string& filename); - void signal_new_function(Function* f); - void signal_new_dyn_symbol(const std::string& f) - { new_dyn_symbol_signal(f); } - - boost::signals2::connection - connect_new_function_signal(std::function f) - { return new_function_signal.connect(f); } - - boost::signals2::connection - connect_new_dyn_symbol_signal(std::function f) - { return new_dyn_symbol_signal.connect(f); } - - boost::signals2::connection - connect_reset_signal(std::function f) - { return reset_signal.connect(f); } - - boost::signals2::connection - connect_rename_function_signal(std::function f) - { return rename_function_signal.connect(f); } - Disassembler* getDisassembler() { return disassembler.get(); } + // Rename Function + typedef std::function RenameFunctionHandler; + connection registerRenameFunctionEvent(RenameFunctionHandler h) + { return renameFunctionSignal.connect(h); } void dispatch(RenameFunctionEvent* event) - { rename_function_signal(event); } - + { renameFunctionSignal(event); } + + // New Function + typedef std::function NewFunctionHandler; + connection registerNewFunctionEvent(NewFunctionHandler h) + { return newFunctionSignal.connect(h); } + void dispatch(NewFunctionEvent* event) + { newFunctionSignal(event); } + + // Change Comment + typedef std::function ChangeCommentHandler; + connection registerChangeCommentEvent(ChangeCommentHandler h) + { return changeCommentSignal.connect(h); } + void dispatch(ChangeCommentEvent* event) + { changeCommentSignal(event); } + + connection connect_reset_signal(std::function f) + { return reset_signal.connect(f); } Function* getFunction(uint64_t address); bool hasFunctions() const {return functions.size() != 0;} @@ -68,7 +72,6 @@ public: std::map::const_iterator beginBasicBlocks(); std::map::const_iterator endBasicBlocks(); - Interpreter* getInterpreter(const std::string& name); bool hasInterpreters() const {return interpreters.size() != 0;} std::map::const_iterator beginInterpreters(); @@ -95,6 +98,7 @@ public: * thingsmay happen. */ Function* newFunction(uint64_t address); + Function* newDynamicFunction(uint64_t address); BasicBlock* newBasicBlock(uint64_t address); Comment* newGlobalComment(uint64_t address); Comment* newLocalComment(uint64_t address, Function* f); @@ -106,14 +110,19 @@ public: void deleteComment(Comment* c); private: + boost::signals2::signal renameFunctionSignal; + boost::signals2::signal newFunctionSignal; + boost::signals2::signal changeCommentSignal; + boost::signals2::signal reset_signal; - boost::signals2::signal new_function_signal; - boost::signals2::signal new_dyn_symbol_signal; - boost::signals2::signal rename_function_signal; + std::unique_ptr disassembler; + std::map interpreters; std::map functions; std::map blocks; + std::multimap comments; + std::string filename; std::unique_ptr tmpfile; std::vector plugins; diff --git a/src/disassembler/llvm/LLVMDisassembler.cxx b/src/disassembler/llvm/LLVMDisassembler.cxx index 21766bb..58d122a 100644 --- a/src/disassembler/llvm/LLVMDisassembler.cxx +++ b/src/disassembler/llvm/LLVMDisassembler.cxx @@ -475,7 +475,11 @@ void LLVMDisassembler::readDynamicSymbols() { // TODO: Error handling std::string symbolname = *(elffile->getSymbolName(it)); std::string symbolversion = *(elffile->getSymbolVersion(nullptr, &*it, is_default)); - manager->signal_new_dyn_symbol(symbolname + (is_default? "@@" : "@") + symbolversion); + // TODO: actually get the symbol address from relocations + Function* f = manager->newDynamicFunction(0); + f->setName(symbolname + (is_default? "@@" : "@") + symbolversion); + manager->finishFunction(f); + LOG4CXX_DEBUG(logger, "Adding dynamic Symbol " << symbolname << (is_default? "@@" : "@") << symbolversion); } } diff --git a/src/gui/Mainwindow.cxx b/src/gui/Mainwindow.cxx index 8593110..33e48bc 100644 --- a/src/gui/Mainwindow.cxx +++ b/src/gui/Mainwindow.cxx @@ -6,6 +6,7 @@ #include "core/BasicBlock.hxx" #include "core/InformationManager.hxx" #include "core/events/RenameFunctionEvent.hxx" +#include "core/events/NewFunctionEvent.hxx" #include "widgets/FridaDock.hxx" #include "widgets/LogDock.hxx" @@ -87,12 +88,16 @@ Mainwindow::Mainwindow(InformationManager* mgr) QTreeWidgetItem * external = new QTreeWidgetItem(listWidget, QStringList("External Functions")); external->setChildIndicatorPolicy(QTreeWidgetItem::ShowIndicator); external->setBackground(0, QBrush(QColor(0xff, 0xdd, 0xdd))); - mgr->connect_new_function_signal([&] (Function* fun) {addFunction(fun);}); - mgr->connect_new_dyn_symbol_signal([=] (const std::string& name) { - auto item = new QTreeWidgetItem(external, QStringList(name.c_str())); - item->setBackground(0, QBrush(QColor(0xff, 0xdd, 0xdd))); + mgr->registerNewFunctionEvent([=] (NewFunctionEvent* event) { + std::string name = event->function->getName(); + if (event->function->isDynamic()) { + auto item = new QTreeWidgetItem(external, QStringList(name.c_str())); + item->setBackground(0, QBrush(QColor(0xff, 0xdd, 0xdd))); + } else { + addFunction(event->function); + } }); - mgr->connect_rename_function_signal([&](RenameFunctionEvent* event) { + mgr->registerRenameFunctionEvent([&](RenameFunctionEvent* event) { if (objects_list_by_address.find(event->address) == objects_list_by_address.end()) return; auto item = objects_list_by_address[event->address]; diff --git a/src/gui/widgets/BasicBlockWidget.cxx b/src/gui/widgets/BasicBlockWidget.cxx index 4889cb4..128b9fb 100644 --- a/src/gui/widgets/BasicBlockWidget.cxx +++ b/src/gui/widgets/BasicBlockWidget.cxx @@ -68,7 +68,7 @@ BasicBlockWidget::BasicBlockWidget(const QString& name, BasicBlock * block, , logger(log4cxx::Logger::getLogger("gui.BasicBlockWidget." + name.toStdString())) { next[0] = NULL; next[1] = NULL; - block->getManager()->connect_rename_function_signal([=](RenameFunctionEvent* event) {updateFunctionName(event);}); + block->getManager()->registerRenameFunctionEvent([=](RenameFunctionEvent* event) {updateFunctionName(event);}); _widget.reset(new CustomQGraphicsTextItem("", this)); _widget->setPos(5, 20); -- 2.39.5