]> git.siccegge.de Git - frida/frida.git/blob - src/core/InformationManager.cxx
Restructure InformationManager
[frida/frida.git] / src / core / InformationManager.cxx
1 #include "InformationManager.hxx"
2 #include "bindings/Interpreter.hxx"
3 #include "disassembler/llvm/LLVMDisassembler.hxx"
4 #include "core/Function.hxx"
5 #include "core/BasicBlock.hxx"
6 #include "core/Comment.hxx"
7 #include "core/events/NewFunctionEvent.hxx"
8
9 #include "gui/qt.hxx"
10 #include <quazip/quazip.h>
11 #include <quazip/quazipfile.h>
12
13 #include <QTemporaryFile>
14
15 InformationManager* current_information_manager;
16
17 InformationManager::InformationManager()
18 : logger(log4cxx::Logger::getLogger("core.InformationManager"))
19 {
20 current_information_manager = this;
21
22 QPluginLoader* loader = new QPluginLoader("libguilePlugin", NULL);
23 if (!loader->load())
24 LOG4CXX_ERROR(logger, "Loading plugin failed: " << loader->errorString().toStdString());
25 interpreters["GUILE"] = qobject_cast<Interpreter*>(loader->instance());
26 plugins.push_back(loader);
27 }
28
29 InformationManager::~InformationManager() {
30 for (auto b : blocks)
31 delete b.second;
32
33 for (auto f : functions)
34 delete f.second;
35
36 for (auto i : plugins)
37 delete i;
38 }
39
40 void InformationManager::reset(const std::string& filename) {
41 this->filename = filename;
42 disassembler.reset(createLLVMDisassembler(filename, this));
43 if (disassembler.get() != NULL)
44 disassembler.get()->start();
45 }
46
47 void InformationManager::load(const std::string& filename) {
48 QuaZip zip(filename.c_str());
49 QuaZipFile file(&zip);
50 QuaZipFileInfo info;
51
52 zip.open(QuaZip::mdUnzip);
53 tmpfile.reset(new QTemporaryFile());
54
55 {
56 LOG4CXX_INFO(logger, "Loading binary from archive");
57 zip.setCurrentFile("binary");
58 tmpfile->open();
59 file.open(QIODevice::ReadOnly);
60 QByteArray buffer;
61 while (!file.atEnd()) {
62 buffer = file.read(4096);
63 tmpfile->write(buffer);
64 }
65 tmpfile->flush();
66 file.close();
67 disassembler.reset(createLLVMDisassembler(tmpfile->fileName().toStdString(), this));
68 }
69
70 for (bool more = zip.goToFirstFile(); more; more = zip.goToNextFile()) {
71 zip.getCurrentFileInfo(&info);
72 file.open(QIODevice::ReadOnly);
73
74 if(info.name != "binary") {
75 QXmlStreamReader reader(&file);
76 assert(QXmlStreamReader::StartDocument == reader.readNext());
77 assert(QXmlStreamReader::StartElement == reader.readNext());
78 Function * fun = Function::deserialize(reader, this);
79 }
80 file.close();
81 }
82 }
83
84 void InformationManager::save(const std::string& filename) {
85 QuaZip zip(filename.c_str());
86 zip.open(QuaZip::mdCreate);
87 zip.setComment("FRIDA 0.0");
88 QuaZipFile outZipFile(&zip);
89
90 {
91 QFile binary(this->filename.c_str());
92 binary.open(QIODevice::ReadOnly);
93 QuaZipNewInfo zipinfo("binary");
94 zipinfo.setPermissions(static_cast<QFile::Permissions>(0x6444));
95 outZipFile.open(QIODevice::WriteOnly, zipinfo);
96 QByteArray buffer;
97 while (!binary.atEnd()) {
98 buffer = binary.read(4096);
99 outZipFile.write(buffer);
100 }
101 outZipFile.close();
102 }
103
104 for (auto funpair : functions) {
105 Function* fun = funpair.second;
106 QuaZipNewInfo zipinfo(fun->getName().c_str());
107 zipinfo.setPermissions(static_cast<QFile::Permissions>(0x6444));
108 outZipFile.open(QIODevice::WriteOnly, zipinfo);
109 QXmlStreamWriter stream(&outZipFile);
110 stream.setAutoFormatting(true);
111 stream.setAutoFormattingIndent(-1);
112 stream.writeStartDocument();
113
114 fun->serialize(stream);
115
116 stream.writeEndDocument();
117 outZipFile.close();
118 }
119
120 zip.close();
121 }
122
123
124 /* *******************************
125 * Accessors for the Functions map
126 */
127
128 Function* InformationManager::getFunction(uint64_t address) {
129 auto it = functions.find(address);
130 if (it != functions.end())
131 return it->second;
132 else
133 return NULL;
134 }
135
136 std::map<uint64_t, Function*>::const_iterator InformationManager::beginFunctions() {
137 return functions.begin();
138 }
139 std::map<uint64_t, Function*>::const_iterator InformationManager::endFunctions() {
140 return functions.end();
141 }
142
143
144 /* *********************************
145 * Accessors for the BasicBlocks map
146 */
147
148 BasicBlock* InformationManager::getBasicBlock(uint64_t address) {
149 auto it = blocks.find(address);
150 if (it != blocks.end())
151 return it->second;
152 else
153 return NULL;
154 }
155
156 std::map<uint64_t, BasicBlock*>::const_iterator InformationManager::beginBasicBlocks() {
157 return blocks.begin();
158 }
159 std::map<uint64_t, BasicBlock*>::const_iterator InformationManager::endBasicBlocks() {
160 return blocks.end();
161 }
162
163
164 /* *********************************
165 * Accessors for the Interpreter map
166 */
167
168 Interpreter* InformationManager::getInterpreter(const std::string& name) {
169 auto it = interpreters.find(name);
170 if (it != interpreters.end())
171 return it->second;
172 else
173 return NULL;
174 }
175
176 std::map<std::string, Interpreter*>::const_iterator InformationManager::beginInterpreters() {
177 return interpreters.begin();
178 }
179 std::map<std::string, Interpreter*>::const_iterator InformationManager::endInterpreters() {
180 return interpreters.end();
181 }
182
183
184 /* ********************************
185 * Factory methods for data classes
186 */
187
188 Function* InformationManager::newFunction(uint64_t address) {
189 Function* fun = new Function(address, false, this);
190 functions.insert(std::make_pair(address, fun));
191 return fun;
192 }
193
194 Function* InformationManager::newDynamicFunction(uint64_t address) {
195 Function* fun = new Function(address, true, this);
196 functions.insert(std::make_pair(address, fun));
197 return fun;
198 }
199
200 BasicBlock* InformationManager::newBasicBlock(uint64_t address) {
201 BasicBlock* block = new BasicBlock(address, this);
202 blocks.insert(std::make_pair(address, block));
203 return block;
204 }
205
206 Comment* InformationManager::newGlobalComment(uint64_t address) {
207 Comment* comment = new Comment(address, this);
208 comments.insert(std::make_pair(address, comment));
209 return comment;
210 }
211
212 Comment* InformationManager::newLocalComment(uint64_t address, Function* f) {
213 Comment* comment = new Comment(address, this);
214 comments.insert(std::make_pair(address, comment));
215 return comment;
216 }
217
218 void InformationManager::finishFunction(Function* fun) {
219 LOG4CXX_DEBUG(logger, "Finishing function " << fun->getName());
220 for (auto b : fun->blocks()) {
221 BasicBlock* bl = b.second;
222 blocks.insert(std::make_pair(bl->getStartAddress(), bl));
223 }
224 NewFunctionEvent event(fun->getStartAddress(), fun);
225 dispatch(&event);
226 }
227
228 void InformationManager::finishBasicBlock(BasicBlock*) {
229 }
230
231 void InformationManager::finnishComment(Comment* c) {
232 }
233
234 void InformationManager::deleteFunction(Function* f) {
235 functions.erase(f->getStartAddress());
236 delete f;
237 }
238
239 void InformationManager::deleteBasicBlock(BasicBlock* b) {
240 blocks.erase(b->getStartAddress());
241 delete b;
242 }
243
244 void InformationManager::deleteComment(Comment* c) {
245 auto range = comments.equal_range(c->getAddress());
246 for (auto it = range.first; it != range.second; ++it) {
247 if (it->second == c) {
248 comments.erase(it);
249 break;
250 }
251 }
252 delete c;
253 }