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