]> git.siccegge.de Git - frida/frida.git/blob - src/gui/Mainwindow.cxx
Whitespace cleanup
[frida/frida.git] / src / gui / Mainwindow.cxx
1 #include "Mainwindow.hxx"
2 #include "qt.hxx"
3 #include "disassembler/llvm/LLVMDisassembler.hxx"
4
5 #include "widgets/CFGScene.hxx"
6
7 #include <iostream>
8 #include <sstream>
9 #include <map>
10
11 #include <QtGui>
12
13 namespace {
14 BasicBlockWidget *
15 local__add_basic_block(BasicBlock * block, Disassembler * dis,
16 std::map<uint64_t, BasicBlockWidget*>& known_blocks,
17 CFGScene * scene, uint64_t starty, uint64_t startx);
18 }
19
20 Mainwindow::Mainwindow(InformationManager* mgr)
21 : manager(mgr) {
22 openAction = new QAction(tr("&Open"), this);
23 // saveAction = new QAction(tr("&Save"), this);
24 exitAction = new QAction(tr("E&xit"), this);
25
26 connect(openAction, SIGNAL(triggered()), this, SLOT(open()));
27 // connect(saveAction, SIGNAL(triggered()), this, SLOT(save()));
28 connect(exitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
29
30 fileMenu = menuBar()->addMenu(tr("&File"));
31 fileMenu->addAction(openAction);
32 // fileMenu->addAction(saveAction);
33 fileMenu->addSeparator();
34 fileMenu->addAction(exitAction);
35
36 scripting = new ScriptingDock(tr("Scripting"), this);
37 scripting->setAllowedAreas(Qt::BottomDockWidgetArea);
38 addDockWidget(Qt::BottomDockWidgetArea, scripting);
39
40 listWidget = new QListWidget();
41 stackedWidget = new QStackedWidget();
42 dockWidget = new QDockWidget(tr("Functions"), this);
43 dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea |
44 Qt::RightDockWidgetArea);
45 dockWidget->setWidget(listWidget);
46 addDockWidget(Qt::LeftDockWidgetArea, dockWidget);
47 setCentralWidget(stackedWidget);
48
49 connect(listWidget, SIGNAL(currentRowChanged(int)),
50 stackedWidget, SLOT(setCurrentIndex(int)));
51
52 setWindowTitle(tr("FRIDA"));
53
54 mgr->connect_new_function_signal([&] (Function* fun) {addFunction(fun);});
55 }
56
57 void Mainwindow::quit()
58 {
59 QMessageBox messageBox;
60 messageBox.setWindowTitle(tr("Notepad"));
61 messageBox.setText(tr("Do you really want to quit?"));
62 messageBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
63 messageBox.setDefaultButton(QMessageBox::No);
64 if (messageBox.exec() == QMessageBox::Yes)
65 qApp->quit();
66 }
67
68 void Mainwindow::open() {
69 QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), "",
70 tr("Binaries (*)"));
71
72 manager->reset(fileName.toStdString());
73 }
74
75 void Mainwindow::addFunction(Function* fun) {
76 if (functions.find(fun) != functions.end())
77 return;
78
79 functions.insert(fun);
80
81 QTabWidget * w = new QTabWidget();
82
83 // CFG
84 CFGScene * scene = new CFGScene;
85
86 Disassembler * dis = manager->getDisassembler();
87 std::cerr << dis << std::endl;
88
89 BasicBlock * block = dis->getBasicBlock(fun->getStartAddress());
90
91 local__add_basic_block(block, manager->getDisassembler(), blocks, scene, block->getStartAddress(), 100);
92
93 QGraphicsView * view = new QGraphicsView(scene);
94 w->addTab(view, "CFG");
95
96 // Listing
97 QTableWidget * t = new QTableWidget();
98 t->setColumnCount(3);
99 t->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
100
101 w->addTab(t, "Listing");
102
103 listWidget->addItem(fun->getName().c_str());
104 stackedWidget->addWidget(w);
105 }
106
107 namespace {
108 BasicBlockWidget *
109 local__add_basic_block(BasicBlock * block, Disassembler * dis,
110 std::map<uint64_t, BasicBlockWidget*>& known_blocks,
111 CFGScene * scene, uint64_t starty, uint64_t startx) {
112
113 decltype(known_blocks.begin()) old;
114 if ((old = known_blocks.find(block->getStartAddress())) != known_blocks.end())
115 return old->second;
116
117 std::stringstream s;
118 s << "BLOCK_" << std::hex << block->getStartAddress()
119 << "_" << block->getEndAddress();
120 BasicBlockWidget * widget = new BasicBlockWidget(s.str().c_str(), block);
121
122 known_blocks.insert(std::make_pair(block->getStartAddress(), widget));
123
124 scene->addItem(widget);
125 widget->setFlag(QGraphicsItem::ItemIsMovable, true);
126 widget->moveBy(100*startx, block->getStartAddress() - starty);
127
128 dis->printEachInstruction(block->getStartAddress(), block->getEndAddress(),
129 [&](uint8_t* bytes, size_t byte_count, const std::string& line) {
130 widget->addItem(bytes, byte_count, line.c_str() + 1);
131 });
132
133 BasicBlockWidget *tmp, *nextl(NULL), *nextr(NULL);
134 BasicBlock * tmpblock;
135 if (block->getNextBlock(0) != 0) {
136 int xshift = 0;
137 if (block->getNextBlock(1) != 0)
138 xshift = 1;
139 tmpblock = dis->getBasicBlock(block->getNextBlock(0));
140 tmp = local__add_basic_block(tmpblock, dis,
141 known_blocks,
142 scene, starty, startx+xshift);
143 nextl = tmp;
144 tmp->addPrevious(widget);
145 }
146 if (block->getNextBlock(1) != 0) {
147 tmpblock = dis->getBasicBlock(block->getNextBlock(1));
148 tmp = local__add_basic_block(tmpblock, dis,
149 known_blocks,
150 scene, starty, startx-1);
151 nextr = tmp;
152 tmp->addPrevious(widget);
153 }
154 widget->addNext(nextl, nextr);
155 return widget;
156 }
157 }