1 // copyright (c) 2020-2021 hors<horsicq@gmail.com>
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a copy
4 // of this software and associated documentation files (the "Software"), to deal
5 // in the Software without restriction, including without limitation the rights
6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 // copies of the Software, and to permit persons to whom the Software is
8 // furnished to do so, subject to the following conditions:
9
10 // The above copyright notice and this permission notice shall be included in all
11 // copies or substantial portions of the Software.
12
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19 // SOFTWARE.
20 //
21 #include "xformats.h"
22
XFormats(QObject * pParent)23 XFormats::XFormats(QObject *pParent) : QObject(pParent)
24 {
25
26 }
27
getMemoryMap(XBinary::FT fileType,QIODevice * pDevice,bool bIsImage,qint64 nModuleAddress)28 XBinary::_MEMORY_MAP XFormats::getMemoryMap(XBinary::FT fileType,QIODevice *pDevice,bool bIsImage,qint64 nModuleAddress)
29 {
30 XBinary::_MEMORY_MAP result={};
31
32 if(XBinary::checkFileType(XBinary::FT_BINARY,fileType))
33 {
34 XBinary binary(pDevice,bIsImage,nModuleAddress);
35 result=binary.getMemoryMap();
36 }
37 else if(XBinary::checkFileType(XBinary::FT_COM,fileType))
38 {
39 XCOM com(pDevice,bIsImage,nModuleAddress);
40 result=com.getMemoryMap();
41 }
42 else if(XBinary::checkFileType(XBinary::FT_MSDOS,fileType))
43 {
44 XMSDOS msdos(pDevice,bIsImage,nModuleAddress);
45 result=msdos.getMemoryMap();
46 }
47 else if(XBinary::checkFileType(XBinary::FT_NE,fileType))
48 {
49 XNE ne(pDevice,bIsImage,nModuleAddress);
50 result=ne.getMemoryMap();
51 }
52 else if(XBinary::checkFileType(XBinary::FT_LE,fileType))
53 {
54 XLE le(pDevice,bIsImage,nModuleAddress);
55 result=le.getMemoryMap();
56 }
57 else if(XBinary::checkFileType(XBinary::FT_PE,fileType))
58 {
59 XPE pe(pDevice,bIsImage,nModuleAddress);
60 result=pe.getMemoryMap();
61 }
62 else if(XBinary::checkFileType(XBinary::FT_ELF,fileType))
63 {
64 XELF elf(pDevice,bIsImage,nModuleAddress);
65 result=elf.getMemoryMap();
66 }
67 else if(XBinary::checkFileType(XBinary::FT_MACHO,fileType))
68 {
69 XMACH mach(pDevice,bIsImage,nModuleAddress);
70 result=mach.getMemoryMap();
71 }
72 #ifdef USE_DEX // TODO Check !!!
73 else if(XBinary::checkFileType(XBinary::FT_DEX,fileType))
74 {
75 XDEX dex(pDevice);
76 result=dex.getMemoryMap();
77 }
78 #endif
79 #ifdef USE_ARCHIVE
80 else if(XBinary::checkFileType(XBinary::FT_ZIP,fileType))
81 {
82 XZip zip(pDevice);
83 result=zip.getMemoryMap();
84 }
85 #endif
86 else
87 {
88 XBinary binary(pDevice,bIsImage,nModuleAddress);
89 result=binary.getMemoryMap();
90 }
91
92 return result;
93 }
94
getEntryPointAddress(XBinary::FT fileType,QIODevice * pDevice,bool bIsImage,qint64 nModuleAddress)95 qint64 XFormats::getEntryPointAddress(XBinary::FT fileType, QIODevice *pDevice, bool bIsImage, qint64 nModuleAddress)
96 {
97 // TODO pMemoryMap
98 qint64 nResult=0; // FT_DEX, FT_ZIP
99
100 if(XBinary::checkFileType(XBinary::FT_BINARY,fileType))
101 {
102 XBinary binary(pDevice,bIsImage,nModuleAddress);
103 nResult=binary.getEntryPointAddress();
104 }
105 else if(XBinary::checkFileType(XBinary::FT_COM,fileType))
106 {
107 XCOM com(pDevice,bIsImage,nModuleAddress);
108 nResult=com.getEntryPointAddress();
109 }
110 else if(XBinary::checkFileType(XBinary::FT_MSDOS,fileType))
111 {
112 XMSDOS msdos(pDevice,bIsImage,nModuleAddress);
113 nResult=msdos.getEntryPointAddress();
114 }
115 else if(XBinary::checkFileType(XBinary::FT_NE,fileType))
116 {
117 XNE ne(pDevice,bIsImage,nModuleAddress);
118 nResult=ne.getEntryPointAddress();
119 }
120 else if(XBinary::checkFileType(XBinary::FT_LE,fileType))
121 {
122 XLE le(pDevice,bIsImage,nModuleAddress);
123 nResult=le.getEntryPointAddress();
124 }
125 else if(XBinary::checkFileType(XBinary::FT_PE,fileType))
126 {
127 XPE pe(pDevice,bIsImage,nModuleAddress);
128 nResult=pe.getEntryPointAddress();
129 }
130 else if(XBinary::checkFileType(XBinary::FT_ELF,fileType))
131 {
132 XELF elf(pDevice,bIsImage,nModuleAddress);
133 nResult=elf.getEntryPointAddress();
134 }
135 else if(XBinary::checkFileType(XBinary::FT_MACHO,fileType))
136 {
137 XMACH mach(pDevice,bIsImage,nModuleAddress);
138 nResult=mach.getEntryPointAddress();
139 }
140 else
141 {
142 nResult=0;
143 }
144
145 return nResult;
146 }
147
getEntryPointOffset(XBinary::FT fileType,QIODevice * pDevice,bool bIsImage,qint64 nModuleAddress)148 qint64 XFormats::getEntryPointOffset(XBinary::FT fileType, QIODevice *pDevice, bool bIsImage, qint64 nModuleAddress)
149 {
150 qint64 nResult=0;
151
152 if(XBinary::checkFileType(XBinary::FT_BINARY,fileType))
153 {
154 XBinary binary(pDevice,bIsImage,nModuleAddress);
155 nResult=binary._getEntryPointOffset();
156 }
157 else if(XBinary::checkFileType(XBinary::FT_COM,fileType))
158 {
159 XCOM com(pDevice,bIsImage,nModuleAddress);
160 nResult=com._getEntryPointOffset();
161 }
162 else if(XBinary::checkFileType(XBinary::FT_MSDOS,fileType))
163 {
164 XMSDOS msdos(pDevice,bIsImage,nModuleAddress);
165 nResult=msdos._getEntryPointOffset();
166 }
167 else if(XBinary::checkFileType(XBinary::FT_NE,fileType))
168 {
169 XNE ne(pDevice,bIsImage,nModuleAddress);
170 nResult=ne._getEntryPointOffset();
171 }
172 else if(XBinary::checkFileType(XBinary::FT_LE,fileType))
173 {
174 XLE le(pDevice,bIsImage,nModuleAddress);
175 nResult=le._getEntryPointOffset();
176 }
177 else if(XBinary::checkFileType(XBinary::FT_PE,fileType))
178 {
179 XPE pe(pDevice,bIsImage,nModuleAddress);
180 nResult=pe._getEntryPointOffset();
181 }
182 else if(XBinary::checkFileType(XBinary::FT_ELF,fileType))
183 {
184 XELF elf(pDevice,bIsImage,nModuleAddress);
185 nResult=elf._getEntryPointOffset();
186 }
187 else if(XBinary::checkFileType(XBinary::FT_MACHO,fileType))
188 {
189 XMACH mach(pDevice,bIsImage,nModuleAddress);
190 nResult=mach._getEntryPointOffset();
191 }
192 else
193 {
194 nResult=0;
195 }
196
197 return nResult;
198 }
199
isBigEndian(XBinary::FT fileType,QIODevice * pDevice,bool bIsImage,qint64 nModuleAddress)200 bool XFormats::isBigEndian(XBinary::FT fileType, QIODevice *pDevice, bool bIsImage, qint64 nModuleAddress)
201 {
202 bool bResult=false;
203
204 if(XBinary::checkFileType(XBinary::FT_BINARY,fileType))
205 {
206 XBinary binary(pDevice,bIsImage,nModuleAddress);
207 bResult=binary.isBigEndian();
208 }
209 else if(XBinary::checkFileType(XBinary::FT_COM,fileType))
210 {
211 XCOM com(pDevice,bIsImage,nModuleAddress);
212 bResult=com.isBigEndian();
213 }
214 else if(XBinary::checkFileType(XBinary::FT_MSDOS,fileType))
215 {
216 XMSDOS msdos(pDevice,bIsImage,nModuleAddress);
217 bResult=msdos.isBigEndian();
218 }
219 else if(XBinary::checkFileType(XBinary::FT_NE,fileType))
220 {
221 XNE ne(pDevice,bIsImage,nModuleAddress);
222 bResult=ne.isBigEndian();
223 }
224 else if(XBinary::checkFileType(XBinary::FT_LE,fileType))
225 {
226 XLE le(pDevice,bIsImage,nModuleAddress);
227 bResult=le.isBigEndian();
228 }
229 else if(XBinary::checkFileType(XBinary::FT_PE,fileType))
230 {
231 XPE pe(pDevice,bIsImage,nModuleAddress);
232 bResult=pe.isBigEndian();
233 }
234 else if(XBinary::checkFileType(XBinary::FT_ELF,fileType))
235 {
236 XELF elf(pDevice,bIsImage,nModuleAddress);
237 bResult=elf.isBigEndian();
238 }
239 else if(XBinary::checkFileType(XBinary::FT_MACHO,fileType))
240 {
241 XMACH mach(pDevice,bIsImage,nModuleAddress);
242 bResult=mach.isBigEndian();
243 }
244 #ifdef USE_DEX
245 else if(XBinary::checkFileType(XBinary::FT_DEX,fileType))
246 {
247 XDEX dex(pDevice);
248 bResult=dex.isBigEndian();
249 }
250 #endif
251 #ifdef USE_ARCHIVE
252 else if(XBinary::checkFileType(XBinary::FT_ZIP,fileType))
253 {
254 XZip zip(pDevice);
255 bResult=zip.isBigEndian();
256 }
257 #endif
258 else
259 {
260 bResult=false;
261 }
262
263 return bResult;
264 }
265
isSigned(XBinary::FT fileType,QIODevice * pDevice,bool bIsImage,qint64 nModuleAddress)266 bool XFormats::isSigned(XBinary::FT fileType, QIODevice *pDevice, bool bIsImage, qint64 nModuleAddress)
267 {
268 bool bResult=false;
269
270 if(XBinary::checkFileType(XBinary::FT_BINARY,fileType))
271 {
272 XBinary binary(pDevice,bIsImage,nModuleAddress);
273 bResult=binary.isSigned();
274 }
275 else if(XBinary::checkFileType(XBinary::FT_COM,fileType))
276 {
277 XCOM com(pDevice,bIsImage,nModuleAddress);
278 bResult=com.isSigned();
279 }
280 else if(XBinary::checkFileType(XBinary::FT_MSDOS,fileType))
281 {
282 XMSDOS msdos(pDevice,bIsImage,nModuleAddress);
283 bResult=msdos.isSigned();
284 }
285 else if(XBinary::checkFileType(XBinary::FT_NE,fileType))
286 {
287 XNE ne(pDevice,bIsImage,nModuleAddress);
288 bResult=ne.isSigned();
289 }
290 else if(XBinary::checkFileType(XBinary::FT_LE,fileType))
291 {
292 XLE le(pDevice,bIsImage,nModuleAddress);
293 bResult=le.isSigned();
294 }
295 else if(XBinary::checkFileType(XBinary::FT_PE,fileType))
296 {
297 XPE pe(pDevice,bIsImage,nModuleAddress);
298 bResult=pe.isSigned();
299 }
300 else if(XBinary::checkFileType(XBinary::FT_ELF,fileType))
301 {
302 XELF elf(pDevice,bIsImage,nModuleAddress);
303 bResult=elf.isSigned();
304 }
305 else if(XBinary::checkFileType(XBinary::FT_MACHO,fileType))
306 {
307 XMACH mach(pDevice,bIsImage,nModuleAddress);
308 bResult=mach.isSigned();
309 }
310 #ifdef USE_DEX
311 else if(XBinary::checkFileType(XBinary::FT_DEX,fileType))
312 {
313 XDEX dex(pDevice);
314 bResult=dex.isSigned();
315 }
316 #endif
317 #ifdef USE_ARCHIVE
318 else if(XBinary::checkFileType(XBinary::FT_ZIP,fileType))
319 {
320 XZip zip(pDevice);
321 bResult=zip.isSigned();
322 }
323 #endif
324 else
325 {
326 bResult=false;
327 }
328
329 return bResult;
330 }
331
getSignOS(XBinary::FT fileType,QIODevice * pDevice,bool bIsImage,qint64 nModuleAddress)332 XBinary::OFFSETSIZE XFormats::getSignOS(XBinary::FT fileType, QIODevice *pDevice, bool bIsImage, qint64 nModuleAddress)
333 {
334 XBinary::OFFSETSIZE result={};
335
336 if(XBinary::checkFileType(XBinary::FT_BINARY,fileType))
337 {
338 XBinary binary(pDevice,bIsImage,nModuleAddress);
339 result=binary.getSignOS();
340 }
341 else if(XBinary::checkFileType(XBinary::FT_COM,fileType))
342 {
343 XCOM com(pDevice,bIsImage,nModuleAddress);
344 result=com.getSignOS();
345 }
346 else if(XBinary::checkFileType(XBinary::FT_MSDOS,fileType))
347 {
348 XMSDOS msdos(pDevice,bIsImage,nModuleAddress);
349 result=msdos.getSignOS();
350 }
351 else if(XBinary::checkFileType(XBinary::FT_NE,fileType))
352 {
353 XNE ne(pDevice,bIsImage,nModuleAddress);
354 result=ne.getSignOS();
355 }
356 else if(XBinary::checkFileType(XBinary::FT_LE,fileType))
357 {
358 XLE le(pDevice,bIsImage,nModuleAddress);
359 result=le.getSignOS();
360 }
361 else if(XBinary::checkFileType(XBinary::FT_PE,fileType))
362 {
363 XPE pe(pDevice,bIsImage,nModuleAddress);
364 result=pe.getSignOS();
365 }
366 else if(XBinary::checkFileType(XBinary::FT_ELF,fileType))
367 {
368 XELF elf(pDevice,bIsImage,nModuleAddress);
369 result=elf.getSignOS();
370 }
371 else if(XBinary::checkFileType(XBinary::FT_MACHO,fileType))
372 {
373 XMACH mach(pDevice,bIsImage,nModuleAddress);
374 result=mach.getSignOS();
375 }
376 #ifdef USE_DEX
377 else if(XBinary::checkFileType(XBinary::FT_DEX,fileType))
378 {
379 XDEX dex(pDevice);
380 result=dex.getSignOS();
381 }
382 #endif
383 #ifdef USE_ARCHIVE
384 else if(XBinary::checkFileType(XBinary::FT_ZIP,fileType))
385 {
386 XZip zip(pDevice);
387 result=zip.getSignOS();
388 }
389 #endif
390
391 return result;
392 }
393
getSignOS(QString sFileName)394 XBinary::OFFSETSIZE XFormats::getSignOS(QString sFileName)
395 {
396 XBinary::OFFSETSIZE result={};
397
398 QFile file;
399
400 file.setFileName(sFileName);
401
402 if(file.open(QIODevice::ReadOnly))
403 {
404 result=getSignOS(XBinary::getPrefFileType(&file,true),&file);
405
406 file.close();
407 }
408
409 return result;
410 }
411
isSigned(QString sFileName)412 bool XFormats::isSigned(QString sFileName)
413 {
414 bool bResult=false;
415
416 QFile file;
417
418 file.setFileName(sFileName);
419
420 if(file.open(QIODevice::ReadOnly))
421 {
422 bResult=isSigned(XBinary::getPrefFileType(&file,true),&file);
423
424 file.close();
425 }
426
427 return bResult;
428 }
429
getSymbolRecords(XBinary::FT fileType,QIODevice * pDevice,bool bIsImage,qint64 nModuleAddress,XBinary::SYMBOL_TYPE symBolType)430 QList<XBinary::SYMBOL_RECORD> XFormats::getSymbolRecords(XBinary::FT fileType, QIODevice *pDevice, bool bIsImage, qint64 nModuleAddress, XBinary::SYMBOL_TYPE symBolType)
431 {
432 QList<XBinary::SYMBOL_RECORD> listResult;
433
434 if(XBinary::checkFileType(XBinary::FT_BINARY,fileType))
435 {
436 XBinary binary(pDevice,bIsImage,nModuleAddress);
437
438 XBinary::_MEMORY_MAP memoryMap=binary.getMemoryMap();
439 listResult=binary.getSymbolRecords(&memoryMap,symBolType);
440 }
441 else if(XBinary::checkFileType(XBinary::FT_COM,fileType))
442 {
443 XCOM com(pDevice,bIsImage,nModuleAddress);
444
445 XBinary::_MEMORY_MAP memoryMap=com.getMemoryMap();
446 listResult=com.getSymbolRecords(&memoryMap,symBolType);
447 }
448 else if(XBinary::checkFileType(XBinary::FT_MSDOS,fileType))
449 {
450 XMSDOS msdos(pDevice,bIsImage,nModuleAddress);
451
452 XBinary::_MEMORY_MAP memoryMap=msdos.getMemoryMap();
453 listResult=msdos.getSymbolRecords(&memoryMap,symBolType);
454 }
455 else if(XBinary::checkFileType(XBinary::FT_NE,fileType))
456 {
457 XNE ne(pDevice,bIsImage,nModuleAddress);
458
459 XBinary::_MEMORY_MAP memoryMap=ne.getMemoryMap();
460 listResult=ne.getSymbolRecords(&memoryMap,symBolType);
461 }
462 else if(XBinary::checkFileType(XBinary::FT_LE,fileType))
463 {
464 XLE le(pDevice,bIsImage,nModuleAddress);
465
466 XBinary::_MEMORY_MAP memoryMap=le.getMemoryMap();
467 listResult=le.getSymbolRecords(&memoryMap,symBolType);
468 }
469 else if(XBinary::checkFileType(XBinary::FT_PE,fileType))
470 {
471 XPE pe(pDevice,bIsImage,nModuleAddress);
472
473 XBinary::_MEMORY_MAP memoryMap=pe.getMemoryMap();
474 listResult=pe.getSymbolRecords(&memoryMap,symBolType);
475 }
476 else if(XBinary::checkFileType(XBinary::FT_ELF,fileType))
477 {
478 XELF elf(pDevice,bIsImage,nModuleAddress);
479
480 XBinary::_MEMORY_MAP memoryMap=elf.getMemoryMap();
481 listResult=elf.getSymbolRecords(&memoryMap,symBolType);
482 }
483 else if(XBinary::checkFileType(XBinary::FT_MACHO,fileType))
484 {
485 XMACH mach(pDevice,bIsImage,nModuleAddress);
486
487 XBinary::_MEMORY_MAP memoryMap=mach.getMemoryMap();
488 listResult=mach.getSymbolRecords(&memoryMap,symBolType);
489 }
490 #ifdef USE_DEX
491 else if(XBinary::checkFileType(XBinary::FT_DEX,fileType))
492 {
493 XDEX dex(pDevice);
494
495 XBinary::_MEMORY_MAP memoryMap=dex.getMemoryMap();
496 listResult=dex.getSymbolRecords(&memoryMap,symBolType);
497 }
498 #endif
499 #ifdef USE_ARCHIVE
500 else if(XBinary::checkFileType(XBinary::FT_ZIP,fileType))
501 {
502 XZip zip(pDevice);
503
504 XBinary::_MEMORY_MAP memoryMap=zip.getMemoryMap();
505 listResult=zip.getSymbolRecords(&memoryMap,symBolType);
506 }
507 #endif
508
509 return listResult;
510 }
511
512 #ifdef QT_GUI_LIB
setFileTypeComboBox(QComboBox * pComboBox,QList<XBinary::FT> * pListFileTypes,XBinary::FT fileType)513 XBinary::FT XFormats::setFileTypeComboBox(QComboBox *pComboBox, QList<XBinary::FT> *pListFileTypes, XBinary::FT fileType)
514 {
515 #if QT_VERSION >= 0x050300
516 const QSignalBlocker block(pComboBox);
517 #else
518 const bool bBlocked1=pComboBox->blockSignals(true);
519 #endif
520
521 pComboBox->clear();
522
523 int nNumberOfListTypes=pListFileTypes->count();
524
525 for(int i=0;i<nNumberOfListTypes;i++)
526 {
527 XBinary::FT fileType=pListFileTypes->at(i);
528 pComboBox->addItem(XBinary::fileTypeIdToString(fileType),fileType);
529 }
530
531 if(nNumberOfListTypes)
532 {
533 if(fileType==XBinary::FT_UNKNOWN)
534 {
535 if(pComboBox->itemData(nNumberOfListTypes-1).toUInt()!=XBinary::FT_COM)
536 {
537 pComboBox->setCurrentIndex(nNumberOfListTypes-1);
538 }
539 }
540 else
541 {
542 int nNumberOfItems=pComboBox->count();
543
544 for(int i=0;i<nNumberOfItems;i++)
545 {
546 if(pComboBox->itemData(i).toUInt()==fileType)
547 {
548 pComboBox->setCurrentIndex(i);
549
550 break;
551 }
552 }
553 }
554 }
555
556 #if QT_VERSION < 0x050300
557 pComboBox->blockSignals(bBlocked1);
558 #endif
559
560 return (XBinary::FT)(pComboBox->currentData().toUInt());
561 }
562 #endif
563 #ifdef QT_GUI_LIB
setEndianessComboBox(QComboBox * pComboBox,bool bIsBigEndian)564 bool XFormats::setEndianessComboBox(QComboBox *pComboBox, bool bIsBigEndian)
565 {
566 #if QT_VERSION >= 0x050300
567 const QSignalBlocker blocker(pComboBox);
568 #else
569 const bool bBlocked1=pComboBox->blockSignals(true);
570 #endif
571
572 bool bResult=bIsBigEndian;
573
574 pComboBox->clear();
575
576 pComboBox->addItem("LE",false);
577 pComboBox->addItem("BE",true);
578
579 if(bIsBigEndian)
580 {
581 pComboBox->setCurrentIndex(0);
582 }
583
584 #if QT_VERSION < 0x050300
585 pComboBox->blockSignals(bBlocked1);
586 #endif
587
588 return bResult;
589 }
590 #endif
591