SET(frida_SOURCES
src/main.cxx
src/core/InformationManager.cxx
+ src/core/Function.cxx
src/gui/Mainwindow.cxx
src/gui/widgets/BasicBlockWidget.cxx
src/gui/widgets/CFGScene.cxx
--- /dev/null
+#include "Function.hxx"
+#include "core/events/RenameFunctionEvent.hxx"
+#include "InformationManager.hxx"
+
+#include <iostream>
+
+Function::Function(const std::string& name, uint64_t start_address,
+ InformationManager* manager)
+ : start_address(start_address)
+ , manager(manager) {
+ setName(name);
+}
+
+
+void Function::setName(const std::string& new_name) {
+ name = new_name;
+ RenameFunctionEvent event(new_name, start_address);
+ manager->dispatch(&event);
+}
+
class Function {
public:
- Function(const std::string& name, uint64_t start_address,
- InformationManager* manager)
- : name(name)
- , start_address(start_address)
- ,manager(manager) {}
+ Function(const std::string& name, uint64_t start_address, InformationManager* manager);
uint64_t getStartAddress() const {
return start_address;
std::string getName() const
{ return name; }
- void setName(const std::string& new_name)
- { name = new_name; }
+ void setName(const std::string& new_name);
InformationManager* getManager() const {
return manager;
#include <quazip/quazipfile.h>
InformationManager::~InformationManager() {
- for (BasicBlock * b : blocks)
- delete b;
+ for (auto b : blocks)
+ delete b.second;
- for (Function * f : functions)
- delete f;
+ for (auto f : functions)
+ delete f.second;
}
void InformationManager::reset(const std::string& filename) {
zip.setComment("FRIDA 0.0");
QuaZipFile outZipFile(&zip);
- for (Function* fun : functions) {
+ for (auto funpair : functions) {
+ Function* fun = funpair.second;
QuaZipNewInfo zipinfo(fun->getName().c_str());
zipinfo.setPermissions(static_cast<QFile::Permissions>(0x6444));
outZipFile.open(QIODevice::WriteOnly, zipinfo);
}
void InformationManager::signal_new_function(Function* fun) {
- functions.insert(fun);
- for (auto b : fun->blocks())
- blocks.insert(b.second);
+ functions.insert(std::make_pair(fun->getStartAddress(), fun));
+ for (auto b : fun->blocks()) {
+ BasicBlock* bl = b.second;
+ blocks.insert(std::make_pair(bl->getStartAddress(), bl));
+ }
new_function_signal(fun);
}
#include <boost/signals2.hpp>
#include <functional>
#include <string>
-#include <set>
+#include <map>
class Disassembler;
class Function;
class QString;
+class RenameFunctionEvent;
+
class InformationManager {
public:
~InformationManager();
void save(const QString& 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<void(Function*)> f)
{ return new_function_signal.connect(f); }
-
-
boost::signals2::connection
connect_new_dyn_symbol_signal(std::function<void(const std::string& name)> f)
{ return new_dyn_symbol_signal.connect(f); }
- void signal_new_dyn_symbol(const std::string& f)
- { new_dyn_symbol_signal(f); }
-
boost::signals2::connection
connect_reset_signal(std::function<void ()> f)
{ return reset_signal.connect(f); }
+ boost::signals2::connection
+ connect_rename_function_signal(std::function<void (RenameFunctionEvent*)> f)
+ { return rename_function_signal.connect(f); }
+
Disassembler* getDisassembler()
{ return disassembler.get(); }
+
+ void dispatch(RenameFunctionEvent* event)
+ { rename_function_signal(event); }
+
+ Function* getFunction(uint64_t address)
+ { return functions[address]; }
+
+ BasicBlock* getBlock(uint64_t address)
+ { return blocks[address]; }
+
private:
boost::signals2::signal<void ()> reset_signal;
boost::signals2::signal<void (Function*)> new_function_signal;
boost::signals2::signal<void (const std::string& name)> new_dyn_symbol_signal;
+ boost::signals2::signal<void (RenameFunctionEvent*)> rename_function_signal;
std::unique_ptr<Disassembler> disassembler;
- std::set<Function*> functions;
- std::set<BasicBlock*> blocks;
+ std::map<uint64_t, Function*> functions;
+ std::map<uint64_t, BasicBlock*> blocks;
};
#endif /* INCLUDE__InformationManager_hxx */
--- /dev/null
+#ifndef INCLUDE__RenameFunctionEvent_hxx_
+#define INCLUDE__RenameFunctionEvent_hxx_
+
+#include <string>
+
+class RenameFunctionEvent {
+public:
+ RenameFunctionEvent(const std::string& name, uint64_t address)
+ : new_name(name), address(address) {}
+
+ std::string new_name;
+ uint64_t address;
+};
+
+#endif /* INCLUDE__RenameFunctionEvent_hxx_ */
#include "gui/Mainwindow.hxx"
#include "gui/dialogs/SimpleStringDialog.hxx"
#include "core/BasicBlock.hxx"
+#include "core/Function.hxx"
+#include "core/InformationManager.hxx"
+#include "core/events/RenameFunctionEvent.hxx"
+#include <iostream>
class CustomQGraphicsTextItem : public QObject, public QGraphicsTextItem {
public:
: width(270), height(45), name(name)
, _table(NULL)
, block(block), mainwindow(mainwindow)
- , logger(log4cxx::Logger::getLogger(name.toStdString() + "BasicBlock")) {
+ , logger(log4cxx::Logger::getLogger(name.toStdString() + " BasicBlockWidget")) {
next[0] = NULL; next[1] = NULL;
+
+ block->getManager()->connect_rename_function_signal([=](RenameFunctionEvent* event) {updateFunctionName(event);});
+
_widget.reset(new CustomQGraphicsTextItem("", this));
_widget->setPos(5, 20);
_widget->setTextInteractionFlags(Qt::TextSelectableByMouse|
}
});
}
+
+void BasicBlockWidget::updateFunctionName(RenameFunctionEvent *event) {
+ QString search = QString("function:") + QString::number(event->address, 16);
+ QTextDocument *document = _widget->document();
+ QTextBlock b = document->begin();
+ while (b.isValid()) {
+ for (QTextBlock::iterator i = b.begin(); !i.atEnd(); ++i) {
+ QTextCharFormat format = i.fragment().charFormat();
+ bool isLink = format.isAnchor();
+ if (isLink)
+ {
+ if (search == format.anchorHref()) {
+ LOG4CXX_DEBUG(logger, i.fragment().text().toStdString() << " ---> " << format.anchorHref().toStdString());
+ QTextCursor c(b);
+ c.setPosition(i.fragment().position());
+ c.movePosition(QTextCursor::Right, QTextCursor::MoveAnchor, i.fragment().length());
+ c.movePosition(QTextCursor::Left, QTextCursor::KeepAnchor, i.fragment().length());
+ c.movePosition(QTextCursor::WordRight, QTextCursor::KeepAnchor);
+ c.insertText(event->new_name.c_str());
+ }
+ }
+ }
+ b = b.next();
+ }
}
void BasicBlockWidget::addItem(uint8_t* bytes, size_t num_bytes,
line = line.replace('\t', ' ').toHtmlEscaped();
if (href != "") {
+ QStringList list = href.split(":");
+ if (list[0] == "function") {
+ uint64_t address = href.split(":")[1].toLongLong(NULL, 16);
+ Function* fun = block->getManager()->getFunction(address);
+
+ if (fun) {
+ line = line.split(" ")[0] + " " + fun->getName().c_str();
+ LOG4CXX_DEBUG(logger, "Naming function at " << address << " " << fun->getName());
+ }
+ }
line = "<a href=\"" + href + "\">" + line + "</a>";
}
class BasicBlock;
+class RenameFunctionEvent;
+
class BasicBlockWidget : public QObject, public QGraphicsItem
{
Q_OBJECT
QString getName() const
{ return name; }
private:
+ void updateFunctionName(RenameFunctionEvent* event);
+
uint32_t width, height;
QString name;
std::unique_ptr<QGraphicsTextItem> _widget;
--- /dev/null
+#include "FunctionWidget.hxx"
--- /dev/null
+#ifndef INCLUDE__FunctionWidget_hxx_
+#define INCLUDE__FunctionWidget_hxx_
+
+#include "gui/qt.hxx"
+
+class Function;
+
+class FunctionWidget : public QTabWidget {
+ Q_OBJECT
+public:
+ FunctionWidget(Function* function)
+ : function(function) {}
+
+ virtual ~FunctionWidget() {}
+
+ Function* getFunction() const
+ { return function; }
+
+private:
+ Function * function;
+};
+
+#endif /* INCLUDE__FunctionWidget_hxx_ */