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