1 // copyright (c) 2017-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 "xbinary.h"
22 
23 const double XBinary::D_ENTROPY_THRESHOLD=6.5;
24 
XBinary(QIODevice * pDevice,bool bIsImage,qint64 nModuleAddress)25 XBinary::XBinary(QIODevice *pDevice, bool bIsImage, qint64 nModuleAddress)
26 {
27     g_pReadWriteMutex=nullptr;
28 
29     setDevice(pDevice);
30     setIsImage(bIsImage);
31     XBinary::setBaseAddress(0);
32     setModuleAddress(nModuleAddress);
33     setEndianness(false); // LE
34     XBinary::setEntryPointOffset(0);
35     setSearchProcessEnable(true);
36     setDumpProcessEnable(true);
37     setEntropyProcessEnable(true);
38     setHashProcessEnable(true);
39     setProcessSignalsEnable(true);
40     setMode(MODE_UNKNOWN);
41     setFileType(FT_BINARY);
42     setArch("NOEXEC");
43     setVersion("");
44     setType(TYPE_UNKNOWN);
45 
46     g_bLog=false;
47 }
48 
setDevice(QIODevice * pDevice)49 void XBinary::setDevice(QIODevice *pDevice)
50 {
51     g_pDevice=pDevice;
52 
53     if(g_pDevice)
54     {
55         if(g_pReadWriteMutex) g_pReadWriteMutex->lock();
56 
57         g_nSize=g_pDevice->size();
58 
59         if(g_pReadWriteMutex) g_pReadWriteMutex->unlock();
60     }
61 }
62 
setReadWriteMutex(QMutex * pReadWriteMutex)63 void XBinary::setReadWriteMutex(QMutex *pReadWriteMutex)
64 {
65     g_pReadWriteMutex=pReadWriteMutex;
66 }
67 
safeReadData(QIODevice * pDevice,qint64 nPos,char * pData,qint64 nMaxLen)68 qint64 XBinary::safeReadData(QIODevice *pDevice, qint64 nPos, char *pData, qint64 nMaxLen)
69 {
70     qint64 nResult=0;
71 
72     if(g_pReadWriteMutex) g_pReadWriteMutex->lock();
73 
74     if(pDevice->seek(nPos))
75     {
76         nResult=pDevice->read(pData,nMaxLen);
77     }
78 
79     if(g_pReadWriteMutex) g_pReadWriteMutex->unlock();
80 
81     return nResult;
82 }
83 
safeWriteData(QIODevice * pDevice,qint64 nPos,const char * pData,qint64 nLen)84 qint64 XBinary::safeWriteData(QIODevice *pDevice, qint64 nPos, const char *pData, qint64 nLen)
85 {
86     qint64 nResult=0;
87 
88     if(g_pReadWriteMutex) g_pReadWriteMutex->lock();
89 
90     if(pDevice->seek(nPos))
91     {
92         nResult=pDevice->write(pData,nLen);
93     }
94 
95     if(g_pReadWriteMutex) g_pReadWriteMutex->unlock();
96 
97     return nResult;
98 }
99 
getSize()100 qint64 XBinary::getSize()
101 {
102     return g_nSize;
103 }
104 
getSize(QIODevice * pDevice)105 qint64 XBinary::getSize(QIODevice *pDevice)
106 {
107     XBinary binary(pDevice);
108 
109     return binary.getSize();
110 }
111 
getSize(QString sFileName)112 qint64 XBinary::getSize(QString sFileName)
113 {
114     qint64 nResult=0;
115 
116     QFile file;
117 
118     file.setFileName(sFileName);
119 
120     if(file.open(QIODevice::ReadOnly))
121     {
122         nResult=getSize(&file);
123 
124         file.close();
125     }
126 
127     return nResult;
128 }
129 
setMode(XBinary::MODE mode)130 void XBinary::setMode(XBinary::MODE mode)
131 {
132     g_mode=mode;
133 }
134 
getMode()135 XBinary::MODE XBinary::getMode()
136 {
137     return g_mode;
138 }
139 
setType(int nType)140 void XBinary::setType(int nType)
141 {
142     g_nType=nType;
143 }
144 
getType()145 int XBinary::getType()
146 {
147     return g_nType;
148 }
149 
typeIdToString(int nType)150 QString XBinary::typeIdToString(int nType)
151 {
152     QString sResult="Unknown"; // mb TODO translate
153 
154     switch(nType)
155     {
156         case TYPE_UNKNOWN:      sResult=QString("Unknown");     break; // mb TODO translate
157     }
158 
159     return sResult;
160 }
161 
getTypeAsString()162 QString XBinary::getTypeAsString()
163 {
164     return typeIdToString(getType());
165 }
166 
setFileType(XBinary::FT fileType)167 void XBinary::setFileType(XBinary::FT fileType)
168 {
169     g_fileType=fileType;
170 }
171 
getFileType()172 XBinary::FT XBinary::getFileType()
173 {
174     return g_fileType;
175 }
176 
modeIdToString(XBinary::MODE mode)177 QString XBinary::modeIdToString(XBinary::MODE mode)
178 {
179     QString sResult="Unknown"; // mb TODO translate
180 
181     switch(mode)
182     {
183         case MODE_UNKNOWN:          sResult=QString("Unknown");     break; // mb TODO translate
184         case MODE_DATA:             sResult=QString("Data");        break; // mb TODO translate
185         case MODE_8:                sResult=QString("8");           break;
186         case MODE_16:               sResult=QString("16");          break;
187         case MODE_16SEG:            sResult=QString("16SEG");       break;
188         case MODE_32:               sResult=QString("32");          break;
189         case MODE_64:               sResult=QString("64");          break;
190     }
191 
192     return sResult;
193 }
194 
endiannessToString(bool bIsBigEndian)195 QString XBinary::endiannessToString(bool bIsBigEndian)
196 {
197     QString sResult;
198 
199     if(bIsBigEndian)
200     {
201         sResult="BE";
202     }
203     else
204     {
205         sResult="LE";
206     }
207 
208     return sResult;
209 }
210 
setArch(QString sArch)211 void XBinary::setArch(QString sArch)
212 {
213     g_sArch=sArch;
214 }
215 
getArch()216 QString XBinary::getArch()
217 {
218     return g_sArch;
219 }
220 
isSigned()221 bool XBinary::isSigned()
222 {
223     return false;
224 }
225 
getSignOS()226 XBinary::OFFSETSIZE XBinary::getSignOS()
227 {
228     OFFSETSIZE result={};
229 
230     return result;
231 }
232 
setEndianness(bool bIsBigEndian)233 void XBinary::setEndianness(bool bIsBigEndian)
234 {
235     g_bIsBigEndian=bIsBigEndian;
236 }
237 
isPacked(double dEntropy)238 bool XBinary::isPacked(double dEntropy)
239 {
240     return (dEntropy>=D_ENTROPY_THRESHOLD);
241 }
242 
random8()243 quint8 XBinary::random8()
244 {
245     return (quint8)random16();
246 }
247 
random16()248 quint16 XBinary::random16()
249 {
250     quint16 nResult=0;
251 
252 #if (QT_VERSION_MAJOR>=5)&&(QT_VERSION_MINOR>=10)
253     nResult=(quint16)(QRandomGenerator::global()->generate());
254 #elif (QT_VERSION_MAJOR>=6)
255     nResult=(quint16)(QRandomGenerator::global()->generate());
256 #else
257     static quint32 nSeed=0;
258 
259     if(!nSeed)
260     {
261         quint32 nRValue=QDateTime::currentMSecsSinceEpoch()&0xFFFFFFFF;
262 
263         nSeed^=nRValue;
264         qsrand(nSeed);
265     }
266     nResult=(quint16)qrand();
267 #endif
268 
269     return nResult;
270 }
271 
random32()272 quint32 XBinary::random32()
273 {
274     quint16 nValue1=random16();
275     quint16 nValue2=random16();
276 
277     return (nValue1<<16)+nValue2;
278 }
279 
random64()280 quint64 XBinary::random64()
281 {
282     quint64 nVal1=random32();
283     quint64 nVal2=random32();
284 
285     nVal1=nVal1<<32;
286 
287     return nVal1+nVal2;
288 }
289 
random(quint64 nLimit)290 quint64 XBinary::random(quint64 nLimit)
291 {
292     quint64 nResult=0;
293 
294     if(nLimit)
295     {
296         nResult=(random64())%nLimit;
297     }
298 
299     return nResult;
300 }
301 
fileTypeIdToString(XBinary::FT fileType)302 QString XBinary::fileTypeIdToString(XBinary::FT fileType)
303 {
304     QString sResult="Unknown"; // mb TODO translate
305 
306     switch(fileType)
307     {
308         case FT_UNKNOWN:            sResult=QString("Unknown");         break; // mb TODO translate
309         case FT_BINARY:             sResult=QString("Binary");          break;
310         case FT_BINARY16:           sResult=QString("Binary16");        break;
311         case FT_BINARY32:           sResult=QString("Binary32");        break;
312         case FT_BINARY64:           sResult=QString("Binary64");        break;
313         case FT_COM:                sResult=QString("COM");             break;
314         case FT_MSDOS:              sResult=QString("MSDOS");           break;
315         case FT_NE:                 sResult=QString("NE");              break;
316         case FT_LE:                 sResult=QString("LE");              break;
317         case FT_LX:                 sResult=QString("LX");              break;
318         case FT_PE:                 sResult=QString("PE");              break;
319         case FT_PE32:               sResult=QString("PE32");            break;
320         case FT_PE64:               sResult=QString("PE64");            break;
321         case FT_ELF:                sResult=QString("ELF");             break;
322         case FT_ELF32:              sResult=QString("ELF32");           break;
323         case FT_ELF64:              sResult=QString("ELF64");           break;
324         case FT_MACHO:              sResult=QString("Mach-O");          break;
325         case FT_MACHO32:            sResult=QString("Mach-O32");        break;
326         case FT_MACHO64:            sResult=QString("Mach-O64");        break;
327         // Extra
328         case FT_ZIP:                sResult=QString("ZIP");             break;
329         case FT_CAB:                sResult=QString("CAB");             break;
330         case FT_RAR:                sResult=QString("RAR");             break;
331         case FT_7Z:                 sResult=QString("7Z");              break;
332         case FT_MACHOFAT:           sResult=QString("Mach-O FAT");      break;
333         case FT_PNG:                sResult=QString("PNG");             break;
334         case FT_JPEG:               sResult=QString("JPEG");            break;
335         case FT_GIF:                sResult=QString("GIF");             break;
336         case FT_TIFF:               sResult=QString("TIFF");            break;
337         case FT_DEX:                sResult=QString("DEX");             break;
338         case FT_ANDROIDASRC:        sResult=QString("Android ASRC");    break;
339         case FT_ANDROIDXML:         sResult=QString("Android XML");     break;
340         case FT_APK:                sResult=QString("APK");             break;
341         case FT_JAR:                sResult=QString("JAR");             break;
342         case FT_IPA:                sResult=QString("IPA");             break;
343         case FT_TEXT:               sResult=tr("Text");                 break;
344         case FT_PLAINTEXT:          sResult=QString("Plain Text");      break; // mb TODO translate
345         case FT_UTF8:               sResult=QString("UTF8");            break;
346         case FT_UNICODE:            sResult=QString("Unicode");         break;
347         case FT_UNICODE_LE:         sResult=QString("Unicode LE");      break;
348         case FT_UNICODE_BE:         sResult=QString("Unicode BE");      break;
349         case FT_DOCUMENT:           sResult=tr("Document");             break;
350         case FT_IMAGE:              sResult=tr("Image");                break;
351         case FT_ARCHIVE:            sResult=tr("Archive");              break;
352     }
353 
354     return sResult;
355 }
356 
convertFileName(QString sFileName)357 QString XBinary::convertFileName(QString sFileName) // TODO Check
358 {
359 #ifdef Q_OS_MAC // Old Qt(4.X)
360     //    if(sFileName.startsWith("/.file/id="))
361     //    {
362     //        CFStringRef relCFStringRef =
363     //            CFStringCreateWithCString(
364     //                kCFAllocatorDefault,
365     //                sFileName.toUtf8().constData(),
366     //                kCFStringEncodingUTF8
367     //            );
368     //    CFURLRef relCFURL =
369     //        CFURLCreateWithFileSystemPath(
370     //            kCFAllocatorDefault,
371     //            relCFStringRef,
372     //            kCFURLPOSIXPathStyle,
373     //            false // isDirectory
374     //        );
375     //    CFErrorRef error=0;
376     //    CFURLRef absCFURL =
377     //    CFURLCreateFilePathURL(
378     //            kCFAllocatorDefault,
379     //            relCFURL,
380     //            &error
381     //        );
382     //    if(!error)
383     //    {
384     //        static const CFIndex maxAbsPathCStrBufLen=4096;
385     //        char absPathCStr[maxAbsPathCStrBufLen];
386     //        if(CFURLGetFileSystemRepresentation(
387     //                absCFURL,
388     //                true, // resolveAgainstBase
389     //                reinterpret_cast<UInt8 *>(&absPathCStr[0] ),
390     //                maxAbsPathCStrBufLen
391     //            ))
392     //            {
393     //            sFileName=QString(absPathCStr);
394     //            }
395     //        }
396     //        CFRelease(absCFURL);
397     //        CFRelease(relCFURL);
398     //        CFRelease(relCFStringRef);
399     //    }
400 #endif
401 
402     QFileInfo fiLink(sFileName);
403 
404     if(fiLink.isSymLink())
405     {
406         sFileName=fiLink.symLinkTarget();
407     }
408 
409     return sFileName;
410 }
411 
convertPathName(QString sPathName)412 QString XBinary::convertPathName(QString sPathName)
413 {
414     QString sResult=sPathName;
415 
416     // TODO more
417     if(sPathName.contains("$app"))
418     {
419         sResult.replace("$app",QCoreApplication::applicationDirPath());
420         sResult.replace("/",QDir::separator());
421     }
422 
423     if(sPathName.contains("$data"))
424     {
425 #ifdef Q_OS_MAC
426         sResult.replace("$data",QCoreApplication::applicationDirPath()+"/../Resources");
427 #else
428         sResult.replace("$data",QCoreApplication::applicationDirPath());
429 #endif
430         sResult.replace("/",QDir::separator());
431     }
432 
433     return sResult;
434 }
435 
getOsAnsiString(qint64 nOffset,qint64 nSize)436 XBinary::OS_ANSISTRING XBinary::getOsAnsiString(qint64 nOffset, qint64 nSize)
437 {
438     OS_ANSISTRING result={};
439 
440     result.nOffset=nOffset;
441     result.nSize=nSize;
442     result.sAnsiString=read_ansiString(nOffset,nSize);
443 
444     return result;
445 }
446 
findFiles(QString sDirectoryName,XBinary::FFOPTIONS * pFFOption,qint32 nLevel)447 void XBinary::findFiles(QString sDirectoryName, XBinary::FFOPTIONS *pFFOption, qint32 nLevel)
448 {
449     *(pFFOption->pnNumberOfFiles)=pFFOption->pListFileNames->count();
450 
451     if(!(*pFFOption->pbIsStop))
452     {
453         QFileInfo fi(sDirectoryName);
454 
455         if(fi.isFile())
456         {
457             pFFOption->pListFileNames->append(fi.absoluteFilePath());
458         }
459         else if(fi.isDir()&&((pFFOption->bSubdirectories)||(nLevel==0)))
460         {
461             QDir dir(sDirectoryName);
462 
463             QFileInfoList eil=dir.entryInfoList();
464 
465             int nNumberOfFiles=eil.count();
466 
467             for(int i=0; (i<nNumberOfFiles)&&(!(*(pFFOption->pbIsStop))); i++)
468             {
469                 QString sFN=eil.at(i).fileName();
470 
471                 if((sFN!=".")&&(sFN!=".."))
472                 {
473                     findFiles(eil.at(i).absoluteFilePath(),pFFOption,nLevel+1);
474                 }
475             }
476         }
477     }
478 }
479 
findFiles(QString sDirectoryName,QList<QString> * pListFileNames)480 void XBinary::findFiles(QString sDirectoryName, QList<QString> *pListFileNames)
481 {
482     QFileInfo fi(sDirectoryName);
483 
484     if(fi.isFile())
485     {
486         pListFileNames->append(fi.absoluteFilePath());
487     }
488     else if(fi.isDir())
489     {
490         QDir dir(sDirectoryName);
491 
492         QFileInfoList eil=dir.entryInfoList();
493 
494         int nNumberOfFiles=eil.count();
495 
496         for(int i=0;i<nNumberOfFiles;i++)
497         {
498             QString sFN=eil.at(i).fileName();
499 
500             if((sFN!=".")&&(sFN!=".."))
501             {
502                 findFiles(eil.at(i).absoluteFilePath(),pListFileNames);
503             }
504         }
505     }
506 }
507 
regExp(QString sRegExp,QString sString,int nIndex)508 QString XBinary::regExp(QString sRegExp, QString sString, int nIndex)
509 {
510     QString sResult;
511 #if (QT_VERSION_MAJOR<5)
512     QRegExp rxString(sRegExp);
513     rxString.indexIn(sString);
514 
515     QStringList list=rxString.capturedTexts();
516 
517     if(list.count()>nIndex)
518     {
519         sResult=list.at(nIndex);
520     }
521 #else
522     QRegularExpression rxString(sRegExp);
523     QRegularExpressionMatch matchString=rxString.match(sString);
524 
525     if(matchString.hasMatch())
526     {
527         sResult=matchString.captured(nIndex);
528     }
529 #endif
530 
531     return sResult;
532 }
533 
isRegExpPresent(QString sRegExp,QString sString)534 bool XBinary::isRegExpPresent(QString sRegExp, QString sString)
535 {
536     return (regExp(sRegExp,sString,0)!="");
537 }
538 
read_array(qint64 nOffset,char * pBuffer,qint64 nMaxSize)539 qint64 XBinary::read_array(qint64 nOffset, char *pBuffer, qint64 nMaxSize)
540 {
541     qint64 nResult=0;
542 
543     nResult=safeReadData(g_pDevice,nOffset,pBuffer,nMaxSize);  // Check for read large files
544 
545     return nResult;
546 }
547 
read_array(qint64 nOffset,qint64 nSize)548 QByteArray XBinary::read_array(qint64 nOffset, qint64 nSize)
549 {
550     QByteArray baResult;
551 
552     XBinary::OFFSETSIZE offsetSize=convertOffsetAndSize(nOffset,nSize);
553 
554     if(offsetSize.nOffset!=-1)
555     {
556         baResult.resize((qint32)offsetSize.nSize);
557 
558         qint64 nBytes=read_array(offsetSize.nOffset,baResult.data(),offsetSize.nSize);
559 
560         if(offsetSize.nSize!=nBytes)
561         {
562             baResult.resize((qint32)nBytes);
563         }
564     }
565 
566     return baResult;
567 }
568 
write_array(qint64 nOffset,char * pBuffer,qint64 nMaxSize)569 qint64 XBinary::write_array(qint64 nOffset, char *pBuffer, qint64 nMaxSize)
570 {
571     qint64 nResult=0;
572 
573     qint64 _nTotalSize=getSize();
574 
575     if((nMaxSize<=(_nTotalSize-nOffset))&&(nOffset>=0))
576     {
577         nResult=safeWriteData(g_pDevice,nOffset,pBuffer,nMaxSize);
578     }
579 
580     return nResult;
581 }
582 
read_array(QIODevice * pDevice,qint64 nOffset,qint64 nSize)583 QByteArray XBinary::read_array(QIODevice *pDevice, qint64 nOffset, qint64 nSize)
584 {
585     XBinary binary(pDevice);
586 
587     return binary.read_array(nOffset,nSize);
588 }
589 
read_array(QIODevice * pDevice,qint64 nOffset,char * pBuffer,qint64 nSize)590 qint64 XBinary::read_array(QIODevice *pDevice, qint64 nOffset, char *pBuffer, qint64 nSize)
591 {
592     XBinary binary(pDevice);
593 
594     return binary.read_array(nOffset,pBuffer,nSize);
595 }
596 
read_uint8(qint64 nOffset)597 quint8 XBinary::read_uint8(qint64 nOffset)
598 {
599     quint8 result=0;
600 
601     read_array(nOffset,(char *)(&result),1);
602 
603     return result;
604 }
605 
read_int8(qint64 nOffset)606 qint8 XBinary::read_int8(qint64 nOffset)
607 {
608     quint8 result=0;
609 
610     read_array(nOffset,(char *)(&result),1);
611 
612     return (qint8)result;
613 }
614 
read_uint16(qint64 nOffset,bool bIsBigEndian)615 quint16 XBinary::read_uint16(qint64 nOffset, bool bIsBigEndian)
616 {
617     quint16 result=0;
618 
619     read_array(nOffset,(char *)(&result),2);
620 
621     if(bIsBigEndian)
622     {
623         result=qFromBigEndian(result);
624     }
625     else
626     {
627         result=qFromLittleEndian(result);
628     }
629 
630     return result;
631 }
632 
read_int16(qint64 nOffset,bool bIsBigEndian)633 qint16 XBinary::read_int16(qint64 nOffset, bool bIsBigEndian)
634 {
635     quint16 result=0;
636 
637     read_array(nOffset,(char *)(&result),2);
638 
639     if(bIsBigEndian)
640     {
641         result=qFromBigEndian(result);
642     }
643     else
644     {
645         result=qFromLittleEndian(result);
646     }
647 
648     return (qint16)result;
649 }
650 
read_uint32(qint64 nOffset,bool bIsBigEndian)651 quint32 XBinary::read_uint32(qint64 nOffset, bool bIsBigEndian)
652 {
653     quint32 result=0;
654 
655     read_array(nOffset,(char *)(&result),4);
656 
657     if(bIsBigEndian)
658     {
659         result=qFromBigEndian(result);
660     }
661     else
662     {
663         result=qFromLittleEndian(result);
664     }
665 
666     return result;
667 }
668 
read_int32(qint64 nOffset,bool bIsBigEndian)669 qint32 XBinary::read_int32(qint64 nOffset, bool bIsBigEndian)
670 {
671     quint32 result=0;
672 
673     read_array(nOffset,(char *)(&result),4);
674 
675     if(bIsBigEndian)
676     {
677         result=qFromBigEndian(result);
678     }
679     else
680     {
681         result=qFromLittleEndian(result);
682     }
683 
684     return (qint32)result;
685 }
686 
read_uint64(qint64 nOffset,bool bIsBigEndian)687 quint64 XBinary::read_uint64(qint64 nOffset, bool bIsBigEndian)
688 {
689     quint64 result=0;
690 
691     read_array(nOffset,(char *)(&result),8);
692 
693     if(bIsBigEndian)
694     {
695         result=qFromBigEndian(result);
696     }
697     else
698     {
699         result=qFromLittleEndian(result);
700     }
701 
702     return result;
703 }
704 
read_int64(qint64 nOffset,bool bIsBigEndian)705 qint64 XBinary::read_int64(qint64 nOffset, bool bIsBigEndian)
706 {
707     qint64 result=0;
708 
709     read_array(nOffset,(char *)(&result),8);
710 
711     if(bIsBigEndian)
712     {
713         result=qFromBigEndian(result);
714     }
715     else
716     {
717         result=qFromLittleEndian(result);
718     }
719 
720     return (qint64)result;
721 }
722 
read_float(qint64 nOffset,bool bIsBigEndian)723 float XBinary::read_float(qint64 nOffset, bool bIsBigEndian)
724 {
725     float result=0;
726 
727     read_array(nOffset,(char *)(&result),2);
728 
729     endian_float(&result,bIsBigEndian);
730 
731     return result;
732 }
733 
read_double(qint64 nOffset,bool bIsBigEndian)734 double XBinary::read_double(qint64 nOffset, bool bIsBigEndian)
735 {
736     double result=0;
737 
738     read_array(nOffset,(char *)(&result),4);
739 
740     endian_double(&result,bIsBigEndian);
741 
742     return result;
743 }
744 
read_uint24(qint64 nOffset,bool bIsBigEndian)745 quint32 XBinary::read_uint24(qint64 nOffset, bool bIsBigEndian)
746 {
747     quint32 result=0;
748 
749     if(bIsBigEndian)
750     {
751         read_array(nOffset,(char *)(&result)+1,3);
752         result=qFromBigEndian(result);
753     }
754     else
755     {
756         read_array(nOffset,(char *)(&result)+0,3);
757         result=qFromLittleEndian(result);
758     }
759 
760     return (result&(0xFFFFFF));
761 }
762 
write_ansiString(qint64 nOffset,QString sString)763 qint64 XBinary::write_ansiString(qint64 nOffset, QString sString)
764 {
765     return write_array(nOffset,sString.toLatin1().data(),sString.length()+1);
766 }
767 
write_ansiStringFix(qint64 nOffset,qint64 nSize,QString sString)768 void XBinary::write_ansiStringFix(qint64 nOffset, qint64 nSize, QString sString)
769 {
770     char *pBuffer=new char[nSize+1]; // mb TODO Check
771 
772     _zeroMemory(pBuffer,nSize+1);
773 
774     if(sString.size()>nSize)
775     {
776         sString.resize(nSize);
777     }
778 
779     _copyMemory(pBuffer,sString.toLatin1().data(),sString.size());
780 
781     XBinary::write_array(nOffset,pBuffer,nSize);
782 
783     delete [] pBuffer;
784 }
785 
read_ansiString(qint64 nOffset,qint64 nMaxSize)786 QString XBinary::read_ansiString(qint64 nOffset,qint64 nMaxSize)
787 {
788     QString sResult;
789 
790     if(nMaxSize)
791     {
792         quint8 *pBuffer=new quint8[nMaxSize+1];
793 
794         for(int i=0; i<nMaxSize; i++)
795         {
796             pBuffer[i]=read_uint8(nOffset+i);
797 
798             if(pBuffer[i]==0)
799             {
800                 break;
801             }
802 
803             if(i==nMaxSize-1)
804             {
805                 pBuffer[nMaxSize]=0;
806             }
807         }
808 
809         sResult.append((char *)pBuffer);
810 
811         delete [] pBuffer;
812     }
813 
814     return sResult;
815 }
816 
read_unicodeString(qint64 nOffset,qint64 nMaxSize,bool bIsBigEndian)817 QString XBinary::read_unicodeString(qint64 nOffset, qint64 nMaxSize,bool bIsBigEndian)
818 {
819     QString sResult;
820 
821     if((nMaxSize>0)&&(nMaxSize<0x10000))
822     {
823         quint16 *pBuffer=new quint16[nMaxSize+1];
824 
825         for(int i=0; i<nMaxSize; i++)
826         {
827             pBuffer[i]=read_uint16(nOffset+2*i,bIsBigEndian);
828 
829             if(pBuffer[i]==0)
830             {
831                 break;
832             }
833 
834             if(i==nMaxSize-1)
835             {
836                 pBuffer[nMaxSize]=0;
837             }
838         }
839 
840         sResult=QString::fromUtf16(pBuffer);
841 
842         delete [] pBuffer;
843     }
844 
845     return sResult;
846 }
847 
read_utf8String(qint64 nOffset,qint64 nMaxSize)848 QString XBinary::read_utf8String(qint64 nOffset, qint64 nMaxSize)
849 {
850     QString sResult;
851 
852     if(nMaxSize)
853     {
854         qint32 nRealSize=0;
855 
856         for(int i=0; i<nMaxSize; i++)
857         {
858             quint8 nByte=read_uint8(nOffset+nRealSize);
859 
860             if(nByte==0)
861             {
862                 break;
863             }
864 
865             // TODO Check !!!
866             if((nByte>>7)&0x1)
867             {
868                 nRealSize++;
869             }
870             else if((nByte>>5)&0x1)
871             {
872                 nRealSize+=2;
873             }
874             else if((nByte>>4)&0x1)
875             {
876                 nRealSize+=3;
877             }
878             else if((nByte>>3)&0x1)
879             {
880                 nRealSize+=4;
881             }
882         }
883 
884         if(nRealSize)
885         {
886             QByteArray baString=read_array(nOffset,nRealSize);
887             sResult=QString::fromUtf8(baString.data());
888         }
889     }
890 
891     return sResult;
892 }
893 
_read_utf8String(qint64 nOffset,qint64 nMaxSize)894 QString XBinary::_read_utf8String(qint64 nOffset, qint64 nMaxSize)
895 {
896     QString sResult;
897 
898     PACKED_INT ulebSize=read_uleb128(nOffset,nMaxSize);
899 
900     sResult=read_utf8String(nOffset+ulebSize.nByteSize,ulebSize.nValue); // TODO mutf8
901 
902     return sResult;
903 }
904 
_read_utf8String(char * pData,qint64 nMaxSize)905 QString XBinary::_read_utf8String(char *pData, qint64 nMaxSize)
906 {
907     QString sResult;
908 
909     PACKED_INT ulebSize=_read_uleb128(pData,nMaxSize);
910 
911     qint32 nStringSize=qMin((qint64)ulebSize.nValue,nMaxSize-ulebSize.nByteSize);
912 
913     if(nStringSize>0)
914     {
915         sResult=QString::fromUtf8(pData+ulebSize.nByteSize,nStringSize);
916     }
917 
918     return sResult;
919 }
920 
_read_utf8String(qint64 nOffset,char * pData,qint32 nDataSize,qint32 nDataOffset)921 QString XBinary::_read_utf8String(qint64 nOffset, char *pData, qint32 nDataSize, qint32 nDataOffset)
922 {
923     QString sResult;
924 
925     if((nOffset>=nDataOffset)&&(nOffset<(nDataOffset+nDataSize)))
926     {
927         char *pStringData=pData+(nOffset-nDataOffset);
928         qint32 nStringSize=nDataSize-(nOffset-nDataOffset);
929         sResult=XBinary::_read_utf8String(pStringData,nStringSize);
930     }
931 
932     return sResult;
933 }
934 
write_uint8(qint64 nOffset,quint8 nValue)935 void XBinary::write_uint8(qint64 nOffset, quint8 nValue)
936 {
937     write_array(nOffset,(char *)(&nValue),1);
938 }
939 
write_int8(qint64 nOffset,qint8 nValue)940 void XBinary::write_int8(qint64 nOffset, qint8 nValue)
941 {
942     quint8 _value=(quint8)nValue;
943     write_array(nOffset,(char *)(&_value),1);
944 }
945 
write_uint16(qint64 nOffset,quint16 nValue,bool bIsBigEndian)946 void XBinary::write_uint16(qint64 nOffset, quint16 nValue, bool bIsBigEndian)
947 {
948     if(bIsBigEndian)
949     {
950         nValue=qFromBigEndian(nValue);
951     }
952     else
953     {
954         nValue=qFromLittleEndian(nValue);
955     }
956 
957     write_array(nOffset,(char *)(&nValue),2);
958 }
959 
write_int16(qint64 nOffset,qint16 nValue,bool bIsBigEndian)960 void XBinary::write_int16(qint64 nOffset, qint16 nValue, bool bIsBigEndian)
961 {
962     quint16 _value=(quint16)nValue;
963 
964     if(bIsBigEndian)
965     {
966         _value=qFromBigEndian(_value);
967     }
968     else
969     {
970         _value=qFromLittleEndian(_value);
971     }
972 
973     write_array(nOffset,(char *)(&_value),2);
974 }
975 
write_uint32(qint64 nOffset,quint32 nValue,bool bIsBigEndian)976 void XBinary::write_uint32(qint64 nOffset, quint32 nValue, bool bIsBigEndian)
977 {
978     if(bIsBigEndian)
979     {
980         nValue=qFromBigEndian(nValue);
981     }
982     else
983     {
984         nValue=qFromLittleEndian(nValue);
985     }
986 
987     write_array(nOffset,(char *)(&nValue),4);
988 }
989 
write_int32(qint64 nOffset,qint32 nValue,bool bIsBigEndian)990 void XBinary::write_int32(qint64 nOffset, qint32 nValue, bool bIsBigEndian)
991 {
992     quint32 _value=(quint32)nValue;
993 
994     if(bIsBigEndian)
995     {
996         _value=qFromBigEndian(_value);
997     }
998     else
999     {
1000         _value=qFromLittleEndian(_value);
1001     }
1002 
1003     write_array(nOffset,(char *)(&_value),4);
1004 }
1005 
write_uint64(qint64 nOffset,quint64 nValue,bool bIsBigEndian)1006 void XBinary::write_uint64(qint64 nOffset, quint64 nValue, bool bIsBigEndian)
1007 {
1008     if(bIsBigEndian)
1009     {
1010         nValue=qFromBigEndian(nValue);
1011     }
1012     else
1013     {
1014         nValue=qFromLittleEndian(nValue);
1015     }
1016 
1017     write_array(nOffset,(char *)(&nValue),8);
1018 }
1019 
write_int64(qint64 nOffset,qint64 nValue,bool bIsBigEndian)1020 void XBinary::write_int64(qint64 nOffset, qint64 nValue, bool bIsBigEndian)
1021 {
1022     quint64 _value=(quint64)nValue;
1023 
1024     if(bIsBigEndian)
1025     {
1026         _value=qFromBigEndian(_value);
1027     }
1028     else
1029     {
1030         _value=qFromLittleEndian(_value);
1031     }
1032 
1033     write_array(nOffset,(char *)(&_value),8);
1034 }
1035 
write_float(qint64 nOffset,float fValue,bool bIsBigEndian)1036 void XBinary::write_float(qint64 nOffset, float fValue, bool bIsBigEndian)
1037 {
1038     endian_float(&fValue,bIsBigEndian);
1039 
1040     write_array(nOffset,(char *)(&fValue),2);
1041 }
1042 
write_double(qint64 nOffset,double dValue,bool bIsBigEndian)1043 void XBinary::write_double(qint64 nOffset, double dValue, bool bIsBigEndian)
1044 {
1045     endian_double(&dValue,bIsBigEndian);
1046 
1047     write_array(nOffset,(char *)(&dValue),4);
1048 }
1049 
read_UUID(qint64 nOffset)1050 QString XBinary::read_UUID(qint64 nOffset)
1051 {
1052     // TODO check!
1053     QString sResult=QString("%1-%2-%3-%4-%5").arg(
1054             read_array(nOffset+0,4).toHex().data(),
1055             read_array(nOffset+4,2).toHex().data(),
1056             read_array(nOffset+6,2).toHex().data(),
1057             read_array(nOffset+8,2).toHex().data(),
1058             read_array(nOffset+10,6).toHex().data());
1059 
1060     return sResult;
1061 }
1062 
write_UUID(qint64 nOffset,QString sValue)1063 void XBinary::write_UUID(qint64 nOffset, QString sValue)
1064 {
1065     sValue=sValue.remove("-");
1066 
1067     QByteArray baUUID=QByteArray::fromHex(sValue.toLatin1().data());
1068 
1069     write_array(nOffset,baUUID.data(),16);
1070 }
1071 
_read_uint8(char * pData)1072 quint8 XBinary::_read_uint8(char *pData)
1073 {
1074     return *(quint8 *)pData;
1075 }
1076 
_read_int8(char * pData)1077 qint8 XBinary::_read_int8(char *pData)
1078 {
1079     return *(qint8 *)pData;
1080 }
1081 
_read_uint16(char * pData,bool bIsBigEndian)1082 quint16 XBinary::_read_uint16(char *pData, bool bIsBigEndian)
1083 {
1084     quint16 result=*(quint16 *)pData;
1085 
1086     if(bIsBigEndian)
1087     {
1088         result=qFromBigEndian(result);
1089     }
1090     else
1091     {
1092         result=qFromLittleEndian(result);
1093     }
1094 
1095     return result;
1096 }
1097 
_read_int16(char * pData,bool bIsBigEndian)1098 qint16 XBinary::_read_int16(char *pData, bool bIsBigEndian)
1099 {
1100     qint16 result=*(qint16 *)pData;
1101 
1102     if(bIsBigEndian)
1103     {
1104         result=qFromBigEndian(result);
1105     }
1106     else
1107     {
1108         result=qFromLittleEndian(result);
1109     }
1110 
1111     return result;
1112 }
1113 
_read_uint32(char * pData,bool bIsBigEndian)1114 quint32 XBinary::_read_uint32(char *pData, bool bIsBigEndian)
1115 {
1116     quint32 result=*(quint32 *)pData;
1117 
1118     if(bIsBigEndian)
1119     {
1120         result=qFromBigEndian(result);
1121     }
1122     else
1123     {
1124         result=qFromLittleEndian(result);
1125     }
1126 
1127     return result;
1128 }
1129 
_read_int32(char * pData,bool bIsBigEndian)1130 qint32 XBinary::_read_int32(char *pData, bool bIsBigEndian)
1131 {
1132     qint32 result=*(qint32 *)pData;
1133 
1134     if(bIsBigEndian)
1135     {
1136         result=qFromBigEndian(result);
1137     }
1138     else
1139     {
1140         result=qFromLittleEndian(result);
1141     }
1142 
1143     return result;
1144 }
1145 
_read_uint64(char * pData,bool bIsBigEndian)1146 quint64 XBinary::_read_uint64(char *pData, bool bIsBigEndian)
1147 {
1148     quint64 result=*(quint64 *)pData;
1149 
1150     if(bIsBigEndian)
1151     {
1152         result=qFromBigEndian(result);
1153     }
1154     else
1155     {
1156         result=qFromLittleEndian(result);
1157     }
1158 
1159     return result;
1160 }
1161 
_read_int64(char * pData,bool bIsBigEndian)1162 qint64 XBinary::_read_int64(char *pData, bool bIsBigEndian)
1163 {
1164     qint64 result=*(qint64 *)pData;
1165 
1166     if(bIsBigEndian)
1167     {
1168         result=qFromBigEndian(result);
1169     }
1170     else
1171     {
1172         result=qFromLittleEndian(result);
1173     }
1174 
1175     return result;
1176 }
1177 
_read_ansiString(char * pData,int nMaxSize)1178 QString XBinary::_read_ansiString(char *pData, int nMaxSize)
1179 {
1180     QString sResult;
1181 
1182     QByteArray baData(pData,nMaxSize);
1183     sResult.append(baData.data());
1184 
1185     return sResult;
1186 }
1187 
_read_byteArray(char * pData,int nSize)1188 QByteArray XBinary::_read_byteArray(char *pData, int nSize)
1189 {
1190     return QByteArray(pData,nSize);
1191 }
1192 
_read_float(char * pData,bool bIsBigEndian)1193 float XBinary::_read_float(char *pData, bool bIsBigEndian)
1194 {
1195     float result=*(float *)pData;
1196 
1197     endian_float(&result,bIsBigEndian);
1198 
1199     return result;
1200 }
1201 
_read_double(char * pData,bool bIsBigEndian)1202 double XBinary::_read_double(char *pData, bool bIsBigEndian)
1203 {
1204     double result=*(double *)pData;
1205 
1206     endian_double(&result,bIsBigEndian);
1207 
1208     return result;
1209 }
1210 
_read_value(MODE mode,char * pData,bool bIsBigEndian)1211 quint64 XBinary::_read_value(MODE mode, char *pData, bool bIsBigEndian)
1212 {
1213     quint64 nResult=0;
1214 
1215     if(mode==MODE::MODE_8)
1216     {
1217         nResult=_read_uint8(pData);
1218     }
1219     else if(mode==MODE::MODE_16)
1220     {
1221         nResult=_read_uint16(pData,bIsBigEndian);
1222     }
1223     else if(mode==MODE::MODE_32)
1224     {
1225         nResult=_read_uint32(pData,bIsBigEndian);
1226     }
1227     else if(mode==MODE::MODE_64)
1228     {
1229         nResult=_read_uint64(pData,bIsBigEndian);
1230     }
1231 
1232     return nResult;
1233 }
1234 
_write_uint8(char * pData,quint8 nValue)1235 void XBinary::_write_uint8(char *pData, quint8 nValue)
1236 {
1237     *(quint8 *)pData=nValue;
1238 }
1239 
_write_int8(char * pData,qint8 nValue)1240 void XBinary::_write_int8(char *pData, qint8 nValue)
1241 {
1242     *(qint8 *)pData=nValue;
1243 }
1244 
_write_uint16(char * pData,quint16 nValue,bool bIsBigEndian)1245 void XBinary::_write_uint16(char *pData, quint16 nValue, bool bIsBigEndian)
1246 {
1247     if(bIsBigEndian)
1248     {
1249         nValue=qToBigEndian(nValue);
1250     }
1251     else
1252     {
1253         nValue=qToLittleEndian(nValue);
1254     }
1255 
1256     *(quint16 *)pData=nValue;
1257 }
1258 
_write_int16(char * pData,qint16 nValue,bool bIsBigEndian)1259 void XBinary::_write_int16(char *pData, qint16 nValue, bool bIsBigEndian)
1260 {
1261     if(bIsBigEndian)
1262     {
1263         nValue=qToBigEndian(nValue);
1264     }
1265     else
1266     {
1267         nValue=qToLittleEndian(nValue);
1268     }
1269 
1270     *(qint16 *)pData=nValue;
1271 }
1272 
_write_uint32(char * pData,quint32 nValue,bool bIsBigEndian)1273 void XBinary::_write_uint32(char *pData, quint32 nValue, bool bIsBigEndian)
1274 {
1275     if(bIsBigEndian)
1276     {
1277         nValue=qToBigEndian(nValue);
1278     }
1279     else
1280     {
1281         nValue=qToLittleEndian(nValue);
1282     }
1283 
1284     *(quint32 *)pData=nValue;
1285 }
1286 
_write_int32(char * pData,qint32 nValue,bool bIsBigEndian)1287 void XBinary::_write_int32(char *pData, qint32 nValue, bool bIsBigEndian)
1288 {
1289     if(bIsBigEndian)
1290     {
1291         nValue=qToBigEndian(nValue);
1292     }
1293     else
1294     {
1295         nValue=qToLittleEndian(nValue);
1296     }
1297 
1298     *(qint32 *)pData=nValue;
1299 }
1300 
_write_uint64(char * pData,quint64 nValue,bool bIsBigEndian)1301 void XBinary::_write_uint64(char *pData, quint64 nValue, bool bIsBigEndian)
1302 {
1303     if(bIsBigEndian)
1304     {
1305         nValue=qToBigEndian(nValue);
1306     }
1307     else
1308     {
1309         nValue=qToLittleEndian(nValue);
1310     }
1311 
1312     *(quint64 *)pData=nValue;
1313 }
1314 
_write_int64(char * pData,qint64 nValue,bool bIsBigEndian)1315 void XBinary::_write_int64(char *pData, qint64 nValue, bool bIsBigEndian)
1316 {
1317     if(bIsBigEndian)
1318     {
1319         nValue=qToBigEndian(nValue);
1320     }
1321     else
1322     {
1323         nValue=qToLittleEndian(nValue);
1324     }
1325 
1326     *(qint64 *)pData=nValue;
1327 }
1328 
_write_float(char * pData,float fValue,bool bIsBigEndian)1329 void XBinary::_write_float(char *pData, float fValue, bool bIsBigEndian)
1330 {
1331     endian_float(&fValue,bIsBigEndian);
1332 
1333     *(float *)pData=fValue;
1334 }
1335 
_write_double(char * pData,double dValue,bool bIsBigEndian)1336 void XBinary::_write_double(char *pData, double dValue, bool bIsBigEndian)
1337 {
1338     endian_double(&dValue,bIsBigEndian);
1339 
1340     *(double *)pData=dValue;
1341 }
1342 
_write_value(MODE mode,char * pData,quint64 nValue,bool bIsBigEndian)1343 void XBinary::_write_value(MODE mode, char *pData, quint64 nValue, bool bIsBigEndian)
1344 {
1345     if(mode==MODE::MODE_8)
1346     {
1347         _write_uint8(pData,nValue);
1348     }
1349     else if(mode==MODE::MODE_16)
1350     {
1351         _write_uint16(pData,nValue,bIsBigEndian);
1352     }
1353     else if(mode==MODE::MODE_32)
1354     {
1355         _write_uint32(pData,nValue,bIsBigEndian);
1356     }
1357     else if(mode==MODE::MODE_64)
1358     {
1359         _write_uint64(pData,nValue,bIsBigEndian);
1360     }
1361 }
1362 
find_array(qint64 nOffset,qint64 nSize,const char * pArray,qint64 nArraySize)1363 qint64 XBinary::find_array(qint64 nOffset, qint64 nSize,const char *pArray, qint64 nArraySize)
1364 {
1365     // TODO CheckSize function
1366     // TODO Optimize
1367     qint64 _nSize=getSize();
1368 
1369     if(nSize==-1)
1370     {
1371         nSize=_nSize-nOffset;
1372     }
1373 
1374     if(nSize<=0)
1375     {
1376         return -1;
1377     }
1378 
1379     if(nOffset+nSize>_nSize)
1380     {
1381         return -1;
1382     }
1383 
1384     if(nArraySize>nSize)
1385     {
1386         return -1;
1387     }
1388 
1389     PROCENT procent=procentInit(nSize);
1390 
1391     _searchProgressMinimumChanged(0);
1392     _searchProgressMaximumChanged(procent.nMaxProcent);
1393     _searchProgressValueChanged(0);
1394 
1395     qint64 nTemp=0;
1396 
1397     char *pBuffer=new char[READWRITE_BUFFER_SIZE+(nArraySize-1)];
1398 
1399     qint64 nStartOffset=nOffset;
1400 
1401     while((nSize>nArraySize-1)&&(!g_bIsSearchStop))
1402     {
1403         nTemp=qMin((qint64)(READWRITE_BUFFER_SIZE+(nArraySize-1)),nSize);
1404 
1405         if(read_array(nOffset,pBuffer,nTemp)!=nTemp)
1406         {
1407             _errorMessage(tr("Read error"));
1408             break;
1409         }
1410 
1411         for(unsigned int i=0; i<nTemp-(nArraySize-1); i++)
1412         {
1413             if(compareMemory(pBuffer+i,pArray,nArraySize))
1414             {
1415                 delete[] pBuffer;
1416 
1417                 return nOffset+i;
1418             }
1419         }
1420 
1421         nSize-=nTemp-(nArraySize-1);
1422         nOffset+=nTemp-(nArraySize-1);
1423 
1424         if(procentSetCurrentValue(&procent,nOffset-nStartOffset))
1425         {
1426             _searchProgressValueChanged(procent.nCurrentProcent);
1427         }
1428     }
1429 
1430     _searchProgressValueChanged(procent.nMaxProcent);
1431 
1432     delete[] pBuffer;
1433 
1434     return -1;
1435 }
1436 
find_byteArray(qint64 nOffset,qint64 nSize,QByteArray baData)1437 qint64 XBinary::find_byteArray(qint64 nOffset, qint64 nSize, QByteArray baData)
1438 {
1439     return find_array(nOffset,nSize,baData.data(),baData.size());
1440 }
1441 
find_uint8(qint64 nOffset,qint64 nSize,quint8 nValue)1442 qint64 XBinary::find_uint8(qint64 nOffset, qint64 nSize, quint8 nValue)
1443 {
1444     return find_array(nOffset,nSize,(char *)&nValue,1);
1445 }
1446 
find_int8(qint64 nOffset,qint64 nSize,qint8 nValue)1447 qint64 XBinary::find_int8(qint64 nOffset, qint64 nSize, qint8 nValue)
1448 {
1449     return find_array(nOffset,nSize,(char *)&nValue,1);
1450 }
1451 
find_uint16(qint64 nOffset,qint64 nSize,quint16 nValue,bool bIsBigEndian)1452 qint64 XBinary::find_uint16(qint64 nOffset, qint64 nSize, quint16 nValue, bool bIsBigEndian)
1453 {
1454     if(bIsBigEndian)
1455     {
1456         nValue=qFromBigEndian(nValue);
1457     }
1458     else
1459     {
1460         nValue=qFromLittleEndian(nValue);
1461     }
1462 
1463     return find_array(nOffset,nSize,(char *)&nValue,2);
1464 }
1465 
find_int16(qint64 nOffset,qint64 nSize,qint16 nValue,bool bIsBigEndian)1466 qint64 XBinary::find_int16(qint64 nOffset, qint64 nSize, qint16 nValue, bool bIsBigEndian)
1467 {
1468     quint16 _value=(quint16)nValue;
1469 
1470     if(bIsBigEndian)
1471     {
1472         _value=qFromBigEndian(_value);
1473     }
1474     else
1475     {
1476         _value=qFromLittleEndian(_value);
1477     }
1478 
1479     return find_array(nOffset,nSize,(char *)&_value,2);
1480 }
1481 
find_uint32(qint64 nOffset,qint64 nSize,quint32 nValue,bool bIsBigEndian)1482 qint64 XBinary::find_uint32(qint64 nOffset, qint64 nSize, quint32 nValue, bool bIsBigEndian)
1483 {
1484     if(bIsBigEndian)
1485     {
1486         nValue=qFromBigEndian(nValue);
1487     }
1488     else
1489     {
1490         nValue=qFromLittleEndian(nValue);
1491     }
1492 
1493     return find_array(nOffset,nSize,(char *)&nValue,4);
1494 }
1495 
find_int32(qint64 nOffset,qint64 nSize,qint32 nValue,bool bIsBigEndian)1496 qint64 XBinary::find_int32(qint64 nOffset, qint64 nSize, qint32 nValue, bool bIsBigEndian)
1497 {
1498     quint32 _value=(quint32)nValue;
1499 
1500     if(bIsBigEndian)
1501     {
1502         _value=qFromBigEndian(_value);
1503     }
1504     else
1505     {
1506         _value=qFromLittleEndian(_value);
1507     }
1508 
1509     return find_array(nOffset,nSize,(char *)&_value,4);
1510 }
1511 
find_uint64(qint64 nOffset,qint64 nSize,quint64 nValue,bool bIsBigEndian)1512 qint64 XBinary::find_uint64(qint64 nOffset, qint64 nSize, quint64 nValue, bool bIsBigEndian)
1513 {
1514     if(bIsBigEndian)
1515     {
1516         nValue=qFromBigEndian(nValue);
1517     }
1518     else
1519     {
1520         nValue=qFromLittleEndian(nValue);
1521     }
1522 
1523     return find_array(nOffset,nSize,(char *)&nValue,8);
1524 }
1525 
find_int64(qint64 nOffset,qint64 nSize,qint64 nValue,bool bIsBigEndian)1526 qint64 XBinary::find_int64(qint64 nOffset, qint64 nSize, qint64 nValue, bool bIsBigEndian)
1527 {
1528     quint64 _value=(quint64)nValue;
1529 
1530     if(bIsBigEndian)
1531     {
1532         _value=qFromBigEndian(_value);
1533     }
1534     else
1535     {
1536         _value=qFromLittleEndian(_value);
1537     }
1538 
1539     return find_array(nOffset,nSize,(char *)&_value,8);
1540 }
1541 
find_float(qint64 nOffset,qint64 nSize,float fValue,bool bIsBigEndian)1542 qint64 XBinary::find_float(qint64 nOffset, qint64 nSize, float fValue, bool bIsBigEndian)
1543 {
1544     float _value=fValue;
1545 
1546     endian_float(&_value,bIsBigEndian);
1547 
1548     return find_array(nOffset,nSize,(char *)&_value,4);
1549 }
1550 
find_double(qint64 nOffset,qint64 nSize,double dValue,bool bIsBigEndian)1551 qint64 XBinary::find_double(qint64 nOffset, qint64 nSize, double dValue, bool bIsBigEndian)
1552 {
1553     double _value=dValue;
1554 
1555     endian_double(&_value,bIsBigEndian);
1556 
1557     return find_array(nOffset,nSize,(char *)&_value,8);
1558 }
1559 
endian_float(float * pValue,bool bIsBigEndian)1560 void XBinary::endian_float(float *pValue,bool bIsBigEndian)
1561 {
1562     bool bReverse=false;
1563 
1564 #if Q_BYTE_ORDER==Q_BIG_ENDIAN
1565     bReverse=!bIsBigEndian;
1566 #else
1567     bReverse=bIsBigEndian;
1568 #endif
1569 
1570     if(bReverse)
1571     {
1572         qSwap(((quint8 *)pValue)[0],((quint8 *)pValue)[3]);
1573         qSwap(((quint8 *)pValue)[1],((quint8 *)pValue)[2]);
1574     }
1575 }
1576 
endian_double(double * pValue,bool bIsBigEndian)1577 void XBinary::endian_double(double *pValue,bool bIsBigEndian)
1578 {
1579     bool bReverse=false;
1580 
1581 #if Q_BYTE_ORDER==Q_BIG_ENDIAN
1582     bReverse=!bIsBigEndian;
1583 #else
1584     bReverse=bIsBigEndian;
1585 #endif
1586 
1587     if(bReverse)
1588     {
1589         qSwap(((quint8 *)pValue)[0],((quint8 *)pValue)[7]);
1590         qSwap(((quint8 *)pValue)[1],((quint8 *)pValue)[6]);
1591         qSwap(((quint8 *)pValue)[2],((quint8 *)pValue)[5]);
1592         qSwap(((quint8 *)pValue)[3],((quint8 *)pValue)[4]);
1593     }
1594 }
1595 
find_ansiString(qint64 nOffset,qint64 nSize,QString sString)1596 qint64 XBinary::find_ansiString(qint64 nOffset, qint64 nSize, QString sString)
1597 {
1598     return find_array(nOffset,nSize,sString.toLatin1().data(),sString.size());
1599 }
1600 
find_unicodeString(qint64 nOffset,qint64 nSize,QString sString)1601 qint64 XBinary::find_unicodeString(qint64 nOffset, qint64 nSize, QString sString)
1602 {
1603     return find_array(nOffset,nSize,(char *)sString.utf16(),sString.size()*2);
1604 }
1605 
find_signature(qint64 nOffset,qint64 nSize,QString sSignature,qint64 * pnResultSize)1606 qint64 XBinary::find_signature(qint64 nOffset, qint64 nSize, QString sSignature, qint64 *pnResultSize)
1607 {
1608     _MEMORY_MAP memoryMap=XBinary::getMemoryMap();
1609 
1610     return find_signature(&memoryMap,nOffset,nSize,sSignature,pnResultSize);
1611 }
1612 
find_signature(_MEMORY_MAP * pMemoryMap,qint64 nOffset,qint64 nSize,QString sSignature,qint64 * pnResultSize)1613 qint64 XBinary::find_signature(_MEMORY_MAP *pMemoryMap, qint64 nOffset, qint64 nSize, QString sSignature, qint64 *pnResultSize)
1614 {
1615     // TODO CheckSize function
1616     qint64 _nSize=getSize();
1617 
1618     qint64 nResultSize=0;
1619 
1620     if(pnResultSize==0)
1621     {
1622         pnResultSize=&nResultSize;
1623     }
1624 
1625     if(nSize==-1)
1626     {
1627         nSize=_nSize-nOffset;
1628     }
1629 
1630     if(nSize<=0)
1631     {
1632         return -1;
1633     }
1634 
1635     if(nOffset+nSize>_nSize)
1636     {
1637         return -1;
1638     }
1639 
1640     sSignature=convertSignature(sSignature);
1641 
1642     if(sSignature.contains("$")||sSignature.contains("#")||sSignature.contains("+"))
1643     {
1644         *pnResultSize=1;
1645     }
1646     else
1647     {
1648         *pnResultSize=sSignature.size()/2;
1649     }
1650 
1651     qint64 nResult=-1;
1652 
1653     if(sSignature.contains(".")||sSignature.contains("$")||sSignature.contains("#")||sSignature.contains("+"))
1654     {
1655         PROCENT procent=procentInit(nSize);
1656 
1657         _searchProgressMinimumChanged(0);
1658         _searchProgressMaximumChanged(procent.nMaxProcent);
1659         _searchProgressValueChanged(0);
1660 
1661         sSignature=convertSignature(sSignature);
1662 
1663         QList<SIGNATURE_RECORD> listSignatureRecords=getSignatureRecords(sSignature);
1664 
1665         if(listSignatureRecords.count()&&((listSignatureRecords.at(0).st==ST_COMPAREBYTES)||(listSignatureRecords.at(0).st==ST_FINDBYTES)))
1666         {
1667             QByteArray baFirst=listSignatureRecords.at(0).baData;
1668 
1669             char *pData=baFirst.data();
1670             qint32 nDataSize=baFirst.size();
1671 
1672             for(qint64 i=0;(i<nSize)&&(!g_bIsSearchStop);)
1673             {
1674                 bool bDisableSignals=true;
1675 
1676                 if(g_bIsProcessSignalsDisable) // If we call find_signature in another search function
1677                 {
1678                     bDisableSignals=false;
1679                 }
1680 
1681                 if(bDisableSignals)
1682                 {
1683                     setProcessSignalsEnable(false);
1684                 }
1685 
1686                 qint64 nTempOffset=find_array(nOffset+i,nSize-1,pData,nDataSize);
1687 
1688                 if(bDisableSignals)
1689                 {
1690                     setProcessSignalsEnable(true);
1691                 }
1692 
1693                 if(nTempOffset!=-1)
1694                 {
1695                     if(_compareSignature(pMemoryMap,&listSignatureRecords,nTempOffset))
1696                     {
1697                         nResult=nTempOffset;
1698 
1699                         break;
1700                     }
1701                 }
1702                 else
1703                 {
1704                     break;
1705                 }
1706 
1707                 i=nTempOffset+nDataSize-nOffset;
1708 
1709                 if(procentSetCurrentValue(&procent,i))
1710                 {
1711                     _searchProgressValueChanged(procent.nCurrentProcent);
1712                 }
1713             }
1714 
1715             _searchProgressValueChanged(procent.nMaxProcent);
1716         }
1717         else
1718         {
1719             for(qint64 i=0;(i<nSize)&&(!g_bIsSearchStop); i++)
1720             {
1721                 if(_compareSignature(pMemoryMap,&listSignatureRecords,nOffset+i))
1722                 {
1723                     nResult=nOffset+i;
1724                     break;
1725                 }
1726 
1727                 if(procentSetCurrentValue(&procent,i))
1728                 {
1729                     _searchProgressValueChanged(procent.nCurrentProcent);
1730                 }
1731             }
1732 
1733             _searchProgressValueChanged(procent.nMaxProcent);
1734         }
1735     }
1736     else
1737     {
1738         QByteArray baData=QByteArray::fromHex(QByteArray(sSignature.toLatin1().data()));
1739         nResult=find_array(nOffset,nSize,baData.data(),baData.size());
1740     }
1741 
1742     return nResult;
1743 }
1744 
find_ansiStringI(qint64 nOffset,qint64 nSize,QString sString)1745 qint64 XBinary::find_ansiStringI(qint64 nOffset, qint64 nSize, QString sString)
1746 {
1747     // TODO CheckSize function
1748     // TODO Optimize
1749     qint64 nStringSize=sString.size();
1750     qint64 _nSize=getSize();
1751 
1752     if(nSize==-1)
1753     {
1754         nSize=_nSize-nOffset;
1755     }
1756 
1757     if(nSize<=0)
1758     {
1759         return -1;
1760     }
1761 
1762     if(nOffset+nSize>_nSize)
1763     {
1764         return -1;
1765     }
1766 
1767     if(nStringSize>nSize)
1768     {
1769         return -1;
1770     }
1771 
1772     PROCENT procent=procentInit(nSize);
1773 
1774     _searchProgressMinimumChanged(0);
1775     _searchProgressMaximumChanged(procent.nMaxProcent);
1776     _searchProgressValueChanged(0);
1777 
1778     qint64 nTemp=0;
1779 
1780     char *pBuffer=new char[READWRITE_BUFFER_SIZE+(nStringSize-1)];
1781 
1782     QByteArray baUpper=sString.toUpper().toLatin1();
1783     QByteArray baLower=sString.toLower().toLatin1();
1784 
1785     qint64 nStartOffset=nOffset;
1786 
1787     while((nSize>nStringSize-1)&&(!g_bIsSearchStop))
1788     {
1789         nTemp=qMin((qint64)(READWRITE_BUFFER_SIZE+(nStringSize-1)),nSize);
1790 
1791         if(read_array(nOffset,pBuffer,nTemp)!=nTemp)
1792         {
1793             _errorMessage(tr("Read error"));
1794             break;
1795         }
1796 
1797         for(unsigned int i=0; i<nTemp-(nStringSize-1); i++)
1798         {
1799             if(compareMemoryByteI((quint8 *)(pBuffer+i),(quint8 *)baUpper.data(),(quint8 *)baLower.data(),nStringSize))
1800             {
1801                 delete[] pBuffer;
1802 
1803                 return nOffset+i;
1804             }
1805         }
1806 
1807         nSize-=nTemp-(nStringSize-1);
1808         nOffset+=nTemp-(nStringSize-1);
1809 
1810         if(procentSetCurrentValue(&procent,nOffset-nStartOffset))
1811         {
1812             _searchProgressValueChanged(procent.nCurrentProcent);
1813         }
1814     }
1815 
1816     _searchProgressValueChanged(procent.nMaxProcent);
1817 
1818     delete[] pBuffer;
1819 
1820     return -1;
1821 }
1822 
find_unicodeStringI(qint64 nOffset,qint64 nSize,QString sString)1823 qint64 XBinary::find_unicodeStringI(qint64 nOffset, qint64 nSize, QString sString)
1824 {
1825     // TODO CheckSize function
1826     // TODO Optimize
1827     qint64 nStringSize=sString.size();
1828     qint64 _nSize=getSize();
1829 
1830     if(nSize==-1)
1831     {
1832         nSize=_nSize-nOffset;
1833     }
1834 
1835     if(nSize<=0)
1836     {
1837         return -1;
1838     }
1839 
1840     if(nOffset+nSize>_nSize)
1841     {
1842         return -1;
1843     }
1844 
1845     if(nStringSize>nSize)
1846     {
1847         return -1;
1848     }
1849 
1850     PROCENT procent=procentInit(nSize);
1851 
1852     _searchProgressMinimumChanged(0);
1853     _searchProgressMaximumChanged(procent.nMaxProcent);
1854     _searchProgressValueChanged(0);
1855 
1856     qint64 nTemp=0;
1857 
1858     char *pBuffer=new char[READWRITE_BUFFER_SIZE+2*(nStringSize-1)];
1859 
1860     QByteArray baUpper=getUnicodeString(sString.toUpper());
1861     QByteArray baLower=getUnicodeString(sString.toLower());
1862 
1863     qint64 nStartOffset=nOffset;
1864 
1865     while((nSize>2*(nStringSize-1))&&(!g_bIsSearchStop))
1866     {
1867         nTemp=qMin((qint64)(READWRITE_BUFFER_SIZE+2*(nStringSize-1)),nSize);
1868 
1869         if(read_array(nOffset,pBuffer,nTemp)!=nTemp)
1870         {
1871             _errorMessage(tr("Read error"));
1872             break;
1873         }
1874 
1875         for(unsigned int i=0; i<nTemp-2*(nStringSize-1); i++)
1876         {
1877             if(compareMemoryWordI((quint16 *)(pBuffer+i),(quint16 *)baUpper.data(),(quint16 *)baLower.data(),nStringSize))
1878             {
1879                 delete[] pBuffer;
1880 
1881                 return nOffset+i;
1882             }
1883         }
1884 
1885         nSize-=nTemp-2*(nStringSize-1);
1886         nOffset+=nTemp-2*(nStringSize-1);
1887 
1888         if(procentSetCurrentValue(&procent,nOffset-nStartOffset))
1889         {
1890             _searchProgressValueChanged(procent.nCurrentProcent);
1891         }
1892     }
1893 
1894     _searchProgressValueChanged(procent.nMaxProcent);
1895 
1896     delete[] pBuffer;
1897 
1898     return -1;
1899 }
1900 
multiSearch_allStrings(qint64 nOffset,qint64 nSize,STRINGSEARCH_OPTIONS ssOptions)1901 QList<XBinary::MS_RECORD> XBinary::multiSearch_allStrings(qint64 nOffset,qint64 nSize,STRINGSEARCH_OPTIONS ssOptions)
1902 {
1903     OFFSETSIZE os=convertOffsetAndSize(nOffset,nSize);
1904 
1905     nOffset=os.nOffset;
1906     nSize=os.nSize;
1907 
1908     QList<XBinary::MS_RECORD> listResult;
1909 
1910     bool bFilter=(ssOptions.sExpFilter!="");
1911 
1912     if(ssOptions.nMinLenght==0)
1913     {
1914         ssOptions.nMinLenght=1;
1915     }
1916 
1917     if(ssOptions.nMaxLenght==0)
1918     {
1919         ssOptions.nMaxLenght=128; // TODO Check
1920     }
1921 
1922     bool bANSICodec=false;
1923     QTextCodec *pCodec=nullptr;
1924 
1925     if(ssOptions.sANSICodec!="")
1926     {
1927         bANSICodec=true;
1928         pCodec=QTextCodec::codecForName(ssOptions.sANSICodec.toLatin1().data());
1929     }
1930 
1931     qint64 _nSize=nSize;
1932     qint64 _nOffset=nOffset;
1933     qint64 _nRawOffset=0;
1934 
1935     bool bReadError=false;
1936 
1937     char *pBuffer=new char[READWRITE_BUFFER_SIZE];
1938     char *pAnsiBuffer=new char[ssOptions.nMaxLenght+1];
1939     char *pUTF8Buffer=new char[ssOptions.nMaxLenght*4+1];
1940 
1941 //    _zeroMemory(pUTF8Buffer,ssOptions.nMaxLenght*4);
1942 
1943     quint16 *pUnicodeBuffer[2]={new quint16[ssOptions.nMaxLenght+1],new quint16[ssOptions.nMaxLenght+1]};
1944     qint64 nCurrentUnicodeSize[2]={0,0};
1945     qint64 nCurrentUnicodeOffset[2]={0,0};
1946 
1947     qint64 nCurrentAnsiSize=0;
1948     qint64 nCurrentAnsiOffset=0;
1949 
1950     qint64 nCurrentUTF8Size=0;
1951     qint64 nCurrentUTF8Offset=0;
1952     qint32 nLastUTF8Width=0;
1953     qint64 nLastUTF8Offset=-1;
1954 
1955     bool bIsStart=true;
1956     char cPrevSymbol=0;
1957 
1958     PROCENT procent=procentInit(nSize);
1959 
1960     _searchProgressMinimumChanged(0);
1961     _searchProgressMaximumChanged(procent.nMaxProcent);
1962     _searchProgressValueChanged(0);
1963 
1964     int nCurrentRecords=0;
1965 
1966     while((_nSize>0)&&(!g_bIsSearchStop))
1967     {
1968         qint64 nCurrentSize=qMin((qint64)READWRITE_BUFFER_SIZE,_nSize);
1969 
1970         if(safeReadData(g_pDevice,_nOffset,pBuffer,nCurrentSize)!=nCurrentSize)
1971         {
1972             bReadError=true;
1973             break;
1974         }
1975 
1976         for(qint64 i=0; i<nCurrentSize; i++)
1977         {
1978             bool bIsEnd=((i==(nCurrentSize-1))&&(_nSize==nCurrentSize));
1979             int nParity=(_nOffset+i)%2;
1980 
1981             char cSymbol=*(pBuffer+i);
1982 
1983             bool bIsAnsiSymbol=false;
1984             bool bIsUTF8Symbol=false;
1985 
1986             bool bNewUTF8String=false;
1987             bool bLongString=false;
1988 
1989             if(ssOptions.bAnsi)
1990             {
1991                 bIsAnsiSymbol=isAnsiSymbol((quint8)cSymbol,bANSICodec);
1992             }
1993 
1994             if(ssOptions.bUTF8)
1995             {
1996                 qint32 nUTF8SymbolWidth=0;
1997 
1998                 bIsUTF8Symbol=isUTF8Symbol((quint8)cSymbol,&nUTF8SymbolWidth);
1999 
2000                 if(bIsUTF8Symbol)
2001                 {
2002                     if(nLastUTF8Offset==-1)
2003                     {
2004                         if(nUTF8SymbolWidth==0) // Cannot start with rest
2005                         {
2006                             bIsUTF8Symbol=false;
2007                         }
2008                         else
2009                         {
2010                             nLastUTF8Offset=_nOffset+i;
2011                             nLastUTF8Width=nUTF8SymbolWidth;
2012                         }
2013                     }
2014                     else
2015                     {
2016                         if(nUTF8SymbolWidth)
2017                         {
2018                             if(((_nOffset+i)-nLastUTF8Offset)<nLastUTF8Width)
2019                             {
2020                                 bIsUTF8Symbol=false;
2021                                 bNewUTF8String=true;
2022                             }
2023 
2024                             nLastUTF8Offset=_nOffset+i;
2025                             nLastUTF8Width=nUTF8SymbolWidth;
2026                         }
2027                     }
2028                 }
2029             }
2030 
2031             if(bIsAnsiSymbol)
2032             {
2033                 if(nCurrentAnsiSize==0)
2034                 {
2035                     nCurrentAnsiOffset=_nOffset+i;
2036                 }
2037 
2038                 if(nCurrentAnsiSize<ssOptions.nMaxLenght)
2039                 {
2040                     *(pAnsiBuffer+nCurrentAnsiSize)=cSymbol;
2041                 }
2042                 else
2043                 {
2044                     bIsAnsiSymbol=false;
2045                     bLongString=true;
2046                 }
2047 
2048                 nCurrentAnsiSize++;
2049             }
2050 
2051             if(bIsUTF8Symbol)
2052             {
2053                 if(nCurrentUTF8Size==0)
2054                 {
2055                     nCurrentUTF8Offset=_nOffset+i;
2056                 }
2057 
2058                 if(nCurrentUTF8Size<ssOptions.nMaxLenght)
2059                 {
2060                     *(pUTF8Buffer+nCurrentUTF8Size)=cSymbol;
2061                 }
2062                 else
2063                 {
2064                     bIsUTF8Symbol=false;
2065                     bNewUTF8String=true;
2066                     bLongString=true;
2067                 }
2068 
2069                 nCurrentUTF8Size++;
2070             }
2071 
2072             if((!bIsAnsiSymbol)||(bIsEnd))
2073             {
2074                 if(nCurrentAnsiSize>=ssOptions.nMinLenght)
2075                 {
2076                     if(nCurrentAnsiSize-1<ssOptions.nMaxLenght)
2077                     {
2078                         pAnsiBuffer[nCurrentAnsiSize]=0;
2079                     }
2080                     else
2081                     {
2082                         pAnsiBuffer[ssOptions.nMaxLenght]=0;
2083                     }
2084 
2085                     if(ssOptions.bAnsi)
2086                     {
2087                         QString sString;
2088 
2089                         if(!bANSICodec)
2090                         {
2091                             sString=pAnsiBuffer;
2092                         }
2093                         else
2094                         {
2095                             QByteArray baString=QByteArray(pAnsiBuffer,nCurrentAnsiSize);
2096                             sString=pCodec->toUnicode(baString);
2097                         }
2098 
2099                         bool bAdd=true;
2100 
2101                         if(bFilter)
2102                         {
2103                             bAdd=isRegExpPresent(ssOptions.sExpFilter,sString);
2104 //                            bAdd=sString.contains(ssOptions.sExpFilter,Qt::CaseInsensitive);
2105                         }
2106 
2107                         if(ssOptions.bCStrings&&cSymbol&&(!bLongString))
2108                         {
2109                             bAdd=false;
2110                         }
2111 
2112                         if(bAdd)
2113                         {
2114                             MS_RECORD record={};
2115                             record.recordType=MS_RECORD_TYPE_ANSI;
2116                             record.nOffset=nCurrentAnsiOffset;
2117                             record.nSize=nCurrentAnsiSize;
2118                             record.sString=sString;
2119 
2120                             listResult.append(record);
2121 
2122                             nCurrentRecords++;
2123 
2124                             if(nCurrentRecords>=ssOptions.nLimit)
2125                             {
2126                                 break;
2127                             }
2128                         }
2129                     }
2130                 }
2131 
2132                 nCurrentAnsiSize=0;
2133             }
2134 
2135             if((!bIsUTF8Symbol)||(bIsEnd))
2136             {
2137                 if(nCurrentUTF8Size>=ssOptions.nMinLenght)
2138                 {
2139                     pUTF8Buffer[nCurrentUTF8Size]=0;
2140 
2141                     if(ssOptions.bUTF8)
2142                     {
2143                         QString sString=QString::fromUtf8(pUTF8Buffer,-1);
2144 
2145                         qint32 nStringSize=sString.size();
2146 
2147                         bool bAdd=true;
2148 
2149                         if(bFilter)
2150                         {
2151                             bAdd=isRegExpPresent(ssOptions.sExpFilter,sString);
2152 //                            bAdd=sString.contains(ssOptions.sExpFilter,Qt::CaseInsensitive);
2153                         }
2154 
2155                         if(ssOptions.bCStrings&&cSymbol&&(!bLongString))
2156                         {
2157                             bAdd=false;
2158                         }
2159 
2160                         if(nStringSize<ssOptions.nMinLenght)
2161                         {
2162                              bAdd=false;
2163                         }
2164 
2165                         if((nStringSize==nCurrentUTF8Size)&&(ssOptions.bAnsi))
2166                         {
2167                             bAdd=false;
2168                         }
2169 
2170                         if(bAdd)
2171                         {
2172                             MS_RECORD record={};
2173                             record.recordType=MS_RECORD_TYPE_UTF8;
2174                             record.nOffset=nCurrentUTF8Offset;
2175                             record.nSize=nCurrentUTF8Size;
2176                             record.sString=sString;
2177 
2178                             listResult.append(record);
2179 
2180                             nCurrentRecords++;
2181 
2182                             if(nCurrentRecords>=ssOptions.nLimit)
2183                             {
2184                                 break;
2185                             }
2186                         }
2187                     }
2188                 }
2189 
2190                 if(bNewUTF8String)
2191                 {
2192                     *(pUTF8Buffer)=cSymbol;
2193                     nCurrentUTF8Offset=_nOffset+i;
2194                     nCurrentUTF8Size=1;
2195                 }
2196                 else
2197                 {
2198                     nCurrentUTF8Size=0;
2199                     nLastUTF8Offset=-1;
2200                 }
2201             }
2202 
2203             if(!bIsStart)
2204             {
2205                 quint16 nCode=cPrevSymbol+(cSymbol<<8); // TODO BE/LE
2206 
2207                 bool bIsUnicodeSymbol=false;
2208 
2209                 if(ssOptions.bAnsi)
2210                 {
2211                     bIsUnicodeSymbol=isUnicodeSymbol(nCode,true);
2212                 }
2213 
2214                 if(nCurrentUnicodeSize[nParity]>=ssOptions.nMaxLenght)
2215                 {
2216                     bIsUnicodeSymbol=false;
2217                     bLongString=true;
2218                 }
2219 
2220                 if(bIsUnicodeSymbol)
2221                 {
2222                     if(nCurrentUnicodeSize[nParity]==0)
2223                     {
2224                         nCurrentUnicodeOffset[nParity]=_nOffset-1+i;
2225                     }
2226 
2227                     if(nCurrentUnicodeSize[nParity]<ssOptions.nMaxLenght)
2228                     {
2229                         *(pUnicodeBuffer[nParity]+nCurrentUnicodeSize[nParity])=nCode;
2230                     }
2231 
2232                     nCurrentUnicodeSize[nParity]++;
2233                 }
2234 
2235                 if((!bIsUnicodeSymbol)||(bIsEnd))
2236                 {
2237                     if(nCurrentUnicodeSize[nParity]>=ssOptions.nMinLenght)
2238                     {
2239                         if(nCurrentUnicodeSize[nParity]-1<ssOptions.nMaxLenght)
2240                         {
2241                             pUnicodeBuffer[nParity][nCurrentUnicodeSize[nParity]]=0;
2242                         }
2243                         else
2244                         {
2245                             pUnicodeBuffer[nParity][ssOptions.nMaxLenght]=0;
2246                         }
2247 
2248                         if(ssOptions.bUnicode)
2249                         {
2250                             QString sString=QString::fromUtf16(pUnicodeBuffer[nParity]);
2251 
2252                             bool bAdd=true;
2253 
2254                             if(bFilter)
2255                             {
2256                                 bAdd=isRegExpPresent(ssOptions.sExpFilter,sString);
2257 //                                bAdd=sString.contains(ssOptions.sExpFilter,Qt::CaseInsensitive);
2258                             }
2259 
2260                             if(ssOptions.bCStrings&&nCode&&(!bLongString))
2261                             {
2262                                 bAdd=false;
2263                             }
2264 
2265                             if(bAdd)
2266                             {
2267                                 MS_RECORD record={};
2268                                 record.recordType=MS_RECORD_TYPE_UNICODE;
2269                                 record.nOffset=nCurrentUnicodeOffset[nParity];
2270                                 record.nSize=nCurrentUnicodeSize[nParity]*2;
2271                                 record.sString=sString;
2272 
2273                                 listResult.append(record);
2274 
2275                                 nCurrentRecords++;
2276 
2277                                 if(nCurrentRecords>=ssOptions.nLimit)
2278                                 {
2279                                     break;
2280                                 }
2281                             }
2282                         }
2283                     }
2284 
2285                     if(bIsEnd)
2286                     {
2287                         int nO=(nParity==1)?(0):(1);
2288 
2289                         if(nCurrentUnicodeSize[nO]>=ssOptions.nMinLenght)
2290                         {
2291                             if(nCurrentUnicodeSize[nO]-1<ssOptions.nMaxLenght)
2292                             {
2293                                 pUnicodeBuffer[nO][nCurrentUnicodeSize[nO]]=0;
2294                             }
2295                             else
2296                             {
2297                                 pUnicodeBuffer[nO][ssOptions.nMaxLenght]=0;
2298                             }
2299 
2300                             if(ssOptions.bUnicode)
2301                             {
2302                                 QString sString=QString::fromUtf16(pUnicodeBuffer[nO]);
2303 
2304                                 bool bAdd=true;
2305 
2306                                 if(bFilter)
2307                                 {
2308                                     bAdd=isRegExpPresent(ssOptions.sExpFilter,sString);
2309 //                                    bAdd=sString.contains(ssOptions.sExpFilter,Qt::CaseInsensitive);
2310                                 }
2311 
2312                                 if(bAdd)
2313                                 {
2314                                     MS_RECORD record={};
2315                                     record.recordType=MS_RECORD_TYPE_UNICODE;
2316                                     record.nOffset=nCurrentUnicodeOffset[nO];
2317                                     record.nSize=nCurrentUnicodeSize[nO]*2;
2318                                     record.sString=sString;
2319 
2320                                     listResult.append(record);
2321 
2322                                     nCurrentRecords++;
2323 
2324                                     if(nCurrentRecords>=ssOptions.nLimit)
2325                                     {
2326                                         break;
2327                                     }
2328                                 }
2329                             }
2330                         }
2331                     }
2332 
2333                     nCurrentUnicodeSize[nParity]=0;
2334                 }
2335             }
2336 
2337             cPrevSymbol=cSymbol;
2338 
2339             if(bIsStart)
2340             {
2341                 bIsStart=false;
2342             }
2343         }
2344 
2345         _nSize-=nCurrentSize;
2346         _nOffset+=nCurrentSize;
2347         _nRawOffset+=nCurrentSize;
2348 
2349         if(procentSetCurrentValue(&procent,_nOffset-nOffset))
2350         {
2351             _searchProgressValueChanged(procent.nCurrentProcent);
2352         }
2353 
2354         if(nCurrentRecords>=ssOptions.nLimit)
2355         {
2356             _errorMessage(QString("%1: %2").arg(tr("Maximum"),QString::number(nCurrentRecords)));
2357 
2358             break;
2359         }
2360     }
2361 
2362     _searchProgressValueChanged(procent.nMaxProcent);
2363 
2364     if(bReadError)
2365     {
2366         _errorMessage(tr("Read error"));
2367     }
2368 
2369     delete [] pBuffer;
2370     delete [] pAnsiBuffer;
2371     delete [] pUTF8Buffer;
2372     delete [] pUnicodeBuffer[0];
2373     delete [] pUnicodeBuffer[1];
2374 
2375     return listResult;
2376 }
2377 
multiSearch_signature(qint64 nOffset,qint64 nSize,qint32 nLimit,QString sSignature,QString sInfo)2378 QList<XBinary::MS_RECORD> XBinary::multiSearch_signature(qint64 nOffset, qint64 nSize, qint32 nLimit, QString sSignature, QString sInfo)
2379 {
2380     _MEMORY_MAP memoryMap=getMemoryMap();
2381 
2382     return multiSearch_signature(&memoryMap,nOffset,nSize,nLimit,sSignature,sInfo);
2383 }
2384 
multiSearch_signature(_MEMORY_MAP * pMemoryMap,qint64 nOffset,qint64 nSize,qint32 nLimit,QString sSignature,QString sInfo)2385 QList<XBinary::MS_RECORD> XBinary::multiSearch_signature(_MEMORY_MAP *pMemoryMap, qint64 nOffset, qint64 nSize, qint32 nLimit, QString sSignature, QString sInfo)
2386 {
2387     QList<XBinary::MS_RECORD> listResult;
2388 
2389     qint64 _nSize=nSize;
2390     qint64 _nOffset=nOffset;
2391 
2392     PROCENT procent=procentInit(nSize);
2393 
2394     _searchProgressMinimumChanged(0);
2395     _searchProgressMaximumChanged(procent.nMaxProcent);
2396     _searchProgressValueChanged(0);
2397 
2398     int nCurrentRecords=0;
2399 
2400     while((_nSize>0)&&(!g_bIsSearchStop))
2401     {
2402         bool bDisableSignals=true;
2403 
2404         if(g_bIsProcessSignalsDisable) // If we call find_signature in another search function
2405         {
2406             bDisableSignals=false;
2407         }
2408 
2409         if(bDisableSignals)
2410         {
2411             setProcessSignalsEnable(false);
2412         }
2413 
2414         qint64 nSignatureSize=0;
2415         qint64 nSignatureOffset=find_signature(pMemoryMap,_nOffset,_nSize,sSignature,&nSignatureSize);
2416 
2417         if(bDisableSignals)
2418         {
2419             setProcessSignalsEnable(true);
2420         }
2421 
2422         if(nSignatureOffset==-1)
2423         {
2424             break;
2425         }
2426 
2427         MS_RECORD record={};
2428         record.recordType=MS_RECORD_TYPE_SIGNATURE;
2429         record.nOffset=nSignatureOffset;
2430         record.nSize=nSignatureSize;
2431         record.sString=sSignature;
2432         record.sInfo=sInfo;
2433 
2434         listResult.append(record);
2435 
2436         nCurrentRecords++;
2437 
2438         if(nCurrentRecords>=nLimit)
2439         {
2440             _errorMessage(QString("%1: %2").arg(tr("Maximum"),QString::number(nCurrentRecords)));
2441 
2442             break;
2443         }
2444 
2445         _nOffset=nSignatureOffset+nSignatureSize;
2446         _nSize=nSize-(_nOffset-nOffset);
2447 
2448         if(procentSetCurrentValue(&procent,_nOffset-nOffset))
2449         {
2450             _searchProgressValueChanged(procent.nCurrentProcent);
2451         }
2452     }
2453 
2454     _searchProgressValueChanged(procent.nMaxProcent);
2455 
2456     return listResult;
2457 }
2458 
getUnicodeString(QString sString)2459 QByteArray XBinary::getUnicodeString(QString sString)
2460 {
2461     QByteArray baResult;
2462 
2463     int nSize=sString.size();
2464 
2465     baResult.resize(nSize*2);
2466 
2467     baResult.fill(0);
2468 
2469     _copyMemory(baResult.data(),(char *)sString.utf16(),nSize*2);
2470 
2471     return baResult;
2472 }
2473 
setSearchProcessEnable(bool bState)2474 void XBinary::setSearchProcessEnable(bool bState)
2475 {
2476     g_bIsSearchStop=!bState;
2477 }
2478 
setDumpProcessEnable(bool bState)2479 void XBinary::setDumpProcessEnable(bool bState)
2480 {
2481     g_bIsDumpStop=!bState;
2482 }
2483 
setEntropyProcessEnable(bool bState)2484 void XBinary::setEntropyProcessEnable(bool bState)
2485 {
2486     g_bIsEntropyStop=!bState;
2487 }
2488 
setHashProcessEnable(bool bState)2489 void XBinary::setHashProcessEnable(bool bState)
2490 {
2491     g_bIsHashStop=!bState;
2492 }
2493 
setProcessSignalsEnable(bool bState)2494 void XBinary::setProcessSignalsEnable(bool bState)
2495 {
2496     g_bIsProcessSignalsDisable=!bState;
2497 }
2498 
isSignaturePresent(_MEMORY_MAP * pMemoryMap,qint64 nOffset,qint64 nSize,QString sSignature)2499 bool XBinary::isSignaturePresent(_MEMORY_MAP *pMemoryMap,qint64 nOffset, qint64 nSize, QString sSignature)
2500 {
2501     return (find_signature(pMemoryMap,nOffset,nSize,sSignature)!=-1);
2502 }
2503 
createFile(QString sFileName,qint64 nFileSize)2504 bool XBinary::createFile(QString sFileName, qint64 nFileSize)
2505 {
2506     bool bResult=false;
2507 
2508     QFile file;
2509 
2510     file.setFileName(sFileName);
2511 
2512     if(file.open(QIODevice::ReadWrite))
2513     {
2514         bResult=true;
2515 
2516         if(nFileSize)
2517         {
2518             bResult=file.resize(nFileSize);
2519         }
2520 
2521         file.close();
2522     }
2523 
2524     return bResult;
2525 }
2526 
isFileExists(QString sFileName)2527 bool XBinary::isFileExists(QString sFileName)
2528 {
2529     QFileInfo fi(sFileName);
2530 
2531     return (fi.exists()&&fi.isFile());
2532 }
2533 
removeFile(QString sFileName)2534 bool XBinary::removeFile(QString sFileName)
2535 {
2536     return QFile::remove(sFileName);
2537 }
2538 
copyFile(QString sSrcFileName,QString sDestFileName)2539 bool XBinary::copyFile(QString sSrcFileName,QString sDestFileName)
2540 {
2541     // mb TODO remove first
2542     return QFile::copy(sSrcFileName,sDestFileName);
2543 }
2544 
moveFile(QString sSrcFileName,QString sDestFileName)2545 bool XBinary::moveFile(QString sSrcFileName, QString sDestFileName)
2546 {
2547     bool bResult=false;
2548 
2549     if(copyFile(sSrcFileName,sDestFileName))
2550     {
2551         bResult=removeFile(sSrcFileName);
2552 
2553         if(!bResult)
2554         {
2555             removeFile(sDestFileName);
2556         }
2557     }
2558 
2559     return bResult;
2560 }
2561 
moveFileToDirectory(QString sSrcFileName,QString sDestDirectory)2562 bool XBinary::moveFileToDirectory(QString sSrcFileName, QString sDestDirectory)
2563 {
2564     QFileInfo fi(sSrcFileName);
2565 
2566     return moveFile(sSrcFileName,sDestDirectory+QDir::separator()+fi.fileName());
2567 }
2568 
convertFileNameSymbols(QString sFileName)2569 QString XBinary::convertFileNameSymbols(QString sFileName)
2570 {
2571     sFileName=sFileName.replace("/","_");
2572     sFileName=sFileName.replace("\\","_");
2573     sFileName=sFileName.replace("?","_");
2574     sFileName=sFileName.replace("*","_");
2575     sFileName=sFileName.replace("\"","_");
2576     sFileName=sFileName.replace("<","_");
2577     sFileName=sFileName.replace(">","_");
2578     sFileName=sFileName.replace("|","_");
2579     sFileName=sFileName.replace(":","_");
2580     sFileName=sFileName.replace("\n","_");
2581     sFileName=sFileName.replace("\r","_");
2582 
2583     return sFileName;
2584 }
2585 
getBaseFileName(QString sFileName)2586 QString XBinary::getBaseFileName(QString sFileName)
2587 {
2588     QFileInfo fi(sFileName);
2589 
2590     return fi.baseName();
2591 }
2592 
createDirectory(QString sDirectoryName)2593 bool XBinary::createDirectory(QString sDirectoryName)
2594 {
2595     return QDir().mkpath(sDirectoryName);
2596 }
2597 
isDirectoryExists(QString sDirectoryName)2598 bool XBinary::isDirectoryExists(QString sDirectoryName)
2599 {
2600     QFileInfo fi(sDirectoryName);
2601 
2602     return (fi.exists()&&fi.isDir());
2603 }
2604 
removeDirectory(QString sDirectoryName)2605 bool XBinary::removeDirectory(QString sDirectoryName)
2606 {
2607     QDir dir(sDirectoryName);
2608 
2609     return dir.removeRecursively();
2610 }
2611 
isDirectoryEmpty(QString sDirectoryName)2612 bool XBinary::isDirectoryEmpty(QString sDirectoryName)
2613 {
2614     return (QDir(sDirectoryName).entryInfoList(QDir::NoDotAndDotDot|QDir::AllEntries).count()==0);
2615 }
2616 
readFile(QString sFileName)2617 QByteArray XBinary::readFile(QString sFileName)
2618 {
2619     QByteArray baResult;
2620 
2621     QFile file;
2622     file.setFileName(sFileName);
2623 
2624     if(file.open(QIODevice::ReadOnly))
2625     {
2626         baResult=file.readAll();
2627 
2628         file.close();
2629     }
2630 
2631     return baResult;
2632 }
2633 
_copyMemory(char * pDest,char * pSource,qint64 nSize)2634 void XBinary::_copyMemory(char *pDest,char *pSource, qint64 nSize)
2635 {
2636     // TODO optimize
2637     while(nSize)
2638     {
2639         *pDest=*pSource;
2640         pDest++;
2641         pSource++;
2642         nSize--;
2643     }
2644 }
2645 
_zeroMemory(char * pDest,qint64 nSize)2646 void XBinary::_zeroMemory(char *pDest, qint64 nSize)
2647 {
2648     // TODO optimize
2649     while(nSize)
2650     {
2651         *pDest=0;
2652         pDest++;
2653         nSize--;
2654     }
2655 }
2656 
_isMemoryZeroFilled(char * pDest,qint64 nSize)2657 bool XBinary::_isMemoryZeroFilled(char *pDest, qint64 nSize)
2658 {
2659     bool bResult=true;
2660 
2661     while(nSize)
2662     {
2663         if(*pDest)
2664         {
2665             bResult=false;
2666 
2667             break;
2668         }
2669 
2670         pDest++;
2671         nSize--;
2672     }
2673 
2674     return bResult;
2675 }
2676 
copyDeviceMemory(QIODevice * pSourceDevice,qint64 nSourceOffset,QIODevice * pDestDevice,qint64 nDestOffset,qint64 nSize,quint32 nBufferSize)2677 bool XBinary::copyDeviceMemory(QIODevice *pSourceDevice,qint64 nSourceOffset,QIODevice *pDestDevice,qint64 nDestOffset,qint64 nSize,quint32 nBufferSize)
2678 {
2679     // TODO optimize
2680     if((!pSourceDevice->seek(nSourceOffset))||(!pDestDevice->seek(nDestOffset)))
2681     {
2682         return false;
2683     }
2684 
2685     char *pBuffer=new char[nBufferSize];
2686 
2687     while(nSize>0)
2688     {
2689         qint64 nCurrentBufferSize=qMin(nSize,(qint64)nBufferSize);
2690 
2691         if(nCurrentBufferSize!=pSourceDevice->read(pBuffer,nCurrentBufferSize))
2692         {
2693             break;
2694         }
2695 
2696         if(nCurrentBufferSize!=pDestDevice->write(pBuffer,nCurrentBufferSize))
2697         {
2698             break;
2699         }
2700 
2701         nSize-=nCurrentBufferSize;
2702     }
2703 
2704     delete [] pBuffer;
2705 
2706     return (bool)(nSize==0);
2707 }
2708 
copyMemory(qint64 nSourceOffset,qint64 nDestOffset,qint64 nSize,quint32 nBufferSize,bool bReverse)2709 bool XBinary::copyMemory(qint64 nSourceOffset, qint64 nDestOffset, qint64 nSize, quint32 nBufferSize, bool bReverse)
2710 {
2711     // TODO optimize
2712     if(nBufferSize==0)
2713     {
2714         return false;
2715     }
2716 
2717     if(nDestOffset==nSourceOffset)
2718     {
2719         return true;
2720     }
2721 
2722     qint64 nMaxSize=getSize();
2723 
2724     if((nDestOffset+nSize>nMaxSize)||(nSourceOffset+nSize>nMaxSize))
2725     {
2726         return false;
2727     }
2728 
2729     // TODO
2730     char *pBuffer=new char[nBufferSize];
2731 
2732     if(bReverse)
2733     {
2734         nSourceOffset+=nSize;
2735         nDestOffset+=nSize;
2736     }
2737 
2738     while(nSize>0)
2739     {
2740         qint64 nTempSize=qMin(nSize,(qint64)nBufferSize);
2741 
2742         if(bReverse)
2743         {
2744             nSourceOffset-=nTempSize;
2745             nDestOffset-=nTempSize;
2746         }
2747 
2748         read_array(nSourceOffset,pBuffer,nTempSize);
2749         write_array(nDestOffset,pBuffer,nTempSize);
2750 
2751         if(!bReverse)
2752         {
2753             nSourceOffset+=nTempSize;
2754             nDestOffset+=nTempSize;
2755         }
2756 
2757         nSize-=nTempSize;
2758     }
2759 
2760     delete [] pBuffer;
2761 
2762     return false;
2763 }
2764 
zeroFill(qint64 nOffset,qint64 nSize)2765 bool XBinary::zeroFill(qint64 nOffset, qint64 nSize)
2766 {
2767     // TODO optimize
2768     if(nSize==0)
2769     {
2770         return false;
2771     }
2772 
2773     qint64 nMaxSize=getSize();
2774 
2775     if(nOffset+nSize>nMaxSize)
2776     {
2777         return false;
2778     }
2779 
2780     quint8 cZero=0;
2781 
2782     // TODO optimize with dwords
2783     for(int i=0;i<nSize;i++)
2784     {
2785         safeWriteData(g_pDevice,nOffset,(char *)&cZero,1);
2786     }
2787 
2788     return true;
2789 }
2790 
compareMemory(char * pMemory1,const char * pMemory2,qint64 nSize)2791 bool XBinary::compareMemory(char *pMemory1,const char *pMemory2, qint64 nSize)
2792 {
2793     while(nSize>0)
2794     {
2795         if(nSize>=4)
2796         {
2797             if(*((unsigned int *)pMemory1)!=*((unsigned int *)pMemory2))
2798             {
2799                 return false;
2800             }
2801 
2802             pMemory1+=4;
2803             pMemory2+=4;
2804             nSize-=4;
2805         }
2806         else if(nSize>=2)
2807         {
2808             if(*((unsigned short *)pMemory1)!=*((unsigned short *)pMemory2))
2809             {
2810                 return false;
2811             }
2812 
2813             pMemory1+=2;
2814             pMemory2+=2;
2815             nSize-=2;
2816         }
2817         else
2818         {
2819             if(*(pMemory1)!=*(pMemory2))
2820             {
2821                 return false;
2822             }
2823 
2824             pMemory1++;
2825             pMemory2++;
2826             nSize--;
2827         }
2828     }
2829 
2830     return true;
2831 }
2832 
compareMemoryByteI(quint8 * pMemory,const quint8 * pMemoryU,const quint8 * pMemoryL,qint64 nSize)2833 bool XBinary::compareMemoryByteI(quint8 *pMemory, const quint8 *pMemoryU, const quint8 *pMemoryL, qint64 nSize)
2834 {
2835     bool bResult=true;
2836 
2837     while(nSize>0)
2838     {
2839         if((*(pMemory)!=*(pMemoryU))&&(*(pMemory)!=*(pMemoryL)))
2840         {
2841             bResult=false;
2842             break;
2843         }
2844 
2845         pMemory++;
2846         pMemoryU++;
2847         pMemoryL++;
2848         nSize--;
2849     }
2850 
2851     return bResult;
2852 }
2853 
compareMemoryWordI(quint16 * pMemory,const quint16 * pMemoryU,const quint16 * pMemoryL,qint64 nSize)2854 bool XBinary::compareMemoryWordI(quint16 *pMemory, const quint16 *pMemoryU, const quint16 *pMemoryL, qint64 nSize)
2855 {
2856     bool bResult=true;
2857 
2858     while(nSize>0)
2859     {
2860         if((*(pMemory)!=*(pMemoryU))&&(*(pMemory)!=*(pMemoryL)))
2861         {
2862             bResult=false;
2863             break;
2864         }
2865 
2866         pMemory++;
2867         pMemoryU++;
2868         pMemoryL++;
2869         nSize--;
2870     }
2871 
2872     return bResult;
2873 }
2874 
isOffsetValid(qint64 nOffset)2875 bool XBinary::isOffsetValid(qint64 nOffset)
2876 {
2877     _MEMORY_MAP memoryMap=getMemoryMap();
2878 
2879     return isOffsetValid(&memoryMap,nOffset);
2880 }
2881 
isAddressValid(qint64 nAddress)2882 bool XBinary::isAddressValid(qint64 nAddress)
2883 {
2884     _MEMORY_MAP memoryMap=getMemoryMap();
2885 
2886     return isAddressValid(&memoryMap,nAddress);
2887 }
2888 
isRelAddressValid(qint64 nRelAddress)2889 bool XBinary::isRelAddressValid(qint64 nRelAddress)
2890 {
2891     _MEMORY_MAP memoryMap=getMemoryMap();
2892 
2893     return isRelAddressValid(&memoryMap,nRelAddress);
2894 }
2895 
offsetToAddress(qint64 nOffset)2896 qint64 XBinary::offsetToAddress(qint64 nOffset)
2897 {
2898     _MEMORY_MAP memoryMap=getMemoryMap();
2899 
2900     return offsetToAddress(&memoryMap,nOffset);
2901 }
2902 
addressToOffset(qint64 nAddress)2903 qint64 XBinary::addressToOffset(qint64 nAddress)
2904 {
2905     _MEMORY_MAP memoryMap=getMemoryMap();
2906     return addressToOffset(&memoryMap,nAddress);
2907 }
2908 
offsetToRelAddress(qint64 nOffset)2909 qint64 XBinary::offsetToRelAddress(qint64 nOffset)
2910 {
2911     _MEMORY_MAP memoryMap=getMemoryMap();
2912 
2913     return offsetToRelAddress(&memoryMap,nOffset);
2914 }
2915 
relAddressToOffset(qint64 nRelAddress)2916 qint64 XBinary::relAddressToOffset(qint64 nRelAddress)
2917 {
2918     _MEMORY_MAP memoryMap=getMemoryMap();
2919 
2920     return relAddressToOffset(&memoryMap,nRelAddress);
2921 }
2922 
isOffsetValid(XBinary::_MEMORY_MAP * pMemoryMap,qint64 nOffset)2923 bool XBinary::isOffsetValid(XBinary::_MEMORY_MAP *pMemoryMap, qint64 nOffset)
2924 {
2925     bool bResult=false;
2926 
2927     if(pMemoryMap->nRawSize)
2928     {
2929         bResult=((nOffset>=0)&&(nOffset<pMemoryMap->nRawSize));
2930     }
2931     else
2932     {
2933         int nNumberOfRecords=pMemoryMap->listRecords.count();
2934 
2935         for(int i=0; i<nNumberOfRecords; i++)
2936         {
2937             if(pMemoryMap->listRecords.at(i).nSize&&(pMemoryMap->listRecords.at(i).nOffset!=-1))
2938             {
2939                 if((pMemoryMap->listRecords.at(i).nOffset<=nOffset)&&(nOffset<pMemoryMap->listRecords.at(i).nOffset+pMemoryMap->listRecords.at(i).nSize))
2940                 {
2941                     bResult=true;
2942                     break;
2943                 }
2944             }
2945         }
2946     }
2947 
2948     return bResult;
2949 }
2950 
isOffsetAndSizeValid(XBinary::_MEMORY_MAP * pMemoryMap,XBinary::OFFSETSIZE * pOffsetSize)2951 bool XBinary::isOffsetAndSizeValid(XBinary::_MEMORY_MAP *pMemoryMap, XBinary::OFFSETSIZE *pOffsetSize)
2952 {
2953     return isOffsetAndSizeValid(pMemoryMap,pOffsetSize->nOffset,pOffsetSize->nSize);
2954 }
2955 
isOffsetAndSizeValid(qint64 nOffset,qint64 nSize)2956 bool XBinary::isOffsetAndSizeValid(qint64 nOffset, qint64 nSize)
2957 {
2958     XBinary::_MEMORY_MAP memoryMap=getMemoryMap();
2959 
2960     return isOffsetAndSizeValid(&memoryMap,nOffset,nSize);
2961 }
2962 
isOffsetAndSizeValid(XBinary::_MEMORY_MAP * pMemoryMap,qint64 nOffset,qint64 nSize)2963 bool XBinary::isOffsetAndSizeValid(XBinary::_MEMORY_MAP *pMemoryMap, qint64 nOffset, qint64 nSize)
2964 {
2965     bool bResult=false;
2966 
2967     if(nSize>0)
2968     {
2969         bool bValidOffset=isOffsetValid(pMemoryMap,nOffset);
2970         bool bValidSize=isOffsetValid(pMemoryMap,nOffset+nSize-1);
2971         bResult=bValidOffset&&bValidSize;
2972     }
2973 
2974     return bResult;
2975 }
2976 
isAddressValid(XBinary::_MEMORY_MAP * pMemoryMap,qint64 nAddress)2977 bool XBinary::isAddressValid(XBinary::_MEMORY_MAP *pMemoryMap, qint64 nAddress)
2978 {
2979     bool bResult=false;
2980 
2981     if(pMemoryMap->nImageSize)
2982     {
2983         bResult=((pMemoryMap->nModuleAddress<=nAddress)&&(nAddress<(pMemoryMap->nModuleAddress+pMemoryMap->nImageSize)));
2984     }
2985     else
2986     {
2987         int nNumberOfRecords=pMemoryMap->listRecords.count();
2988 
2989         for(int i=0; i<nNumberOfRecords; i++)
2990         {
2991             if(pMemoryMap->listRecords.at(i).nSize&&(pMemoryMap->listRecords.at(i).nAddress!=-1))
2992             {
2993                 if((pMemoryMap->listRecords.at(i).nAddress<=nAddress)&&(nAddress<pMemoryMap->listRecords.at(i).nAddress+pMemoryMap->listRecords.at(i).nSize))
2994                 {
2995                     bResult=true;
2996                     break;
2997                 }
2998             }
2999         }
3000     }
3001 
3002     return bResult;
3003 }
3004 
isRelAddressValid(XBinary::_MEMORY_MAP * pMemoryMap,qint64 nRelAddress)3005 bool XBinary::isRelAddressValid(XBinary::_MEMORY_MAP *pMemoryMap, qint64 nRelAddress)
3006 {
3007     return isAddressValid(pMemoryMap,pMemoryMap->nModuleAddress+nRelAddress);
3008 }
3009 
isAddressPhysical(XBinary::_MEMORY_MAP * pMemoryMap,qint64 nAddress)3010 bool XBinary::isAddressPhysical(XBinary::_MEMORY_MAP *pMemoryMap, qint64 nAddress)
3011 {
3012     return (addressToOffset(pMemoryMap,nAddress)!=-1);
3013 }
3014 
offsetToAddress(XBinary::_MEMORY_MAP * pMemoryMap,qint64 nOffset)3015 qint64 XBinary::offsetToAddress(XBinary::_MEMORY_MAP *pMemoryMap, qint64 nOffset)
3016 {
3017     qint64 nResult=-1;
3018 
3019     int nNumberOfRecords=pMemoryMap->listRecords.count();
3020 
3021     for(int i=0; i<nNumberOfRecords; i++)
3022     {
3023         if(pMemoryMap->listRecords.at(i).nSize&&(pMemoryMap->listRecords.at(i).nOffset!=-1)&&(pMemoryMap->listRecords.at(i).nAddress!=-1))
3024         {
3025             if((pMemoryMap->listRecords.at(i).nOffset<=nOffset)&&(nOffset<pMemoryMap->listRecords.at(i).nOffset+pMemoryMap->listRecords.at(i).nSize))
3026             {
3027                 nResult=(nOffset-pMemoryMap->listRecords.at(i).nOffset)+pMemoryMap->listRecords.at(i).nAddress;
3028                 break;
3029             }
3030         }
3031     }
3032 
3033     return nResult;
3034 }
3035 
addressToOffset(XBinary::_MEMORY_MAP * pMemoryMap,qint64 nAddress)3036 qint64 XBinary::addressToOffset(XBinary::_MEMORY_MAP *pMemoryMap, qint64 nAddress)
3037 {
3038     qint64 nResult=-1;
3039 
3040     if(pMemoryMap->mode==MODE_16) // Check COM Check 16SEG
3041     {
3042         if(nAddress>0xFFFF)
3043         {
3044             nAddress=((nAddress>>16)&0xFFFF)*16+(nAddress&0xFFFF);
3045         }
3046     }
3047 
3048     int nNumberOfRecords=pMemoryMap->listRecords.count();
3049 
3050     for(int i=0; i<nNumberOfRecords; i++)
3051     {
3052         if(pMemoryMap->listRecords.at(i).nSize&&(pMemoryMap->listRecords.at(i).nAddress!=-1)&&(pMemoryMap->listRecords.at(i).nOffset!=-1))
3053         {
3054             if((pMemoryMap->listRecords.at(i).nAddress<=nAddress)&&(nAddress<pMemoryMap->listRecords.at(i).nAddress+pMemoryMap->listRecords.at(i).nSize))
3055             {
3056                 nResult=(nAddress-pMemoryMap->listRecords.at(i).nAddress)+pMemoryMap->listRecords.at(i).nOffset;
3057                 break;
3058             }
3059         }
3060     }
3061 
3062     return nResult;
3063 }
3064 
offsetToRelAddress(XBinary::_MEMORY_MAP * pMemoryMap,qint64 nOffset)3065 qint64 XBinary::offsetToRelAddress(XBinary::_MEMORY_MAP *pMemoryMap, qint64 nOffset)
3066 {
3067     qint64 nResult=offsetToAddress(pMemoryMap,nOffset);
3068 
3069     if(nResult!=-1)
3070     {
3071         nResult-=pMemoryMap->nModuleAddress;
3072     }
3073 
3074     return nResult;
3075 }
3076 
relAddressToOffset(XBinary::_MEMORY_MAP * pMemoryMap,qint64 nRelAddress)3077 qint64 XBinary::relAddressToOffset(XBinary::_MEMORY_MAP *pMemoryMap, qint64 nRelAddress)
3078 {
3079     return addressToOffset(pMemoryMap,nRelAddress+pMemoryMap->nModuleAddress);
3080 }
3081 
relAddressToAddress(XBinary::_MEMORY_MAP * pMemoryMap,qint64 nRelAddress)3082 qint64 XBinary::relAddressToAddress(XBinary::_MEMORY_MAP *pMemoryMap, qint64 nRelAddress)
3083 {
3084     qint64 nResult=-1;
3085 
3086     if(isRelAddressValid(pMemoryMap,nRelAddress))
3087     {
3088         nResult=nRelAddress+pMemoryMap->nModuleAddress;
3089     }
3090 
3091     return nResult;
3092 }
3093 
addressToRelAddress(XBinary::_MEMORY_MAP * pMemoryMap,qint64 nAddress)3094 qint64 XBinary::addressToRelAddress(XBinary::_MEMORY_MAP *pMemoryMap, qint64 nAddress)
3095 {
3096     qint64 nResult=-1;
3097 
3098     if(isAddressValid(pMemoryMap,nAddress))
3099     {
3100         nResult=nAddress-=pMemoryMap->nModuleAddress;
3101     }
3102 
3103     return nResult;
3104 }
3105 
getMemoryRecordByOffset(XBinary::_MEMORY_MAP * pMemoryMap,qint64 nOffset)3106 XBinary::_MEMORY_RECORD XBinary::getMemoryRecordByOffset(XBinary::_MEMORY_MAP *pMemoryMap, qint64 nOffset)
3107 {
3108     _MEMORY_RECORD result={};
3109 
3110     int nNumberOfRecords=pMemoryMap->listRecords.count();
3111 
3112     for(int i=0; i<nNumberOfRecords; i++)
3113     {
3114         if(pMemoryMap->listRecords.at(i).nSize&&(pMemoryMap->listRecords.at(i).nOffset!=-1))
3115         {
3116             if((pMemoryMap->listRecords.at(i).nOffset<=nOffset)&&(nOffset<pMemoryMap->listRecords.at(i).nOffset+pMemoryMap->listRecords.at(i).nSize))
3117             {
3118                 result=pMemoryMap->listRecords.at(i);
3119                 break;
3120             }
3121         }
3122     }
3123 
3124     return result;
3125 }
3126 
getMemoryRecordByAddress(XBinary::_MEMORY_MAP * pMemoryMap,qint64 nAddress)3127 XBinary::_MEMORY_RECORD XBinary::getMemoryRecordByAddress(XBinary::_MEMORY_MAP *pMemoryMap, qint64 nAddress)
3128 {
3129     _MEMORY_RECORD result={};
3130 
3131     int nNumberOfRecords=pMemoryMap->listRecords.count();
3132 
3133     for(int i=0; i<nNumberOfRecords; i++)
3134     {
3135         if(pMemoryMap->listRecords.at(i).nSize&&(pMemoryMap->listRecords.at(i).nAddress!=-1))
3136         {
3137             if((pMemoryMap->listRecords.at(i).nAddress<=nAddress)&&(nAddress<pMemoryMap->listRecords.at(i).nAddress+pMemoryMap->listRecords.at(i).nSize))
3138             {
3139                 result=pMemoryMap->listRecords.at(i);
3140                 break;
3141             }
3142         }
3143     }
3144 
3145     return result;
3146 }
3147 
getMemoryRecordByRelAddress(XBinary::_MEMORY_MAP * pMemoryMap,qint64 nRelAddress)3148 XBinary::_MEMORY_RECORD XBinary::getMemoryRecordByRelAddress(XBinary::_MEMORY_MAP *pMemoryMap, qint64 nRelAddress)
3149 {
3150     _MEMORY_RECORD result={};
3151 
3152     qint64 nAddress=relAddressToAddress(pMemoryMap,nRelAddress);
3153 
3154     if(nAddress!=-1)
3155     {
3156         getMemoryRecordByAddress(pMemoryMap,nAddress);
3157     }
3158 
3159     return result;
3160 }
3161 
addressToLoadSection(_MEMORY_MAP * pMemoryMap,qint64 nAddress)3162 qint32 XBinary::addressToLoadSection(_MEMORY_MAP *pMemoryMap, qint64 nAddress)
3163 {
3164     qint32 nResult=-1;
3165 
3166     _MEMORY_RECORD mm=getMemoryRecordByAddress(pMemoryMap,nAddress);
3167 
3168     if(mm.type==MMT_LOADSEGMENT)
3169     {
3170         nResult=mm.nLoadSection;
3171     }
3172 
3173     return nResult;
3174 }
3175 
isSolidAddressRange(XBinary::_MEMORY_MAP * pMemoryMap,qint64 nAddress,qint64 nSize)3176 bool XBinary::isSolidAddressRange(XBinary::_MEMORY_MAP *pMemoryMap, qint64 nAddress, qint64 nSize)
3177 {
3178     bool bResult=false;
3179 
3180     qint32 nIndex1=getMemoryRecordByAddress(pMemoryMap,nAddress).nIndex;
3181     qint32 nIndex2=getMemoryRecordByAddress(pMemoryMap,nAddress+nSize-1).nIndex;
3182 
3183     bResult=(nIndex1==nIndex2);
3184 
3185     return bResult;
3186 }
3187 
getMemoryRecordInfoByOffset(qint64 nOffset)3188 QString XBinary::getMemoryRecordInfoByOffset(qint64 nOffset)
3189 {
3190     _MEMORY_MAP memoryMap=getMemoryMap();
3191 
3192     return getMemoryRecordInfoByOffset(&memoryMap,nOffset);
3193 }
3194 
getMemoryRecordInfoByAddress(qint64 nAddress)3195 QString XBinary::getMemoryRecordInfoByAddress(qint64 nAddress)
3196 {
3197     _MEMORY_MAP memoryMap=getMemoryMap();
3198 
3199     return getMemoryRecordInfoByAddress(&memoryMap,nAddress);
3200 }
3201 
getMemoryRecordInfoByRelAddress(qint64 nRelAddress)3202 QString XBinary::getMemoryRecordInfoByRelAddress(qint64 nRelAddress)
3203 {
3204     _MEMORY_MAP memoryMap=getMemoryMap();
3205 
3206     return getMemoryRecordInfoByRelAddress(&memoryMap,nRelAddress);
3207 }
3208 
getMemoryRecordInfoByOffset(XBinary::_MEMORY_MAP * pMemoryMap,qint64 nOffset)3209 QString XBinary::getMemoryRecordInfoByOffset(XBinary::_MEMORY_MAP *pMemoryMap, qint64 nOffset)
3210 {
3211     XBinary::_MEMORY_RECORD memoryRecord=getMemoryRecordByOffset(pMemoryMap,nOffset);
3212 
3213     return getMemoryRecordInfo(&memoryRecord);
3214 }
3215 
getMemoryRecordInfoByAddress(XBinary::_MEMORY_MAP * pMemoryMap,qint64 nAddress)3216 QString XBinary::getMemoryRecordInfoByAddress(XBinary::_MEMORY_MAP *pMemoryMap, qint64 nAddress)
3217 {
3218     XBinary::_MEMORY_RECORD memoryRecord=getMemoryRecordByAddress(pMemoryMap,nAddress);
3219 
3220     return getMemoryRecordInfo(&memoryRecord);
3221 }
3222 
getMemoryRecordInfoByRelAddress(XBinary::_MEMORY_MAP * pMemoryMap,qint64 nRelAddress)3223 QString XBinary::getMemoryRecordInfoByRelAddress(XBinary::_MEMORY_MAP *pMemoryMap, qint64 nRelAddress)
3224 {
3225     XBinary::_MEMORY_RECORD memoryRecord=getMemoryRecordByAddress(pMemoryMap,nRelAddress+pMemoryMap->nModuleAddress);
3226 
3227     return getMemoryRecordInfo(&memoryRecord);
3228 }
3229 
getMemoryRecordInfo(XBinary::_MEMORY_RECORD * pMemoryRecord)3230 QString XBinary::getMemoryRecordInfo(XBinary::_MEMORY_RECORD *pMemoryRecord)
3231 {
3232     QString sRecord;
3233 
3234     sRecord=pMemoryRecord->sName; // TODO
3235 
3236     return sRecord;
3237 }
3238 
getMemoryMap()3239 XBinary::_MEMORY_MAP XBinary::getMemoryMap()
3240 {
3241     _MEMORY_MAP result={};
3242 
3243     qint64 nTotalSize=getSize();
3244 
3245     result.nModuleAddress=getModuleAddress();
3246     result.nRawSize=nTotalSize;
3247     result.nImageSize=nTotalSize;
3248     result.fileType=getFileType();
3249     result.mode=getMode();
3250     result.sArch=getArch();
3251     result.bIsBigEndian=isBigEndian();
3252     result.sType=getTypeAsString();
3253 
3254     _MEMORY_RECORD record={};
3255     record.nAddress=result.nModuleAddress;
3256     record.segment=ADDRESS_SEGMENT_FLAT;
3257     record.nOffset=0;
3258     record.nSize=nTotalSize;
3259     record.nIndex=0;
3260 
3261     result.listRecords.append(record);
3262 
3263     return result;
3264 }
3265 
getNumberOfPhysicalRecords(XBinary::_MEMORY_MAP * pMemoryMap)3266 qint32 XBinary::getNumberOfPhysicalRecords(XBinary::_MEMORY_MAP *pMemoryMap)
3267 {
3268     qint32 nResult=0;
3269 
3270     int nNumberOfRecords=pMemoryMap->listRecords.count();
3271 
3272     for(int i=0;i<nNumberOfRecords;i++)
3273     {
3274         if(!pMemoryMap->listRecords.at(i).bIsVirtual)
3275         {
3276             nResult++;
3277         }
3278     }
3279 
3280     return nResult;
3281 }
3282 
getBaseAddress()3283 qint64 XBinary::getBaseAddress()
3284 {
3285     return this->g_nBaseAddress;
3286 }
3287 
setBaseAddress(qint64 nBaseAddress)3288 void XBinary::setBaseAddress(qint64 nBaseAddress)
3289 {
3290     this->g_nBaseAddress=nBaseAddress;
3291 }
3292 
getImageSize()3293 qint64 XBinary::getImageSize()
3294 {
3295     return getSize();
3296 }
3297 
isImage()3298 bool XBinary::isImage()
3299 {
3300     return g_bIsImage;
3301 }
3302 
setIsImage(bool bValue)3303 void XBinary::setIsImage(bool bValue)
3304 {
3305     g_bIsImage=bValue;
3306 }
3307 
compareSignature(QString sSignature,qint64 nOffset)3308 bool XBinary::compareSignature(QString sSignature, qint64 nOffset)
3309 {
3310     _MEMORY_MAP memoryMap=getMemoryMap();
3311 
3312     return compareSignature(&memoryMap,sSignature,nOffset);
3313 }
3314 
compareSignature(_MEMORY_MAP * pMemoryMap,QString sSignature,qint64 nOffset)3315 bool XBinary::compareSignature(_MEMORY_MAP *pMemoryMap,QString sSignature, qint64 nOffset)
3316 {
3317     sSignature=convertSignature(sSignature);
3318 
3319     QList<SIGNATURE_RECORD> listSignatureRecords=getSignatureRecords(sSignature);
3320 
3321     return _compareSignature(pMemoryMap,&listSignatureRecords,nOffset);
3322 }
3323 
_compareByteArrayWithSignature(QByteArray baData,QString sSignature)3324 bool XBinary::_compareByteArrayWithSignature(QByteArray baData, QString sSignature)
3325 {
3326     bool bResult=false;
3327 
3328     QString sHex=baData.toHex().data();
3329 
3330     if(sHex.size()==sSignature.size())
3331     {
3332         bResult=true;
3333         int nNumberOfSymbols=sSignature.size();
3334 
3335         for(int i=0; i<nNumberOfSymbols; i++)
3336         {
3337             if(sSignature.at(i)!=QChar('.'))
3338             {
3339                 if(sSignature.at(i)!=sHex.at(i))
3340                 {
3341                     bResult=false;
3342                     break;
3343                 }
3344             }
3345         }
3346     }
3347 
3348     return bResult;
3349 }
3350 
_createSignature(QString sSignature1,QString sSignature2)3351 QString XBinary::_createSignature(QString sSignature1, QString sSignature2)
3352 {
3353     QString sResult;
3354 
3355     if(sSignature1.size()==sSignature2.size())
3356     {
3357         for(int i=0; i<sSignature1.size(); i+=2)
3358         {
3359             if(sSignature1.mid(i,2)==sSignature2.mid(i,2))
3360             {
3361                 sResult.append(sSignature1.mid(i,2));
3362             }
3363             else
3364             {
3365                 sResult.append("..");
3366             }
3367         }
3368     }
3369 
3370     return sResult;
3371 }
3372 
compareSignatureOnAddress(QString sSignature,qint64 nAddress)3373 bool XBinary::compareSignatureOnAddress(QString sSignature, qint64 nAddress)
3374 {
3375     XBinary::_MEMORY_MAP memoryMap=getMemoryMap();
3376 
3377     return compareSignatureOnAddress(&memoryMap,sSignature,nAddress);
3378 }
3379 
compareSignatureOnAddress(XBinary::_MEMORY_MAP * pMemoryMap,QString sSignature,qint64 nAddress)3380 bool XBinary::compareSignatureOnAddress(XBinary::_MEMORY_MAP *pMemoryMap, QString sSignature, qint64 nAddress)
3381 {
3382     bool bResult=false;
3383 
3384     qint64 nOffset=addressToOffset(pMemoryMap,nAddress);
3385 
3386     if(nOffset!=-1)
3387     {
3388         bResult=compareSignature(pMemoryMap,sSignature,nOffset);
3389     }
3390 
3391     return bResult;
3392 }
3393 
_getEntryPointOffset()3394 qint64 XBinary::_getEntryPointOffset()
3395 {
3396     XBinary::_MEMORY_MAP memoryMap=getMemoryMap();
3397 
3398     return getEntryPointOffset(&memoryMap);
3399 }
3400 
getEntryPointOffset(_MEMORY_MAP * pMemoryMap)3401 qint64 XBinary::getEntryPointOffset(_MEMORY_MAP *pMemoryMap)
3402 {
3403     Q_UNUSED(pMemoryMap)
3404 
3405     return this->g_nEntryPointOffset;
3406 }
3407 
setEntryPointOffset(qint64 nEntryPointOffset)3408 void XBinary::setEntryPointOffset(qint64 nEntryPointOffset)
3409 {
3410     this->g_nEntryPointOffset=nEntryPointOffset;
3411 }
3412 
getEntryPointAddress()3413 qint64 XBinary::getEntryPointAddress()
3414 {
3415     XBinary::_MEMORY_MAP memoryMap=getMemoryMap();
3416 
3417     return getEntryPointAddress(&memoryMap);
3418 }
3419 
getEntryPointAddress(XBinary::_MEMORY_MAP * pMemoryMap)3420 qint64 XBinary::getEntryPointAddress(XBinary::_MEMORY_MAP *pMemoryMap)
3421 {
3422     qint64 nEntryPointOffset=getEntryPointOffset(pMemoryMap);
3423 
3424     return offsetToAddress(pMemoryMap,nEntryPointOffset);
3425 }
3426 
getLowestAddress(XBinary::_MEMORY_MAP * pMemoryMap)3427 qint64 XBinary::getLowestAddress(XBinary::_MEMORY_MAP *pMemoryMap)
3428 {
3429     qint64 nResult=-1;
3430 
3431     int nNumberOfRecords=pMemoryMap->listRecords.count();
3432 
3433     for(int i=0;i<nNumberOfRecords;i++)
3434     {
3435         if(pMemoryMap->listRecords.at(i).nAddress!=-1)
3436         {
3437             if(nResult==-1)
3438             {
3439                 nResult=pMemoryMap->listRecords.at(i).nAddress;
3440             }
3441 
3442             nResult=qMin(pMemoryMap->listRecords.at(i).nAddress,nResult);
3443         }
3444     }
3445 
3446     return nResult;
3447 }
3448 
getTotalVirtualSize(XBinary::_MEMORY_MAP * pMemoryMap)3449 qint64 XBinary::getTotalVirtualSize(XBinary::_MEMORY_MAP *pMemoryMap)
3450 {
3451     qint64 nResult=0;
3452 
3453     int nNumberOfRecords=pMemoryMap->listRecords.count();
3454 
3455     for(int i=0;i<nNumberOfRecords;i++)
3456     {
3457         if(pMemoryMap->listRecords.at(i).type!=MMT_OVERLAY) // TODO Check ELF
3458         {
3459             nResult+=pMemoryMap->listRecords.at(i).nSize;
3460         }
3461     }
3462 
3463     return nResult;
3464 }
3465 
positionToVirtualAddress(_MEMORY_MAP * pMemoryMap,qint64 nPosition)3466 qint64 XBinary::positionToVirtualAddress(_MEMORY_MAP *pMemoryMap,qint64 nPosition)
3467 {
3468     qint64 nResult=-1;
3469 
3470     int nNumberOfRecords=pMemoryMap->listRecords.count();
3471 
3472     qint64 _nSize=0;
3473 
3474     for(int i=0;i<nNumberOfRecords;i++)
3475     {
3476         if((_nSize<=nPosition)&&(nPosition<_nSize+pMemoryMap->listRecords.at(i).nSize))
3477         {
3478             nResult=pMemoryMap->listRecords.at(i).nAddress+(nPosition-_nSize);
3479         }
3480 
3481        _nSize+=pMemoryMap->listRecords.at(i).nSize;
3482     }
3483 
3484     return nResult;
3485 }
3486 
setModuleAddress(qint64 nValue)3487 void XBinary::setModuleAddress(qint64 nValue)
3488 {
3489     this->g_nModuleAddress=nValue;
3490 }
3491 
getModuleAddress()3492 qint64 XBinary::getModuleAddress()
3493 {
3494     qint64 nResult=0;
3495 
3496     if(g_nModuleAddress!=-1)
3497     {
3498         nResult=g_nModuleAddress;
3499     }
3500     else
3501     {
3502         nResult=getBaseAddress();
3503     }
3504 
3505     return nResult;
3506 }
3507 
compareEntryPoint(QString sSignature,qint64 nOffset)3508 bool XBinary::compareEntryPoint(QString sSignature, qint64 nOffset)
3509 {
3510     XBinary::_MEMORY_MAP memoryMap=getMemoryMap();
3511 
3512     return compareEntryPoint(&memoryMap,sSignature,nOffset);
3513 }
3514 
compareEntryPoint(XBinary::_MEMORY_MAP * pMemoryMap,QString sSignature,qint64 nOffset)3515 bool XBinary::compareEntryPoint(XBinary::_MEMORY_MAP *pMemoryMap, QString sSignature, qint64 nOffset)
3516 {
3517     qint64 nEPOffset=getEntryPointOffset(pMemoryMap)+nOffset;
3518 
3519     return compareSignature(pMemoryMap,sSignature,nEPOffset);
3520 }
3521 
moveMemory(qint64 nSourceOffset,qint64 nDestOffset,qint64 nSize)3522 bool XBinary::moveMemory(qint64 nSourceOffset,qint64 nDestOffset, qint64 nSize)
3523 {
3524     bool bResult=false;
3525 
3526     if(nDestOffset==nSourceOffset)
3527     {
3528         return true;
3529     }
3530 
3531     qint64 nMaxSize=getSize();
3532 
3533     if((nDestOffset+nSize>nMaxSize)||(nSourceOffset+nSize>nMaxSize))
3534     {
3535         return false;
3536     }
3537 
3538     qint64 nDelta=nDestOffset-nSourceOffset;
3539 
3540     if(nDelta>0)
3541     {
3542         bResult=copyMemory(nSourceOffset,nDestOffset,nSize,nDelta,true);
3543         zeroFill(nSourceOffset,nDelta);
3544     }
3545     else
3546     {
3547         bResult=copyMemory(nSourceOffset,nDestOffset,nSize,-nDelta,false);
3548         zeroFill(nDestOffset+nSize,-nDelta);
3549     }
3550 
3551     return bResult;
3552 }
3553 
dumpToFile(QString sFileName,const char * pData,qint64 nDataSize)3554 bool XBinary::dumpToFile(QString sFileName, const char *pData, qint64 nDataSize)
3555 {
3556     bool bResult=false;
3557 
3558     QFile file;
3559     file.setFileName(sFileName);
3560     file.resize(0);
3561 
3562     if(file.open(QIODevice::ReadWrite))
3563     {
3564         file.write(pData,nDataSize);
3565 
3566         bResult=true;
3567 
3568         file.close();
3569     }
3570 
3571     return bResult;
3572 }
3573 
dumpToFile(QString sFileName,qint64 nDataOffset,qint64 nDataSize)3574 bool XBinary::dumpToFile(QString sFileName, qint64 nDataOffset, qint64 nDataSize)
3575 {
3576     bool bResult=false;
3577 
3578     PROCENT procent=procentInit(nDataSize);
3579 
3580     QFile file;
3581     file.setFileName(sFileName);
3582 
3583     if(file.open(QIODevice::ReadWrite))
3584     {
3585         file.resize(0);
3586 
3587         _dumpProgressMinimumChanged(0);
3588         _dumpProgressMaximumChanged(procent.nMaxProcent);
3589         _dumpProgressValueChanged(0);
3590 
3591         char *pBuffer=new char[0x1000]; // TODO const
3592 
3593         qint64 nSourceOffset=nDataOffset;
3594         qint64 nDestOffset=0;
3595 
3596         bResult=true;
3597 
3598         while((nDataSize>0)&&(!g_bIsDumpStop))
3599         {
3600             qint64 nTempSize=qMin(nDataSize,(qint64)0x1000); // TODO const
3601 
3602             if(safeReadData(g_pDevice,nSourceOffset,pBuffer,nTempSize)!=nTempSize)
3603             {
3604                 _errorMessage(QObject::tr("Read error"));
3605                 bResult=false;
3606                 break;
3607             }
3608 
3609             if(!((file.seek(nDestOffset))&&(file.write(pBuffer,nTempSize)==nTempSize)))
3610             {
3611                 _errorMessage(QObject::tr("Write error"));
3612                 bResult=false;
3613                 break;
3614             }
3615 
3616             nSourceOffset+=nTempSize;
3617             nDestOffset+=nTempSize;
3618 
3619             nDataSize-=nTempSize;
3620 
3621             if(procentSetCurrentValue(&procent,nDestOffset))
3622             {
3623                 _dumpProgressValueChanged(procent.nCurrentProcent);
3624             }
3625         }
3626 
3627         _dumpProgressValueChanged(procent.nMaxProcent);
3628 
3629         delete [] pBuffer;
3630 
3631         file.close();
3632     }
3633     else
3634     {
3635         _errorMessage(QString("%1: %2").arg(QObject::tr("Cannot open file"),sFileName));
3636     }
3637 
3638     return bResult;
3639 }
3640 
getFileTypes(bool bExtra)3641 QSet<XBinary::FT> XBinary::getFileTypes(bool bExtra)
3642 {
3643     QSet<XBinary::FT> stResult;
3644 
3645     stResult.insert(FT_BINARY);
3646 
3647     QByteArray baHeader;
3648     baHeader=read_array(0,qMin(getSize(),(qint64)0x200)); // TODO const
3649     char *pOffset=baHeader.data();
3650     unsigned int nSize=getSize();
3651 
3652     if(nSize>=(int)sizeof(XMSDOS_DEF::IMAGE_DOS_HEADEREX))
3653     {
3654         if( (((XMSDOS_DEF::IMAGE_DOS_HEADEREX *)pOffset)->e_magic==XMSDOS_DEF::S_IMAGE_DOS_SIGNATURE_MZ)||
3655             (((XMSDOS_DEF::IMAGE_DOS_HEADEREX *)pOffset)->e_magic==XMSDOS_DEF::S_IMAGE_DOS_SIGNATURE_ZM))
3656         {
3657             stResult.insert(FT_MSDOS);
3658             // TODO rewrite for NE, LE
3659             unsigned int nLfanew=((XMSDOS_DEF::IMAGE_DOS_HEADEREX *)pOffset)->e_lfanew;
3660             unsigned int nHeaderSize=baHeader.size()-sizeof(XPE_DEF::IMAGE_NT_HEADERS32);
3661             QByteArray baNewHeader;
3662 
3663             bool bIsNewHeaderValid=false;
3664 
3665             if((nLfanew<nHeaderSize)&&((quint32)baHeader.size()>(nLfanew+sizeof(XPE_DEF::IMAGE_NT_HEADERS32)))) // TODO do not use IMAGE_NT_HEADERS32
3666             {
3667                 pOffset+=nLfanew;
3668                 bIsNewHeaderValid=true;
3669             }
3670             else
3671             {
3672                 qint64 nNtHeadersSize=4+sizeof(XPE_DEF::IMAGE_FILE_HEADER);
3673 
3674                 baNewHeader=read_array(nLfanew,nNtHeadersSize);
3675 
3676                 nHeaderSize=baNewHeader.size();
3677 
3678                 if(nHeaderSize==nNtHeadersSize)
3679                 {
3680                     pOffset=baNewHeader.data();
3681                     bIsNewHeaderValid=true;
3682                 }
3683             }
3684 
3685             if(bIsNewHeaderValid)
3686             {
3687                 if((((XPE_DEF::IMAGE_NT_HEADERS32 *)pOffset))->Signature==XPE_DEF::S_IMAGE_NT_SIGNATURE)
3688                 {
3689                     stResult.insert(FT_PE);
3690 
3691                     quint16 nMachine=((XPE_DEF::IMAGE_NT_HEADERS32 *)pOffset)->FileHeader.Machine;
3692 
3693                     // TODO more
3694                     if( (nMachine==XPE_DEF::S_IMAGE_FILE_MACHINE_AMD64)||
3695                         (nMachine==XPE_DEF::S_IMAGE_FILE_MACHINE_IA64)||
3696                         (nMachine==XPE_DEF::S_IMAGE_FILE_MACHINE_ARM64))
3697                     {
3698                         stResult.insert(FT_PE64);
3699                     }
3700                     else
3701                     {
3702                         stResult.insert(FT_PE32);
3703                     }
3704                 }
3705                 else if((((XNE_DEF::IMAGE_OS2_HEADER *)pOffset))->ne_magic==XNE_DEF::S_IMAGE_OS2_SIGNATURE)
3706                 {
3707                     stResult.insert(FT_NE);
3708                 }
3709                 else if((((XPE_DEF::IMAGE_NT_HEADERS32 *)pOffset))->Signature==XLE_DEF::S_IMAGE_VXD_SIGNATURE)
3710                 {
3711                     stResult.insert(FT_LE);
3712                 }
3713                 else if((((XPE_DEF::IMAGE_NT_HEADERS32 *)pOffset))->Signature==XLE_DEF::S_IMAGE_LX_SIGNATURE)
3714                 {
3715                     stResult.insert(FT_LX);
3716                 }
3717             }
3718         }
3719     }
3720 
3721     if(nSize>=(int)sizeof(XELF_DEF::Elf32_Ehdr))
3722     {
3723         if( (((XELF_DEF::Elf32_Ehdr *)pOffset)->e_ident[0]==0x7f) &&
3724             (((XELF_DEF::Elf32_Ehdr *)pOffset)->e_ident[1]=='E') &&
3725             (((XELF_DEF::Elf32_Ehdr *)pOffset)->e_ident[2]=='L') &&
3726             (((XELF_DEF::Elf32_Ehdr *)pOffset)->e_ident[3]=='F'))
3727         {
3728             stResult.insert(FT_ELF);
3729 
3730             if(((XELF_DEF::Elf32_Ehdr *)pOffset)->e_ident[4]==1)
3731             {
3732                 stResult.insert(FT_ELF32);
3733             }
3734             else if(((XELF_DEF::Elf32_Ehdr *)pOffset)->e_ident[4]==2)
3735             {
3736                 stResult.insert(FT_ELF64);
3737             }
3738             // mb TODO another e_ident[4]
3739         }
3740     }
3741 
3742     if(nSize>=(int)sizeof(XMACH_DEF::mach_header))
3743     {
3744         if((((XMACH_DEF::mach_header *)pOffset)->magic==XMACH_DEF::S_MH_MAGIC)||(((XMACH_DEF::mach_header *)pOffset)->magic==XMACH_DEF::S_MH_CIGAM))
3745         {
3746             stResult.insert(FT_MACHO);
3747             stResult.insert(FT_MACHO32);
3748         }
3749         else if((((XMACH_DEF::mach_header *)pOffset)->magic==XMACH_DEF::S_MH_MAGIC_64)||(((XMACH_DEF::mach_header *)pOffset)->magic==XMACH_DEF::S_MH_CIGAM_64))
3750         {
3751             stResult.insert(FT_MACHO);
3752             stResult.insert(FT_MACHO64);
3753         }
3754     }
3755 
3756     if(bExtra)
3757     {
3758         _MEMORY_MAP memoryMap=XBinary::getMemoryMap();
3759         UNICODE_TYPE unicodeType=getUnicodeType(&baHeader);
3760 
3761         if(compareSignature(&memoryMap,"'PK'0304",0)||compareSignature(&memoryMap,"'PK'0506",0)) // TODO baHeader
3762         {
3763             stResult.insert(FT_ARCHIVE);
3764             stResult.insert(FT_ZIP);
3765             // TODO Check APK, JAR
3766             // TODO basic ZIP
3767         }
3768         else if(compareSignature(&memoryMap,"CAFEBABE",0))
3769         {
3770             if(read_uint32(4,true)<10)
3771             {
3772                 stResult.insert(FT_ARCHIVE);
3773                 stResult.insert(FT_MACHOFAT);
3774             }
3775         }
3776         else if(compareSignature(&memoryMap,"BEBAFECA",0))
3777         {
3778             if(read_uint32(4,false)<10)
3779             {
3780                 stResult.insert(FT_ARCHIVE);
3781                 stResult.insert(FT_MACHOFAT);
3782             }
3783         }
3784         else if(compareSignature(&memoryMap,"89'PNG\r\n'1A0A........'IHDR'",0))
3785         {
3786             stResult.insert(FT_IMAGE);
3787             stResult.insert(FT_PNG);
3788         }
3789         else if(compareSignature(&memoryMap,"FFD8FFE0....'JFIF'00",0))
3790         {
3791             stResult.insert(FT_IMAGE);
3792             stResult.insert(FT_JPEG);
3793         }
3794         else if(compareSignature(&memoryMap,"'GIF8'",0))
3795         {
3796             stResult.insert(FT_IMAGE);
3797             stResult.insert(FT_GIF);
3798         }
3799         else if(compareSignature(&memoryMap,"'MM'002A",0)||compareSignature(&memoryMap,"'II'2A00",0))
3800         {
3801             stResult.insert(FT_IMAGE);
3802             stResult.insert(FT_TIFF);
3803         }
3804         else if(compareSignature(&memoryMap,"'dex\n'......00"))
3805         {
3806             stResult.insert(FT_DEX);
3807         }
3808         else if(compareSignature(&memoryMap,"02000C00"))
3809         {
3810             stResult.insert(FT_ANDROIDASRC);
3811         }
3812         else if(compareSignature(&memoryMap,"03000800"))
3813         {
3814             stResult.insert(FT_ANDROIDXML);
3815         }
3816 
3817         if(isPlainTextType(&baHeader))
3818         {
3819             stResult.insert(FT_TEXT);
3820             stResult.insert(FT_PLAINTEXT);
3821         }
3822         else if(isUTF8TextType(&baHeader))
3823         {
3824             stResult.insert(FT_TEXT);
3825             stResult.insert(FT_UTF8);
3826         }
3827         else if(unicodeType!=UNICODE_TYPE_NONE)
3828         {
3829             stResult.insert(FT_TEXT);
3830             stResult.insert(FT_UNICODE);
3831 
3832             if(unicodeType==UNICODE_TYPE_LE)
3833             {
3834                 stResult.insert(FT_UNICODE_LE);
3835             }
3836             else
3837             {
3838                 stResult.insert(FT_UNICODE_BE);
3839             }
3840         }
3841         // TODO more
3842         // TODO MIME
3843 
3844         // Fix
3845         if(stResult.contains(FT_GIF)&&stResult.contains(FT_TEXT))
3846         {
3847             stResult.remove(FT_GIF);
3848         }
3849     }
3850 
3851     return stResult;
3852 }
3853 
getFileTypes(QIODevice * pDevice,bool bExtra)3854 QSet<XBinary::FT> XBinary::getFileTypes(QIODevice *pDevice,bool bExtra)
3855 {
3856     XBinary _binary(pDevice);
3857 
3858     return _binary.getFileTypes(bExtra);
3859 }
3860 
getFileTypes(QString sFileName,bool bExtra)3861 QSet<XBinary::FT> XBinary::getFileTypes(QString sFileName,bool bExtra)
3862 {
3863     QSet<XBinary::FT> result;
3864 
3865     QFile file;
3866     file.setFileName(sFileName);
3867 
3868     if(file.open(QIODevice::ReadOnly))
3869     {
3870         XBinary _binary(&file);
3871 
3872         result=_binary.getFileTypes(bExtra);
3873 
3874         file.close();
3875     }
3876 
3877     return result;
3878 }
3879 
getFileTypes(QByteArray * pbaData,bool bExtra)3880 QSet<XBinary::FT> XBinary::getFileTypes(QByteArray *pbaData,bool bExtra)
3881 {
3882     QSet<XBinary::FT> result;
3883 
3884     QBuffer buffer;
3885 
3886     buffer.setBuffer(pbaData);
3887 
3888     if(buffer.open(QIODevice::ReadOnly))
3889     {
3890         XBinary _binary(&buffer);
3891 
3892         result=_binary.getFileTypes(bExtra);
3893 
3894         buffer.close();
3895     }
3896 
3897     return result;
3898 }
3899 
getPrefFileType(QIODevice * pDevice,bool bExtra)3900 XBinary::FT XBinary::getPrefFileType(QIODevice *pDevice, bool bExtra)
3901 {
3902     XBinary::FT result=FT_UNKNOWN;
3903 
3904     QSet<XBinary::FT> stFileTypes=getFileTypes(pDevice,bExtra);
3905 
3906     if(stFileTypes.contains(FT_PE32))
3907     {
3908         result=FT_PE32;
3909     }
3910     else if(stFileTypes.contains(FT_PE64))
3911     {
3912         result=FT_PE64;
3913     }
3914     else if(stFileTypes.contains(FT_MACHO32))
3915     {
3916         result=FT_MACHO32;
3917     }
3918     else if(stFileTypes.contains(FT_MACHO64))
3919     {
3920         result=FT_MACHO64;
3921     }
3922     else if(stFileTypes.contains(FT_ELF32))
3923     {
3924         result=FT_ELF32;
3925     }
3926     else if(stFileTypes.contains(FT_ELF64))
3927     {
3928         result=FT_ELF64;
3929     }
3930     else if(stFileTypes.contains(FT_LE))
3931     {
3932         result=FT_LE;
3933     }
3934     else if(stFileTypes.contains(FT_LX))
3935     {
3936         result=FT_LX;
3937     }
3938     else if(stFileTypes.contains(FT_NE))
3939     {
3940         result=FT_NE;
3941     }
3942     else if(stFileTypes.contains(FT_MSDOS))
3943     {
3944         result=FT_MSDOS;
3945     }
3946     else if(stFileTypes.contains(FT_ZIP))
3947     {
3948         result=FT_ZIP;
3949     }
3950     else if(stFileTypes.contains(FT_BINARY))
3951     {
3952         result=FT_BINARY;
3953     }
3954 
3955     return result;
3956 }
3957 
_getFileTypeListFromSet(QSet<XBinary::FT> stFileTypes)3958 QList<XBinary::FT> XBinary::_getFileTypeListFromSet(QSet<XBinary::FT> stFileTypes)
3959 {
3960     QList<XBinary::FT> listResult;
3961 
3962     if(stFileTypes.contains(FT_BINARY))     listResult.append(FT_BINARY);
3963     if(stFileTypes.contains(FT_BINARY16))   listResult.append(FT_BINARY16);
3964     if(stFileTypes.contains(FT_BINARY32))   listResult.append(FT_BINARY32);
3965     if(stFileTypes.contains(FT_BINARY64))   listResult.append(FT_BINARY64);
3966     if(stFileTypes.contains(FT_ZIP))        listResult.append(FT_ZIP);
3967     if(stFileTypes.contains(FT_DEX))        listResult.append(FT_DEX);
3968     if(stFileTypes.contains(FT_COM))        listResult.append(FT_COM);
3969     if(stFileTypes.contains(FT_MSDOS))      listResult.append(FT_MSDOS);
3970     if(stFileTypes.contains(FT_NE))         listResult.append(FT_NE);
3971     if(stFileTypes.contains(FT_LE))         listResult.append(FT_LE);
3972     if(stFileTypes.contains(FT_LX))         listResult.append(FT_LX);
3973     if(stFileTypes.contains(FT_PE32))       listResult.append(FT_PE32);
3974     if(stFileTypes.contains(FT_PE64))       listResult.append(FT_PE64);
3975     if(stFileTypes.contains(FT_ELF32))      listResult.append(FT_ELF32);
3976     if(stFileTypes.contains(FT_ELF64))      listResult.append(FT_ELF64);
3977     if(stFileTypes.contains(FT_MACHO32))     listResult.append(FT_MACHO32);
3978     if(stFileTypes.contains(FT_MACHO64))     listResult.append(FT_MACHO64);
3979 
3980     return listResult;
3981 }
3982 
valueToHex(quint8 nValue)3983 QString XBinary::valueToHex(quint8 nValue)
3984 {
3985     return QString("%1").arg(nValue,2,16,QChar('0'));
3986 }
3987 
valueToHex(qint8 nValue)3988 QString XBinary::valueToHex(qint8 nValue)
3989 {
3990     return valueToHex((quint8)nValue);
3991 }
3992 
valueToHex(quint16 nValue,bool bIsBigEndian)3993 QString XBinary::valueToHex(quint16 nValue, bool bIsBigEndian)
3994 {
3995     if(bIsBigEndian)
3996     {
3997         nValue=qFromBigEndian(nValue);
3998     }
3999     else
4000     {
4001         nValue=qFromLittleEndian(nValue);
4002     }
4003 
4004     return QString("%1").arg(nValue,4,16,QChar('0'));
4005 }
4006 
valueToHex(qint16 nValue,bool bIsBigEndian)4007 QString XBinary::valueToHex(qint16 nValue, bool bIsBigEndian)
4008 {
4009     if(bIsBigEndian)
4010     {
4011         nValue=qFromBigEndian(nValue);
4012     }
4013     else
4014     {
4015         nValue=qFromLittleEndian(nValue);
4016     }
4017 
4018     return valueToHex((quint16)nValue);
4019 }
4020 
valueToHex(quint32 nValue,bool bIsBigEndian)4021 QString XBinary::valueToHex(quint32 nValue, bool bIsBigEndian)
4022 {
4023     if(bIsBigEndian)
4024     {
4025         nValue=qFromBigEndian(nValue);
4026     }
4027     else
4028     {
4029         nValue=qFromLittleEndian(nValue);
4030     }
4031 
4032     return QString("%1").arg(nValue,8,16,QChar('0'));
4033 }
4034 
valueToHex(qint32 nValue,bool bIsBigEndian)4035 QString XBinary::valueToHex(qint32 nValue, bool bIsBigEndian)
4036 {
4037     if(bIsBigEndian)
4038     {
4039         nValue=qFromBigEndian(nValue);
4040     }
4041     else
4042     {
4043         nValue=qFromLittleEndian(nValue);
4044     }
4045 
4046     return valueToHex((quint32)nValue);
4047 }
4048 
valueToHex(quint64 nValue,bool bIsBigEndian)4049 QString XBinary::valueToHex(quint64 nValue, bool bIsBigEndian)
4050 {
4051     if(bIsBigEndian)
4052     {
4053         nValue=qFromBigEndian(nValue);
4054     }
4055     else
4056     {
4057         nValue=qFromLittleEndian(nValue);
4058     }
4059 
4060     return QString("%1").arg(nValue,16,16,QChar('0'));
4061 }
4062 
valueToHex(qint64 nValue,bool bIsBigEndian)4063 QString XBinary::valueToHex(qint64 nValue, bool bIsBigEndian)
4064 {
4065     if(bIsBigEndian)
4066     {
4067         nValue=qFromBigEndian(nValue);
4068     }
4069     else
4070     {
4071         nValue=qFromLittleEndian(nValue);
4072     }
4073 
4074     return valueToHex((quint64)nValue);
4075 }
4076 
valueToHex(float fValue,bool bIsBigEndian)4077 QString XBinary::valueToHex(float fValue, bool bIsBigEndian)
4078 {
4079     float _value=fValue;
4080 
4081     endian_float(&_value,bIsBigEndian);
4082 
4083     quint32 _nValue=0;
4084 
4085     _copyMemory((char *)&_nValue,(char *)&_value,4);
4086 
4087     return QString("%1").arg(_nValue,8,16,QChar('0'));
4088 }
4089 
valueToHex(double dValue,bool bIsBigEndian)4090 QString XBinary::valueToHex(double dValue, bool bIsBigEndian)
4091 {
4092     double _value=dValue;
4093 
4094     endian_double(&_value,bIsBigEndian);
4095 
4096     quint64 _nValue=0;
4097 
4098     _copyMemory((char *)&_nValue,(char *)&_value,8);
4099 
4100     return QString("%1").arg(_nValue,16,16,QChar('0'));
4101 }
4102 
valueToHex(XBinary::MODE mode,quint64 nValue,bool bIsBigEndian)4103 QString XBinary::valueToHex(XBinary::MODE mode, quint64 nValue, bool bIsBigEndian)
4104 {
4105     QString sResult;
4106 
4107     if(mode==MODE_UNKNOWN)
4108     {
4109         mode=getWidthModeFromSize(nValue);
4110     }
4111 
4112     if(mode==MODE_8)
4113     {
4114         sResult=valueToHex((quint8)nValue);
4115     }
4116     else if(mode==MODE_16)
4117     {
4118         sResult=valueToHex((quint16)nValue,bIsBigEndian);
4119     }
4120     else if(mode==MODE_32)
4121     {
4122         sResult=valueToHex((quint32)nValue,bIsBigEndian);
4123     }
4124     else if(mode==MODE_64)
4125     {
4126         sResult=valueToHex((quint64)nValue,bIsBigEndian);
4127     }
4128 
4129     return sResult;
4130 }
4131 
valueToHexEx(quint64 nValue,bool bIsBigEndian)4132 QString XBinary::valueToHexEx(quint64 nValue, bool bIsBigEndian)
4133 {
4134     XBinary::MODE mode=getWidthModeFromSize(nValue);
4135 
4136     return valueToHex(mode,nValue,bIsBigEndian);
4137 }
4138 
checkString_uint8(QString sValue)4139 bool XBinary::checkString_uint8(QString sValue)
4140 {
4141     bool bResult=false;
4142 
4143     // TODO Check
4144 
4145     quint16 nValue=sValue.toUShort(&bResult);
4146 
4147     if(bResult)
4148     {
4149         bResult=(nValue<=256);
4150     }
4151 
4152     return bResult;
4153 }
4154 
checkString_int8(QString sValue)4155 bool XBinary::checkString_int8(QString sValue)
4156 {
4157     bool bResult=false;
4158 
4159     qint16 nValue=sValue.toShort(&bResult);
4160 
4161     if(bResult)
4162     {
4163         bResult=((-127<=nValue)&&(nValue<=128));
4164     }
4165 
4166     return bResult;
4167 }
4168 
checkString_uint16(QString sValue)4169 bool XBinary::checkString_uint16(QString sValue)
4170 {
4171     bool bResult=false;
4172 
4173     sValue.toUShort(&bResult);
4174 
4175     return bResult;
4176 }
4177 
checkString_int16(QString sValue)4178 bool XBinary::checkString_int16(QString sValue)
4179 {
4180     bool bResult=false;
4181 
4182     sValue.toShort(&bResult);
4183 
4184     return bResult;
4185 }
4186 
checkString_uint32(QString sValue)4187 bool XBinary::checkString_uint32(QString sValue)
4188 {
4189     bool bResult=false;
4190 
4191     sValue.toUInt(&bResult);
4192 
4193     return bResult;
4194 }
4195 
checkString_int32(QString sValue)4196 bool XBinary::checkString_int32(QString sValue)
4197 {
4198     bool bResult=false;
4199 
4200     sValue.toInt(&bResult);
4201 
4202     return bResult;
4203 }
4204 
checkString_uint64(QString sValue)4205 bool XBinary::checkString_uint64(QString sValue)
4206 {
4207     bool bResult=false;
4208 
4209     sValue.toULongLong(&bResult);
4210 
4211     return bResult;
4212 }
4213 
checkString_int64(QString sValue)4214 bool XBinary::checkString_int64(QString sValue)
4215 {
4216     bool bResult=false;
4217 
4218     sValue.toLongLong(&bResult);
4219 
4220     return bResult;
4221 }
4222 
checkString_float(QString sValue)4223 bool XBinary::checkString_float(QString sValue)
4224 {
4225     bool bResult=false;
4226 
4227     sValue.toFloat(&bResult);
4228 
4229     return bResult;
4230 }
4231 
checkString_double(QString sValue)4232 bool XBinary::checkString_double(QString sValue)
4233 {
4234     bool bResult=false;
4235 
4236     sValue.toDouble(&bResult);
4237 
4238     return bResult;
4239 }
4240 
boolToString(bool bValue)4241 QString XBinary::boolToString(bool bValue)
4242 {
4243     QString sResult;
4244 
4245     if(bValue)
4246     {
4247         sResult="true";
4248     }
4249     else
4250     {
4251         sResult="false";
4252     }
4253 
4254     return sResult;
4255 }
4256 
getSpaces(qint32 nNumberOfSpaces)4257 QString XBinary::getSpaces(qint32 nNumberOfSpaces)
4258 {
4259     QString sResult;
4260 
4261     sResult=sResult.rightJustified(nNumberOfSpaces,QChar(' '));
4262 
4263     return sResult;
4264 }
4265 
getUnpackedFileName(QIODevice * pDevice)4266 QString XBinary::getUnpackedFileName(QIODevice *pDevice)
4267 {
4268     QString sResult="unpacked";
4269 
4270     QString sClassName=pDevice->metaObject()->className();
4271 
4272     if(sClassName=="QFile")
4273     {
4274         QFile *pFile=(QFile *)pDevice;
4275 
4276         QString sFileName=pFile->fileName(); // TODO
4277 
4278         if(sFileName!="")
4279         {
4280             sResult=getUnpackedFileName(sFileName);
4281         }
4282     }
4283 
4284     return sResult;
4285 }
4286 
getUnpackedFileName(QString sFileName)4287 QString XBinary::getUnpackedFileName(QString sFileName)
4288 {
4289     QFileInfo fileInfo(sFileName);
4290     QString sResult=fileInfo.absolutePath()+QDir::separator()+fileInfo.completeBaseName()+".unp."+fileInfo.suffix();
4291     //            sResult=fi.absolutePath()+QDir::separator()+fi.baseName()+".unp."+fi.completeSuffix();
4292 
4293     return sResult;
4294 }
4295 
getDumpFileName(QIODevice * pDevice)4296 QString XBinary::getDumpFileName(QIODevice *pDevice)
4297 {
4298     QString sResult="dump";
4299 
4300     QString sClassName=pDevice->metaObject()->className();
4301 
4302     if(sClassName=="QFile")
4303     {
4304         QFile *pFile=(QFile *)pDevice;
4305 
4306         QString sFileName=pFile->fileName(); // TODO
4307 
4308         if(sFileName!="")
4309         {
4310             sResult=getDumpFileName(sFileName);
4311         }
4312     }
4313 
4314     return sResult;
4315 }
4316 
getDumpFileName(QString sFileName)4317 QString XBinary::getDumpFileName(QString sFileName)
4318 {
4319     QFileInfo fileInfo(sFileName);
4320     QString sResult=fileInfo.absolutePath()+QDir::separator()+fileInfo.completeBaseName()+".dump."+fileInfo.suffix();
4321 
4322     return sResult;
4323 }
4324 
getBackupFileName(QIODevice * pDevice)4325 QString XBinary::getBackupFileName(QIODevice *pDevice)
4326 {
4327     QString sResult=QString("Backup.%1.BAK").arg(getCurrentBackupDate());
4328 
4329     QString sClassName=pDevice->metaObject()->className();
4330 
4331     if(sClassName=="QFile")
4332     {
4333         QFile *pFile=(QFile *)pDevice;
4334 
4335         QString sFileName=pFile->fileName(); // TODO
4336 
4337         if(sFileName!="")
4338         {
4339             sResult=getBackupFileName(sFileName);
4340         }
4341     }
4342 
4343     return sResult;
4344 }
4345 
getBackupFileName(QString sFileName)4346 QString XBinary::getBackupFileName(QString sFileName)
4347 {
4348     QFileInfo fi(sFileName);
4349     QString sResult;
4350 
4351     sResult+=fi.absolutePath()+QDir::separator()+fi.completeBaseName();
4352 
4353     QString sSuffix=fi.suffix();
4354 
4355     if(sSuffix!="")
4356     {
4357         sResult+="."+sSuffix;
4358     }
4359 
4360     sResult+=QString(".%1.BAK").arg(getCurrentBackupDate());
4361 
4362     return sResult;
4363 }
4364 
getResultFileName(QIODevice * pDevice,QString sAppendix)4365 QString XBinary::getResultFileName(QIODevice *pDevice, QString sAppendix)
4366 {
4367     QString sResult=sAppendix;
4368 
4369     QString sClassName=pDevice->metaObject()->className();
4370 
4371     if(sClassName=="QFile")
4372     {
4373         QFile *pFile=(QFile *)pDevice;
4374 
4375         QString sFileName=pFile->fileName(); // TODO
4376 
4377         if(sFileName!="")
4378         {
4379             sResult=getResultFileName(sFileName,sAppendix);
4380         }
4381     }
4382 
4383     return sResult;
4384 }
4385 
getResultFileName(QString sFileName,QString sAppendix)4386 QString XBinary::getResultFileName(QString sFileName,QString sAppendix)
4387 {
4388     // mb TODO if file exists write other .1 .2 ...
4389     QFileInfo fileInfo(sFileName);
4390     QString sResult=fileInfo.absolutePath()+QDir::separator()+fileInfo.completeBaseName()+"."+fileInfo.suffix()+"."+sAppendix;
4391 
4392     return sResult;
4393 }
4394 
getDeviceFileName(QIODevice * pDevice)4395 QString XBinary::getDeviceFileName(QIODevice *pDevice)
4396 {
4397     QString sResult;
4398 
4399     QString sClassName=pDevice->metaObject()->className();
4400 
4401     if(sClassName=="QFile")
4402     {
4403         QFile *pFile=(QFile *)pDevice;
4404 
4405         sResult=pFile->fileName();
4406     }
4407 
4408     return sResult;
4409 }
4410 
getDeviceFilePath(QIODevice * pDevice)4411 QString XBinary::getDeviceFilePath(QIODevice *pDevice)
4412 {
4413     QString sResult;
4414 
4415     QString sClassName=pDevice->metaObject()->className();
4416 
4417     if(sClassName=="QFile")
4418     {
4419         QFile *pFile=(QFile *)pDevice;
4420 
4421         QString sFileName=pFile->fileName(); // TODO
4422 
4423         if(sFileName!="")
4424         {
4425             QFileInfo fi(sFileName);
4426 
4427             sResult=fi.absoluteFilePath();
4428         }
4429     }
4430 
4431     return sResult;
4432 }
4433 
getDeviceDirectory(QIODevice * pDevice)4434 QString XBinary::getDeviceDirectory(QIODevice *pDevice)
4435 {
4436     QString sResult;
4437 
4438     QString sClassName=pDevice->metaObject()->className();
4439 
4440     if(sClassName=="QFile")
4441     {
4442         QFile *pFile=(QFile *)pDevice;
4443 
4444         QString sFileName=pFile->fileName(); // TODO
4445 
4446         if(sFileName!="")
4447         {
4448             QFileInfo fi(sFileName);
4449 
4450             sResult=fi.absolutePath();
4451         }
4452     }
4453 
4454     return sResult;
4455 }
4456 
getDeviceFileBaseName(QIODevice * pDevice)4457 QString XBinary::getDeviceFileBaseName(QIODevice *pDevice)
4458 {
4459     QString sResult;
4460 
4461     QString sClassName=pDevice->metaObject()->className();
4462 
4463     if(sClassName=="QFile")
4464     {
4465         QFile *pFile=(QFile *)pDevice;
4466 
4467         QString sFileName=pFile->fileName(); // TODO
4468 
4469         if(sFileName!="")
4470         {
4471             QFileInfo fi(sFileName);
4472 
4473             sResult=fi.baseName();
4474         }
4475     }
4476 
4477     return sResult;
4478 }
4479 
getDeviceFileCompleteSuffix(QIODevice * pDevice)4480 QString XBinary::getDeviceFileCompleteSuffix(QIODevice *pDevice)
4481 {
4482     QString sResult;
4483 
4484     QString sClassName=pDevice->metaObject()->className();
4485 
4486     if(sClassName=="QFile")
4487     {
4488         QFile *pFile=(QFile *)pDevice;
4489 
4490         QString sFileName=pFile->fileName(); // TODO
4491 
4492         if(sFileName!="")
4493         {
4494             QFileInfo fi(sFileName);
4495 
4496             sResult=fi.completeSuffix();
4497         }
4498     }
4499 
4500     return sResult;
4501 }
4502 
getDeviceFileSuffix(QIODevice * pDevice)4503 QString XBinary::getDeviceFileSuffix(QIODevice *pDevice)
4504 {
4505     QString sResult;
4506 
4507     QString sClassName=pDevice->metaObject()->className();
4508 
4509     if(sClassName=="QFile")
4510     {
4511         QFile *pFile=(QFile *)pDevice;
4512 
4513         QString sFileName=pFile->fileName(); // TODO
4514 
4515         if(sFileName!="")
4516         {
4517             QFileInfo fi(sFileName);
4518 
4519             sResult=fi.suffix();
4520         }
4521     }
4522 
4523     return sResult;
4524 }
4525 
isBackupPresent(QIODevice * pDevice)4526 bool XBinary::isBackupPresent(QIODevice *pDevice)
4527 {
4528     return XBinary::isFileExists(XBinary::getBackupFileName(pDevice));
4529 }
4530 
saveBackup(QIODevice * pDevice)4531 bool XBinary::saveBackup(QIODevice *pDevice)
4532 {
4533     bool bResult=false;
4534 
4535     QString sBackupFileName=XBinary::getBackupFileName(pDevice);
4536 
4537     if(sBackupFileName!="")
4538     {
4539         if(!QFile::exists(sBackupFileName))
4540         {
4541             QString sFileName=XBinary::getDeviceFileName(pDevice);
4542 
4543             if(sFileName!="")
4544             {
4545                 bResult=QFile::copy(sFileName,sBackupFileName);
4546             }
4547             else
4548             {
4549                 bResult=XBinary::writeToFile(sBackupFileName,pDevice);
4550             }
4551         }
4552     }
4553 
4554     return bResult;
4555 }
4556 
getCurrentBackupDate()4557 QString XBinary::getCurrentBackupDate()
4558 {
4559     QString sResult;
4560 
4561     sResult=QDate::currentDate().toString("yyyy-MM-dd");
4562 
4563     return sResult;
4564 }
4565 
getFixupList(QIODevice * pDevice1,QIODevice * pDevice2,qint64 nDelta)4566 QList<qint64> XBinary::getFixupList(QIODevice *pDevice1, QIODevice *pDevice2, qint64 nDelta)
4567 {
4568     QList<qint64> listResult;
4569 
4570     qint64 nSize1=pDevice1->size();
4571     qint64 nSize2=pDevice2->size();
4572 
4573     if(nSize1==nSize2)
4574     {
4575         qint64 nSize=nSize1;
4576         qint64 nTemp=0;
4577 
4578         char *pBuffer1=new char[READWRITE_BUFFER_SIZE+3];
4579         char *pBuffer2=new char[READWRITE_BUFFER_SIZE+3];
4580         qint64 nOffset=0;
4581 
4582         while(nSize>3)
4583         {
4584             nTemp=qMin((qint64)(READWRITE_BUFFER_SIZE+3),nSize);
4585 
4586             pDevice1->seek(nOffset);
4587 
4588             if(pDevice1->read(pBuffer1,nTemp)<=0)
4589             {
4590                 break;
4591             }
4592 
4593             pDevice2->seek(nOffset);
4594 
4595             if(pDevice2->read(pBuffer2,nTemp)<=0)
4596             {
4597                 break;
4598             }
4599 
4600             for(unsigned int i=0; i<nTemp-3; i++)
4601             {
4602                 qint32 nValue1=*(qint32 *)(pBuffer1+i);
4603                 qint32 nValue2=*(qint32 *)(pBuffer2+i);
4604 
4605                 if(nValue1+nDelta==nValue2)
4606                 {
4607                     listResult.append(nOffset+i);
4608                 }
4609             }
4610 
4611             nSize-=nTemp-3;
4612             nOffset+=nTemp-3;
4613         }
4614 
4615         delete[] pBuffer1;
4616         delete[] pBuffer2;
4617     }
4618 
4619     return listResult;
4620 }
4621 
getHash(XBinary::HASH hash,QString sFileName)4622 QString XBinary::getHash(XBinary::HASH hash, QString sFileName)
4623 {
4624     QString sResult;
4625 
4626     QFile file;
4627     file.setFileName(sFileName);
4628 
4629     if(file.open(QIODevice::ReadOnly))
4630     {
4631         sResult=XBinary::getHash(hash,&file);
4632 
4633         file.close();
4634     }
4635 
4636     return sResult;
4637 }
4638 
getHash(XBinary::HASH hash,QIODevice * pDevice)4639 QString XBinary::getHash(XBinary::HASH hash, QIODevice *pDevice)
4640 {
4641     QString sResult;
4642 
4643     XBinary binary(pDevice);
4644 
4645     sResult=binary.getHash(hash,0,-1);
4646 
4647     pDevice->reset();
4648 
4649     return sResult;
4650 }
4651 
getHash(XBinary::HASH hash,qint64 nOffset,qint64 nSize)4652 QString XBinary::getHash(XBinary::HASH hash, qint64 nOffset, qint64 nSize)
4653 {
4654     QString sResult;
4655 
4656     OFFSETSIZE offsetSize=convertOffsetAndSize(nOffset,nSize);
4657 
4658     nOffset=offsetSize.nOffset;
4659     nSize=offsetSize.nSize;
4660 
4661     if(nOffset!=-1)
4662     {
4663         QList<OFFSETSIZE> listOS;
4664         listOS.append(offsetSize);
4665 
4666         sResult=getHash(hash,&listOS);
4667     }
4668 
4669     return sResult;
4670 }
4671 
getHash(HASH hash,QList<OFFSETSIZE> * pListOS)4672 QString XBinary::getHash(HASH hash, QList<OFFSETSIZE> *pListOS)
4673 {
4674     QString sResult;
4675 
4676     PROCENT procent=procentInit(getTotalOSSize(pListOS));
4677 
4678     _hashProgressMinimumChanged(0);
4679     _hashProgressMaximumChanged(procent.nMaxProcent);
4680     _hashProgressValueChanged(0);
4681 
4682     qint64 nTemp=0;
4683     char *pBuffer=new char[READWRITE_BUFFER_SIZE];
4684 
4685     QCryptographicHash::Algorithm algorithm=QCryptographicHash::Md4;
4686 
4687     switch(hash) // TODO Check new versions of Qt
4688     {
4689         case HASH_MD4:          algorithm=QCryptographicHash::Md4;          break;
4690         case HASH_MD5:          algorithm=QCryptographicHash::Md5;          break;
4691         case HASH_SHA1:         algorithm=QCryptographicHash::Sha1;         break;
4692     #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
4693         case HASH_SHA224:       algorithm=QCryptographicHash::Sha224;       break; // Keccak_224 ?
4694         case HASH_SHA256:       algorithm=QCryptographicHash::Sha256;       break;
4695         case HASH_SHA384:       algorithm=QCryptographicHash::Sha384;       break;
4696         case HASH_SHA512:       algorithm=QCryptographicHash::Sha512;       break;
4697     #endif
4698     }
4699 
4700     QCryptographicHash crypto(algorithm);
4701 
4702     int nNumberOfRecords=pListOS->count();
4703 
4704     qint64 nCurrentSize=0;
4705 
4706     for(int i=0;(i<nNumberOfRecords)&&(!g_bIsHashStop);i++)
4707     {
4708         qint64 nOffset=pListOS->at(i).nOffset;
4709         qint64 nSize=pListOS->at(i).nSize;
4710 
4711         while((nSize>0)&&(!g_bIsHashStop))
4712         {
4713             nTemp=qMin((qint64)READWRITE_BUFFER_SIZE,nSize);
4714 
4715             if(read_array(nOffset,pBuffer,nTemp)!=nTemp)
4716             {
4717                 _errorMessage(tr("Read error"));
4718                 delete[] pBuffer;
4719                 return "";
4720             }
4721 
4722             crypto.addData(pBuffer,nTemp);
4723 
4724             nSize-=nTemp;
4725             nOffset+=nTemp;
4726             nCurrentSize+=nTemp;
4727 
4728             if(procentSetCurrentValue(&procent,nCurrentSize))
4729             {
4730                 _hashProgressValueChanged(procent.nCurrentProcent);
4731             }
4732         }
4733     }
4734 
4735     _hashProgressValueChanged(procent.nMaxProcent);
4736 
4737     delete[] pBuffer;
4738 
4739     sResult=crypto.result().toHex();
4740 
4741     return sResult;
4742 }
4743 
getHashMethods()4744 QSet<XBinary::HASH> XBinary::getHashMethods()
4745 {
4746     QSet<XBinary::HASH> stResult;
4747 
4748     stResult.insert(HASH_MD4);
4749     stResult.insert(HASH_MD5);
4750     stResult.insert(HASH_SHA1);
4751 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
4752     stResult.insert(HASH_SHA224);
4753     stResult.insert(HASH_SHA256);
4754     stResult.insert(HASH_SHA384);
4755     stResult.insert(HASH_SHA512);
4756 #endif
4757 
4758     return stResult;
4759 }
4760 
getHashMethodsAsList()4761 QList<XBinary::HASH> XBinary::getHashMethodsAsList()
4762 {
4763     QList<XBinary::HASH> listResult;
4764 
4765     listResult.append(HASH_MD4);
4766     listResult.append(HASH_MD5);
4767     listResult.append(HASH_SHA1);
4768 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
4769     listResult.append(HASH_SHA224);
4770     listResult.append(HASH_SHA256);
4771     listResult.append(HASH_SHA384);
4772     listResult.append(HASH_SHA512);
4773 #endif
4774 
4775     return listResult;
4776 }
4777 
hashIdToString(XBinary::HASH hash)4778 QString XBinary::hashIdToString(XBinary::HASH hash)
4779 {
4780     QString sResult="Unknown"; // mb TODO translate
4781 
4782     switch(hash)
4783     {
4784         case HASH_MD4:          sResult=QString("MD4");         break;
4785         case HASH_MD5:          sResult=QString("MD5");         break;
4786         case HASH_SHA1:         sResult=QString("SHA1");        break;
4787 #ifndef QT_CRYPTOGRAPHICHASH_ONLY_SHA1
4788         case HASH_SHA224:       sResult=QString("SHA224");      break;
4789         case HASH_SHA256:       sResult=QString("SHA256");      break;
4790         case HASH_SHA384:       sResult=QString("SHA384");      break;
4791         case HASH_SHA512:       sResult=QString("SHA512");      break;
4792 #endif
4793     }
4794 
4795     return sResult;
4796 }
4797 
isFileHashValid(XBinary::HASH hash,QString sFileName,QString sHash)4798 bool XBinary::isFileHashValid(XBinary::HASH hash, QString sFileName, QString sHash)
4799 {
4800     bool bResult=false;
4801 
4802     if(isFileExists(sFileName))
4803     {
4804         bResult=(getHash(hash,sFileName).toUpper()==sHash.toUpper());
4805     }
4806 
4807     return bResult;
4808 }
4809 
getAdler32(QString sFileName)4810 quint32 XBinary::getAdler32(QString sFileName)
4811 {
4812     quint32 nResult=0;
4813 
4814     QFile file;
4815     file.setFileName(sFileName);
4816 
4817     if(file.open(QIODevice::ReadOnly))
4818     {
4819         nResult=XBinary::getAdler32(&file);
4820 
4821         file.close();
4822     }
4823 
4824     return nResult;
4825 }
4826 
getAdler32(QIODevice * pDevice)4827 quint32 XBinary::getAdler32(QIODevice *pDevice)
4828 {
4829     quint32 nResult=0;
4830 
4831     XBinary binary(pDevice);
4832 
4833     nResult=binary.getAdler32(0,-1);
4834 
4835     pDevice->reset();
4836 
4837     return nResult;
4838 }
4839 
getAdler32(qint64 nOffset,qint64 nSize)4840 quint32 XBinary::getAdler32(qint64 nOffset, qint64 nSize)
4841 {
4842     // TODO optimize!!!
4843     quint32 nResult=0;
4844 
4845     OFFSETSIZE offsetSize=convertOffsetAndSize(nOffset,nSize);
4846 
4847     nOffset=offsetSize.nOffset;
4848     nSize=offsetSize.nSize;
4849 
4850     const quint32 MOD_ADLER=65521;
4851 
4852     if(nOffset!=-1)
4853     {
4854         qint64 nTemp=0;
4855         char *pBuffer=new char[READWRITE_BUFFER_SIZE];
4856 
4857         quint32 a=1;
4858         quint32 b=0;
4859 
4860         while(nSize>0)
4861         {
4862             nTemp=qMin((qint64)READWRITE_BUFFER_SIZE,nSize);
4863 
4864             if(read_array(nOffset,pBuffer,nTemp)!=nTemp)
4865             {
4866                 _errorMessage(tr("Read error"));
4867                 delete[] pBuffer;
4868                 return 0;
4869             }
4870 
4871             for(qint64 i=0; i<nTemp; i++)
4872             {
4873                 a=(a+(quint8)(pBuffer[nOffset+i]))%MOD_ADLER;
4874                 b=(b+a)%MOD_ADLER;
4875             }
4876 
4877             nSize-=nTemp;
4878             nOffset+=nTemp;
4879         }
4880 
4881         delete[] pBuffer;
4882 
4883         nResult=(b<<16)|a;
4884     }
4885 
4886     return nResult;
4887 }
4888 
_getCRC32(QString sFileName)4889 quint32 XBinary::_getCRC32(QString sFileName)
4890 {
4891     quint32 nResult=0;
4892 
4893     QFile file;
4894     file.setFileName(sFileName);
4895 
4896     if(file.open(QIODevice::ReadOnly))
4897     {
4898         nResult=XBinary::_getCRC32(&file);
4899 
4900         file.close();
4901     }
4902 
4903     return nResult;
4904 }
4905 
_getCRC32(QIODevice * pDevice)4906 quint32 XBinary::_getCRC32(QIODevice *pDevice)
4907 {
4908     quint32 nResult=0;
4909 
4910     XBinary binary(pDevice);
4911 
4912     nResult=binary._getCRC32(0,-1);
4913 
4914     pDevice->reset();
4915 
4916     return nResult;
4917 }
4918 
_getCRC32(qint64 nOffset,qint64 nSize)4919 quint32 XBinary::_getCRC32(qint64 nOffset, qint64 nSize)
4920 {
4921     // TODO optimize!!!
4922     quint32 nResult=0xFFFFFFFF; // ~0
4923 
4924     OFFSETSIZE offsetSize=convertOffsetAndSize(nOffset,nSize);
4925 
4926     nOffset=offsetSize.nOffset;
4927     nSize=offsetSize.nSize;
4928 
4929     if(nOffset!=-1)
4930     {
4931         quint32 crc_table[256];
4932 
4933         for(int i=0;i<256;i++)
4934         {
4935             quint32 crc=i;
4936             for (int j=0;j<8;j++)
4937             {
4938                 crc=(crc&1)?((crc>>1)^0xEDB88320):(crc>>1);
4939             }
4940             crc_table[i]=crc;
4941         }
4942 
4943         qint64 nTemp=0;
4944         char *pBuffer=new char[READWRITE_BUFFER_SIZE];
4945 
4946         while(nSize>0)
4947         {
4948             nTemp=qMin((qint64)READWRITE_BUFFER_SIZE,nSize);
4949 
4950             if(read_array(nOffset,pBuffer,nTemp)!=nTemp)
4951             {
4952                 _errorMessage(tr("Read error"));
4953                 delete[] pBuffer;
4954                 return 0;
4955             }
4956 
4957             for(int i=0;i<nTemp;i++)
4958             {
4959                 nResult=crc_table[(nResult^((quint8)pBuffer[i]))&0xFF]^(nResult>>8);
4960             }
4961 
4962             nSize-=nTemp;
4963             nOffset+=nTemp;
4964         }
4965 
4966         delete[] pBuffer;
4967     }
4968 
4969     nResult^=0xFFFFFFFF;
4970 
4971     return nResult;
4972 }
4973 
getEntropy(QString sFileName)4974 double XBinary::getEntropy(QString sFileName)
4975 {
4976     double dResult=0;
4977 
4978     QFile file;
4979 
4980     file.setFileName(sFileName);
4981 
4982     if(file.open(QIODevice::ReadOnly))
4983     {
4984         dResult=XBinary::getEntropy(&file);
4985 
4986         file.close();
4987     }
4988 
4989     return dResult;
4990 }
4991 
getEntropy(QIODevice * pDevice)4992 double XBinary::getEntropy(QIODevice *pDevice)
4993 {
4994     double dResult=0;
4995 
4996     XBinary binary(pDevice);
4997 
4998     dResult=binary.getEntropy(0,-1);
4999 
5000     pDevice->reset();
5001 
5002     return dResult;
5003 }
5004 
getEntropy(qint64 nOffset,qint64 nSize)5005 double XBinary::getEntropy(qint64 nOffset, qint64 nSize)
5006 {
5007     double dResult=1.4426950408889634073599246810023;
5008 
5009     OFFSETSIZE offsetSize=convertOffsetAndSize(nOffset,nSize);
5010 
5011     nOffset=offsetSize.nOffset;
5012     nSize=offsetSize.nSize;
5013 
5014     if(nSize==0)
5015     {
5016         dResult=0;
5017     }
5018 
5019     if(nOffset!=-1)
5020     {
5021         PROCENT procent=procentInit(nSize);
5022 
5023         _entropyProgressMinimumChanged(0);
5024         _entropyProgressMaximumChanged(procent.nMaxProcent);
5025         _entropyProgressValueChanged(0);
5026 
5027         double bytes[256]={0.0};
5028 
5029         qint64 nTemp=0;
5030         char *pBuffer=new char[READWRITE_BUFFER_SIZE];
5031 
5032         while((nSize>0)&&(!g_bIsEntropyStop))
5033         {
5034             nTemp=qMin((qint64)READWRITE_BUFFER_SIZE,nSize);
5035 
5036             if(read_array(nOffset,pBuffer,nTemp)!=nTemp)
5037             {
5038                 _errorMessage(tr("Read error"));
5039                 delete[] pBuffer;
5040                 return 0;
5041             }
5042 
5043             for(qint64 i=0; i<nTemp; i++)
5044             {
5045                 bytes[(unsigned char)pBuffer[i]]+=1;
5046             }
5047 
5048             nSize-=nTemp;
5049             nOffset+=nTemp;
5050 
5051             if(procentSetCurrentValue(&procent,nOffset-offsetSize.nOffset))
5052             {
5053                 _entropyProgressValueChanged(procent.nCurrentProcent);
5054             }
5055         }
5056 
5057         _entropyProgressValueChanged(procent.nMaxProcent);
5058 
5059         delete[] pBuffer;
5060 
5061         if(!g_bIsEntropyStop)
5062         {
5063             for(int j=0; j<256; j++)
5064             {
5065                 double dTemp=bytes[j]/(double)offsetSize.nSize;
5066 
5067                 if(dTemp)
5068                 {
5069                     dResult+=(-log(dTemp)/log((double)2))*bytes[j];
5070                 }
5071             }
5072         }
5073 
5074         dResult=dResult/(double)offsetSize.nSize;
5075     }
5076 
5077     if(g_bIsEntropyStop)
5078     {
5079         dResult=0;
5080     }
5081 
5082     return dResult;
5083 }
5084 
getByteCounts(qint64 nOffset,qint64 nSize)5085 XBinary::BYTE_COUNTS XBinary::getByteCounts(qint64 nOffset, qint64 nSize)
5086 {
5087     BYTE_COUNTS result={0};
5088 
5089     OFFSETSIZE offsetSize=convertOffsetAndSize(nOffset,nSize);
5090 
5091     nOffset=offsetSize.nOffset;
5092     nSize=offsetSize.nSize;
5093 
5094     if(nOffset!=-1)
5095     {
5096         result.nSize=nSize;
5097 
5098         PROCENT procent=procentInit(nSize);
5099 
5100         _entropyProgressMinimumChanged(0);
5101         _entropyProgressMaximumChanged(procent.nMaxProcent);
5102         _entropyProgressValueChanged(0);
5103 
5104         qint64 nTemp=0;
5105         char *pBuffer=new char[READWRITE_BUFFER_SIZE];
5106 
5107         while((nSize>0)&&(!g_bIsEntropyStop))
5108         {
5109             nTemp=qMin((qint64)READWRITE_BUFFER_SIZE,nSize);
5110 
5111             if(read_array(nOffset,pBuffer,nTemp)!=nTemp)
5112             {
5113                 _errorMessage(tr("Read error"));
5114                 delete[] pBuffer;
5115 
5116                 return {0};
5117             }
5118 
5119             for(qint64 i=0; i<nTemp; i++)
5120             {
5121                 result.nCount[(unsigned char)pBuffer[i]]+=1;
5122             }
5123 
5124             nSize-=nTemp;
5125             nOffset+=nTemp;
5126 
5127             if(procentSetCurrentValue(&procent,nOffset-offsetSize.nOffset))
5128             {
5129                 _entropyProgressValueChanged(procent.nCurrentProcent);
5130             }
5131         }
5132 
5133         _entropyProgressValueChanged(procent.nMaxProcent);
5134 
5135         delete[] pBuffer;
5136     }
5137 
5138     if(g_bIsEntropyStop)
5139     {
5140         result={0};
5141     }
5142 
5143     return result;
5144 }
5145 
_xor(quint8 nXorValue,qint64 nOffset,qint64 nSize)5146 void XBinary::_xor(quint8 nXorValue, qint64 nOffset, qint64 nSize)
5147 {
5148     // TODO Optimize
5149     OFFSETSIZE offsetSize=convertOffsetAndSize(nOffset,nSize);
5150 
5151     nOffset=offsetSize.nOffset;
5152     nSize=offsetSize.nSize;
5153 
5154     if(nOffset!=-1)
5155     {
5156         if(nOffset!=-1)
5157         {
5158             qint64 nTemp=0;
5159             char *pBuffer=new char[READWRITE_BUFFER_SIZE];
5160 
5161             while(nSize>0)
5162             {
5163                 nTemp=qMin((qint64)READWRITE_BUFFER_SIZE,nSize);
5164 
5165                 if(read_array(nOffset,pBuffer,nTemp)!=nTemp)
5166                 {
5167                     _errorMessage(tr("Read error"));
5168                     break;
5169                 }
5170 
5171                 for(int i=0;i<nTemp;i++)
5172                 {
5173                     *(pBuffer+i)^=nXorValue;
5174                 }
5175 
5176                 if(!write_array(nOffset,pBuffer,nTemp))
5177                 {
5178                     _errorMessage(tr("Write error"));
5179                     break;
5180                 }
5181 
5182                 nSize-=nTemp;
5183                 nOffset+=nTemp;
5184             }
5185 
5186             delete[] pBuffer;
5187         }
5188     }
5189 }
5190 
5191 //quint32 XBinary::_ror32(quint32 nValue, quint32 nShift)
5192 //{
5193 //    // TODO Check
5194 //    nShift&=(31);
5195 //    return (nValue>>nShift)|(nValue<<((-nShift)&31));
5196 //}
5197 
5198 //quint32 XBinary::_rol32(quint32 nValue, quint32 nShift)
5199 //{
5200 //    // TODO Check
5201 //    nShift&=(31);
5202 //    return (nValue<<nShift)|(nValue>>((-nShift)&31));
5203 //}
5204 
getStringCustomCRC32(QString sString)5205 quint32 XBinary::getStringCustomCRC32(QString sString)
5206 {
5207     quint32 nResult=0; // not ~0 !!! if ~0 (0xFFFFFFFF) it will be a CRC32C
5208 
5209     int nSize=sString.size();
5210     QByteArray baString=sString.toLatin1();
5211 
5212     for(int i=0; i<nSize; i++)
5213     {
5214         unsigned char _char=(unsigned char)baString.data()[i];
5215 //        unsigned char _char1=(unsigned char)sString.at(i).toLatin1();
5216 
5217 //        if(_char!=_char1)
5218 //        {
5219 //            qFatal("Error"); // TODO remove
5220 //        }
5221 
5222         nResult^=_char;
5223 
5224         for(int k=0; k<8; k++)
5225         {
5226             nResult=(nResult&1)?((nResult>>1)^0x82f63b78):(nResult>>1);
5227         }
5228     }
5229 
5230     nResult=~nResult;
5231 
5232     return nResult;
5233 }
5234 
getDevice()5235 QIODevice *XBinary::getDevice()
5236 {
5237     return g_pDevice;
5238 }
5239 
isValid()5240 bool XBinary::isValid()
5241 {
5242     return true;
5243 }
5244 
isValid(QIODevice * pDevice,bool bIsImage,qint64 nModuleAddress)5245 bool XBinary::isValid(QIODevice *pDevice, bool bIsImage, qint64 nModuleAddress)
5246 {
5247     XBinary xbinary(pDevice,bIsImage,nModuleAddress);
5248 
5249     return xbinary.isValid();
5250 }
5251 
getMode(QIODevice * pDevice,bool bIsImage,qint64 nModuleAddress)5252 XBinary::MODE XBinary::getMode(QIODevice *pDevice, bool bIsImage, qint64 nModuleAddress)
5253 {
5254     XBinary xbinary(pDevice,bIsImage,nModuleAddress);
5255 
5256     return xbinary.getMode();
5257 }
5258 
isBigEndian()5259 bool XBinary::isBigEndian()
5260 {
5261     return g_bIsBigEndian;
5262 }
5263 
is16()5264 bool XBinary::is16()
5265 {
5266     MODE mode=getMode();
5267 
5268     return ((mode==MODE_16)||(mode==MODE_16SEG));
5269 }
5270 
is32()5271 bool XBinary::is32()
5272 {
5273     MODE mode=getMode();
5274 
5275     return (mode==MODE_32);
5276 }
5277 
is64()5278 bool XBinary::is64()
5279 {
5280     MODE mode=getMode();
5281 
5282     return (mode==MODE_64);
5283 }
5284 
isBigEndian(XBinary::_MEMORY_MAP * pMemoryMap)5285 bool XBinary::isBigEndian(XBinary::_MEMORY_MAP *pMemoryMap)
5286 {
5287     return pMemoryMap->bIsBigEndian;
5288 }
5289 
is16(XBinary::_MEMORY_MAP * pMemoryMap)5290 bool XBinary::is16(XBinary::_MEMORY_MAP *pMemoryMap)
5291 {
5292     return (pMemoryMap->mode==MODE_16)||(pMemoryMap->mode==MODE_16SEG);
5293 }
5294 
is32(XBinary::_MEMORY_MAP * pMemoryMap)5295 bool XBinary::is32(XBinary::_MEMORY_MAP *pMemoryMap)
5296 {
5297     return (pMemoryMap->mode==MODE_32);
5298 }
5299 
is64(XBinary::_MEMORY_MAP * pMemoryMap)5300 bool XBinary::is64(XBinary::_MEMORY_MAP *pMemoryMap)
5301 {
5302     return (pMemoryMap->mode==MODE_64);
5303 }
5304 
setVersion(QString sVersion)5305 void XBinary::setVersion(QString sVersion)
5306 {
5307     g_sVersion=sVersion;
5308 }
5309 
getVersion()5310 QString XBinary::getVersion()
5311 {
5312     return g_sVersion;
5313 }
5314 
isEncrypted()5315 bool XBinary::isEncrypted()
5316 {
5317     return false;
5318 }
5319 
getSignature(qint64 nOffset,qint64 nSize)5320 QString XBinary::getSignature(qint64 nOffset, qint64 nSize)
5321 {
5322     QString sResult;
5323 
5324     if(nOffset!=-1)
5325     {
5326         OFFSETSIZE offsetSize=convertOffsetAndSize(nOffset,-1);
5327 
5328         nSize=qMin(offsetSize.nSize,nSize);
5329 
5330         sResult=read_array(nOffset,nSize).toHex().toUpper();
5331     }
5332 
5333     return sResult;
5334 }
5335 
convertOffsetAndSize(qint64 nOffset,qint64 nSize)5336 XBinary::OFFSETSIZE XBinary::convertOffsetAndSize(qint64 nOffset, qint64 nSize)
5337 {
5338     OFFSETSIZE result={};
5339 
5340     result.nOffset=-1;
5341     result.nSize=0;
5342 
5343     qint64 nTotalSize=getSize();
5344 
5345     if((nSize==-1)&&(nTotalSize>nOffset))
5346     {
5347         nSize=nTotalSize-nOffset;
5348     }
5349 
5350     if((nOffset+nSize>nTotalSize)&&(nOffset<nTotalSize))
5351     {
5352         nSize=nTotalSize-nOffset;
5353     }
5354 
5355     if((nSize>0)&&(nOffset>=0)&&(nOffset<nTotalSize)&&(nOffset+nSize-1<nTotalSize))
5356     {
5357         result.nOffset=nOffset;
5358         result.nSize=nSize;
5359     }
5360 
5361     return result;
5362 }
5363 
convertOffsetAndSize(QIODevice * pDevice,qint64 nOffset,qint64 nSize)5364 XBinary::OFFSETSIZE XBinary::convertOffsetAndSize(QIODevice *pDevice, qint64 nOffset, qint64 nSize)
5365 {
5366     XBinary binary(pDevice);
5367 
5368     return binary.convertOffsetAndSize(nOffset,nSize);
5369 }
5370 
compareSignatureStrings(QString sBaseSignature,QString sOptSignature)5371 bool XBinary::compareSignatureStrings(QString sBaseSignature, QString sOptSignature)
5372 {
5373     bool bResult=false;
5374     // TODO optimize
5375     // TODO check
5376     sBaseSignature=convertSignature(sBaseSignature);
5377     sOptSignature=convertSignature(sOptSignature);
5378 
5379     int nSize=qMin(sBaseSignature.size(),sOptSignature.size());
5380 
5381     if((nSize)&&(sBaseSignature.size()>=sOptSignature.size()))
5382     {
5383         bResult=true;
5384 
5385         for(int i=0; i<nSize; i++)
5386         {
5387             QChar _qchar1=sBaseSignature.at(i);
5388             QChar _qchar2=sOptSignature.at(i);
5389 
5390             if((_qchar1!=QChar('.'))&&(_qchar2!=QChar('.')))
5391             {
5392                 if(_qchar1!=_qchar2)
5393                 {
5394                     bResult=false;
5395 
5396                     break;
5397                 }
5398             }
5399         }
5400     }
5401 
5402     return bResult;
5403 }
5404 
_errorMessage(QString sErrorMessage)5405 void XBinary::_errorMessage(QString sErrorMessage)
5406 {
5407 #ifdef QT_DEBUG
5408     qDebug("Error: %s",sErrorMessage.toLatin1().data());
5409 #endif
5410     emit errorMessage(sErrorMessage);
5411 }
5412 
_infoMessage(QString sInfoMessage)5413 void XBinary::_infoMessage(QString sInfoMessage)
5414 {
5415 #ifdef QT_DEBUG
5416     qDebug("Info: %s",sInfoMessage.toLatin1().data());
5417 #endif
5418     emit infoMessage(sInfoMessage);
5419 }
5420 
_calculateRawSize()5421 qint64 XBinary::_calculateRawSize()
5422 {
5423     _MEMORY_MAP memoryMap=getMemoryMap();
5424 
5425     return _calculateRawSize(&memoryMap);
5426 }
5427 
_calculateRawSize(XBinary::_MEMORY_MAP * pMemoryMap)5428 qint64 XBinary::_calculateRawSize(XBinary::_MEMORY_MAP *pMemoryMap)
5429 {
5430     qint64 nResult=0;
5431 
5432     int nNumberOfRecords=pMemoryMap->listRecords.count();
5433 
5434     qint64 _nOverlayOffset=-1;
5435 
5436     for(int i=0; i<nNumberOfRecords; i++)
5437     {
5438         if((pMemoryMap->listRecords.at(i).nOffset!=-1)&&(pMemoryMap->listRecords.at(i).type!=MMT_OVERLAY))
5439         {
5440             nResult=qMax(nResult,(qint64)(pMemoryMap->listRecords.at(i).nOffset+pMemoryMap->listRecords.at(i).nSize));
5441         }
5442 
5443         if(pMemoryMap->listRecords.at(i).type==MMT_OVERLAY)
5444         {
5445             _nOverlayOffset=pMemoryMap->listRecords.at(i).nOffset;
5446         }
5447     }
5448 
5449     if(_nOverlayOffset!=-1)
5450     {
5451         nResult=qMin(nResult,_nOverlayOffset);
5452     }
5453 
5454     return nResult;
5455 }
5456 
convertSignature(QString sSignature)5457 QString XBinary::convertSignature(QString sSignature)
5458 {
5459     // 'AnsiString'
5460     // TODO more defs
5461     if(sSignature.contains(QChar(39)))
5462     {
5463         QString sTemp;
5464         int nStringSize=sSignature.size();
5465         bool bAnsiString=false;
5466 
5467         for(int i=0; i<nStringSize; i++)
5468         {
5469             QChar c=sSignature.at(i);
5470 
5471             if(c==QChar(39))
5472             {
5473                 bAnsiString=!bAnsiString;
5474             }
5475             else if(bAnsiString)
5476             {
5477                 sTemp.append(qcharToHex(c));
5478             }
5479             else
5480             {
5481                 sTemp.append(c);
5482             }
5483         }
5484 
5485         sSignature=sTemp;
5486     }
5487 
5488     if(sSignature.contains(QChar(' ')))
5489     {
5490         sSignature=sSignature.remove(QChar(' '));
5491     }
5492 
5493     if(sSignature.contains(QChar('?')))
5494     {
5495         sSignature=sSignature.replace(QChar('?'),QChar('.'));
5496     }
5497 
5498     sSignature=sSignature.toLower();
5499 
5500     return sSignature;
5501 }
5502 
qcharToHex(QChar cSymbol)5503 QString XBinary::qcharToHex(QChar cSymbol)
5504 {
5505     // TODO mb
5506     return QString("%1").arg((quint8)(cSymbol.toLatin1()),2,16,QChar('0'));
5507 }
5508 
stringToHex(QString sString)5509 QString XBinary::stringToHex(QString sString)
5510 {
5511     return QString::fromLatin1(sString.toLatin1().toHex());
5512 }
5513 
hexToString(QString sHex)5514 QString XBinary::hexToString(QString sHex)
5515 {
5516     QString sResult;
5517 
5518     sResult=QByteArray::fromHex(sHex.toLatin1().data());
5519 
5520     return sResult;
5521 }
5522 
floatToString(float fValue,int nPrec)5523 QString XBinary::floatToString(float fValue, int nPrec)
5524 {
5525     return QString("%1").arg(fValue,0,'f',nPrec);
5526 }
5527 
doubleToString(double dValue,int nPrec)5528 QString XBinary::doubleToString(double dValue,int nPrec)
5529 {
5530     return QString("%1").arg(dValue,0,'f',nPrec);
5531 }
5532 
hexToUint8(QString sHex)5533 quint8 XBinary::hexToUint8(QString sHex)
5534 {
5535     quint8 nResult=0;
5536 
5537     if((quint32)sHex.length()>=sizeof(quint8))
5538     {
5539         sHex=sHex.mid(0,2*sizeof(quint8));
5540         bool bStatus=false;
5541         nResult=(quint8)(sHex.toInt(&bStatus,16));
5542     }
5543 
5544     return nResult;
5545 }
5546 
hexToInt8(QString sHex)5547 qint8 XBinary::hexToInt8(QString sHex)
5548 {
5549     quint8 nResult=0;
5550 
5551     if((quint32)sHex.length()>=sizeof(qint8))
5552     {
5553         sHex=sHex.mid(0,2*sizeof(qint8));
5554         bool bStatus=false;
5555         nResult=(qint8)(sHex.toInt(&bStatus,16));
5556     }
5557 
5558     return nResult;
5559 }
5560 
hexToUint16(QString sHex,bool bIsBigEndian)5561 quint16 XBinary::hexToUint16(QString sHex, bool bIsBigEndian)
5562 {
5563     quint16 nResult=0;
5564 
5565     if((quint32)sHex.length()>=sizeof(quint16))
5566     {
5567         if(!bIsBigEndian)
5568         {
5569             sHex=invertHexByteString(sHex.mid(0,2*sizeof(quint16)));
5570         }
5571 
5572         bool bStatus=false;
5573         nResult=sHex.toUShort(&bStatus,16);
5574     }
5575 
5576     return nResult;
5577 }
5578 
hexToInt16(QString sHex,bool bIsBigEndian)5579 qint16 XBinary::hexToInt16(QString sHex, bool bIsBigEndian)
5580 {
5581     qint16 nResult=0;
5582 
5583     if((quint32)sHex.length()>=sizeof(qint16))
5584     {
5585         if(!bIsBigEndian)
5586         {
5587             sHex=invertHexByteString(sHex.mid(0,2*sizeof(qint16)));
5588         }
5589 
5590         bool bStatus=false;
5591         nResult=sHex.toShort(&bStatus,16);
5592     }
5593 
5594     return nResult;
5595 }
5596 
hexToUint32(QString sHex,bool bIsBigEndian)5597 quint32 XBinary::hexToUint32(QString sHex, bool bIsBigEndian)
5598 {
5599     quint32 nResult=0;
5600 
5601     if((quint32)sHex.length()>=sizeof(quint32))
5602     {
5603         if(!bIsBigEndian)
5604         {
5605             sHex=invertHexByteString(sHex.mid(0,2*sizeof(quint32)));
5606         }
5607 
5608         bool bStatus=false;
5609         nResult=sHex.toUInt(&bStatus,16);
5610     }
5611 
5612     return nResult;
5613 }
5614 
hexToInt32(QString sHex,bool bIsBigEndian)5615 qint32 XBinary::hexToInt32(QString sHex, bool bIsBigEndian)
5616 {
5617     qint32 nResult=0;
5618 
5619     if((quint32)sHex.length()>=sizeof(qint32))
5620     {
5621         if(!bIsBigEndian)
5622         {
5623             sHex=invertHexByteString(sHex.mid(0,2*sizeof(qint32)));
5624         }
5625 
5626         bool bStatus=false;
5627         nResult=sHex.toInt(&bStatus,16);
5628     }
5629 
5630     return nResult;
5631 }
5632 
hexToUint64(QString sHex,bool bIsBigEndian)5633 quint64 XBinary::hexToUint64(QString sHex, bool bIsBigEndian)
5634 {
5635     quint64 nResult=0;
5636 
5637     if((quint32)sHex.length()>=sizeof(quint64))
5638     {
5639         if(!bIsBigEndian)
5640         {
5641             sHex=invertHexByteString(sHex.mid(0,2*sizeof(quint64)));
5642         }
5643 
5644         bool bStatus=false;
5645         nResult=sHex.toULongLong(&bStatus,16);
5646     }
5647 
5648     return nResult;
5649 }
5650 
hexToInt64(QString sHex,bool bIsBigEndian)5651 qint64 XBinary::hexToInt64(QString sHex, bool bIsBigEndian)
5652 {
5653     qint64 nResult=0;
5654 
5655     if((quint32)sHex.length()>=sizeof(qint64))
5656     {
5657         if(!bIsBigEndian)
5658         {
5659             sHex=invertHexByteString(sHex.mid(0,2*sizeof(qint64)));
5660         }
5661 
5662         bool bStatus=false;
5663         nResult=sHex.toLongLong(&bStatus,16);
5664     }
5665 
5666     return nResult;
5667 }
5668 
invertHexByteString(QString sHex)5669 QString XBinary::invertHexByteString(QString sHex)
5670 {
5671     QString sResult;
5672 
5673     for(int i=sHex.length()-2; i>=0; i-=2)
5674     {
5675         sResult+=sHex.mid(i,2);
5676     }
5677 
5678     return sResult;
5679 }
5680 
_swapBytes(char * pSource,int nSize)5681 void XBinary::_swapBytes(char *pSource, int nSize)
5682 {
5683     for(int i=0;i<(nSize/2);i++)
5684     {
5685         char cTemp=pSource[i];
5686         pSource[i]=pSource[(nSize-1)-i];
5687         pSource[(nSize-1)-i]=cTemp;
5688     }
5689 }
5690 
swapBytes(quint16 nValue)5691 quint16 XBinary::swapBytes(quint16 nValue)
5692 {
5693     _swapBytes((char *)&nValue,2);
5694 
5695     return nValue;
5696 }
5697 
swapBytes(quint32 nValue)5698 quint32 XBinary::swapBytes(quint32 nValue)
5699 {
5700     _swapBytes((char *)&nValue,4);
5701 
5702     return nValue;
5703 }
5704 
swapBytes(quint64 nValue)5705 quint64 XBinary::swapBytes(quint64 nValue)
5706 {
5707     _swapBytes((char *)&nValue,8);
5708 
5709     return nValue;
5710 }
5711 
isPlainTextType()5712 bool XBinary::isPlainTextType()
5713 {
5714     QByteArray baData=read_array(0,qMin(getSize(),(qint64)0x100));
5715 
5716     return isPlainTextType(&baData);
5717 }
5718 
isPlainTextType(QByteArray * pbaData)5719 bool XBinary::isPlainTextType(QByteArray *pbaData)
5720 {
5721     bool bResult=false;
5722 
5723     unsigned char *pDataOffset=(unsigned char *)(pbaData->data());
5724     int nDataSize=pbaData->size();
5725 
5726     if(nDataSize)
5727     {
5728         bResult=true;
5729 
5730         for(int i=0; i<nDataSize; i++)
5731         {
5732             if(pDataOffset[i]<0x9)
5733             {
5734                 bResult=false;
5735                 break;
5736             }
5737         }
5738     }
5739 
5740     return bResult;
5741 }
5742 
isUTF8TextType()5743 bool XBinary::isUTF8TextType()
5744 {
5745     QByteArray baData=read_array(0,qMin(getSize(),(qint64)0x100));
5746 
5747     return isUTF8TextType(&baData);
5748 }
5749 
isUTF8TextType(QByteArray * pbaData)5750 bool XBinary::isUTF8TextType(QByteArray *pbaData)
5751 {
5752     // EFBBBF
5753     bool bResult=false;
5754 
5755     unsigned char *pDataOffset=(unsigned char *)(pbaData->data());
5756     int nDataSize=pbaData->size();
5757 
5758     if(nDataSize>=3)
5759     {
5760         if((pDataOffset[0]==0xEF)&&(pDataOffset[1]==0xBB)&&(pDataOffset[2]==0xBF))
5761         {
5762             bResult=true;
5763         }
5764     }
5765 
5766     if(bResult)
5767     {
5768         unsigned char *pDataOffset=(unsigned char *)(pbaData->data());
5769         pDataOffset+=3;
5770 
5771         nDataSize=pbaData->size();
5772         nDataSize=nDataSize-3;
5773 
5774         for(int i=0; i<nDataSize; i++)
5775         {
5776             if(pDataOffset[i]==0)
5777             {
5778                 bResult=false;
5779                 break;
5780             }
5781         }
5782     }
5783 
5784     return bResult;
5785 }
5786 
isPlainTextType(QIODevice * pDevice)5787 bool XBinary::isPlainTextType(QIODevice *pDevice)
5788 {
5789     XBinary binary(pDevice);
5790 
5791     return binary.isPlainTextType();
5792 }
5793 
getUnicodeType()5794 XBinary::UNICODE_TYPE XBinary::getUnicodeType()
5795 {
5796     QByteArray baData=read_array(0,qMin(getSize(),(qint64)0x2));
5797 
5798     return getUnicodeType(&baData);
5799 }
5800 
getUnicodeType(QByteArray * pbaData)5801 XBinary::UNICODE_TYPE XBinary::getUnicodeType(QByteArray *pbaData)
5802 {
5803     XBinary::UNICODE_TYPE result=XBinary::UNICODE_TYPE_NONE;
5804 
5805     unsigned char *pDataOffset=(unsigned char *)(pbaData->data());
5806     int nDataSize=pbaData->size();
5807 
5808     if(nDataSize)
5809     {
5810         quint16 nSymbol=*((quint16 *)(pDataOffset));
5811 
5812         nSymbol=qFromLittleEndian(nSymbol);
5813 
5814         if(nSymbol==0xFFFE)
5815         {
5816             result=UNICODE_TYPE_BE;
5817         }
5818         else if(nSymbol==0xFEFF)
5819         {
5820             result=UNICODE_TYPE_LE;
5821         }
5822         else
5823         {
5824             result=UNICODE_TYPE_NONE;
5825         }
5826     }
5827     // TODO 0 end
5828 
5829     return result;
5830 }
5831 
tryToOpen(QIODevice * pDevice)5832 bool XBinary::tryToOpen(QIODevice *pDevice)
5833 {
5834     bool bResult=false;
5835 
5836     bResult=pDevice->open(QIODevice::ReadWrite);
5837 
5838     if(!bResult)
5839     {
5840         bResult=pDevice->open(QIODevice::ReadOnly);
5841     }
5842 
5843     return bResult;
5844 }
5845 
checkOffsetSize(XBinary::OFFSETSIZE os)5846 bool XBinary::checkOffsetSize(XBinary::OFFSETSIZE os)
5847 {
5848     qint64 nTotalSize=getSize();
5849 
5850     bool bOffsetValid=(os.nOffset>=0)&&(os.nOffset<nTotalSize);
5851     bool bSizeValid=(os.nSize>0)&&((os.nOffset+os.nSize-1)<nTotalSize);
5852 
5853     return (bOffsetValid)&&(bSizeValid);
5854 }
5855 
get_uint32_version(quint32 nValue)5856 QString XBinary::get_uint32_version(quint32 nValue)
5857 {
5858     QString sResult=QString("%1.%2.%3").arg(    QString::number((nValue>>16)&0xFF),
5859                                                 QString::number((nValue>>8)&0xFF),
5860                                                 QString::number((nValue)&0xFF));
5861 
5862     return sResult;
5863 }
5864 
isResizeEnable(QIODevice * pDevice)5865 bool XBinary::isResizeEnable(QIODevice *pDevice)
5866 {
5867     bool bResult=false;
5868 
5869     QString sClassName=pDevice->metaObject()->className();
5870 
5871     if(sClassName=="QFile")
5872     {
5873         bResult=true;
5874     }
5875     else if(sClassName=="QBuffer")
5876     {
5877         bResult=true;
5878     }
5879 
5880     return bResult;
5881 }
5882 
resize(QIODevice * pDevice,qint64 nSize)5883 bool XBinary::resize(QIODevice *pDevice, qint64 nSize)
5884 {
5885     bool bResult=false;
5886 
5887     QString sClassName=pDevice->metaObject()->className();
5888 
5889     if(sClassName=="QFile")
5890     {
5891         bResult=((QFile *)pDevice)->resize(nSize);
5892     }
5893     else if(sClassName=="QBuffer")
5894     {
5895         ((QBuffer *)pDevice)->buffer().resize((qint32)nSize);
5896         bResult=true;
5897     }
5898 
5899     return bResult;
5900 }
5901 
read_uleb128(qint64 nOffset,qint64 nSize)5902 XBinary::PACKED_INT XBinary::read_uleb128(qint64 nOffset,qint64 nSize)
5903 {
5904     PACKED_INT result={};
5905 
5906     quint32 nShift=0;
5907 
5908     for(int i=0;i<nSize;i++)
5909     {
5910         quint8 nByte=read_uint8(nOffset+i);
5911         result.nValue|=((nByte&0x7F)<<nShift);
5912         result.nByteSize++;
5913         nShift+=7;
5914 
5915         if((nByte&0x80)==0)
5916         {
5917             result.bIsValid=true;
5918             break;
5919         }
5920     }
5921 
5922     return result;
5923 }
5924 
_read_uleb128(char * pData,qint64 nSize)5925 XBinary::PACKED_INT XBinary::_read_uleb128(char *pData,qint64 nSize)
5926 {
5927     PACKED_INT result={};
5928 
5929     quint32 nShift=0;
5930 
5931     for(int i=0;i<nSize;i++)
5932     {
5933         quint8 nByte=(quint8)(*(pData+i));
5934         result.nValue|=((nByte&0x7F)<<nShift);
5935         result.nByteSize++;
5936         nShift+=7;
5937 
5938         if((nByte&0x80)==0)
5939         {
5940             result.bIsValid=true;
5941             break;
5942         }
5943     }
5944 
5945     return result;
5946 }
5947 
read_acn1_integer(qint64 nOffset,qint64 nSize)5948 XBinary::PACKED_INT XBinary::read_acn1_integer(qint64 nOffset, qint64 nSize)
5949 {
5950     PACKED_INT result={};
5951 
5952     if(nSize>0)
5953     {
5954         quint8 nByte=read_uint8(nOffset);
5955 
5956         if((nByte&0x80)==0)
5957         {
5958             result.bIsValid=true;
5959             result.nByteSize=1;
5960             result.nValue=nByte;
5961         }
5962         else
5963         {
5964             quint8 _nSize=(nByte&0x7F);
5965 
5966             if((_nSize<=4)&&(_nSize<=nSize))
5967             {
5968                 result.bIsValid=true;
5969                 result.nByteSize=1+_nSize;
5970 
5971                 for(int i=0;i<_nSize;i++)
5972                 {
5973                     result.nValue<<=8;
5974                     result.nValue|=read_uint8(nOffset+1+i);
5975                 }
5976             }
5977         }
5978     }
5979 
5980     return result;
5981 }
5982 
get_packedNumber(qint64 nOffset)5983 XBinary::PACKED XBinary::get_packedNumber(qint64 nOffset)
5984 {
5985     PACKED result={};
5986 
5987     quint8 nFirstByte=0;
5988     quint8 nSecondByte=0;
5989     quint8 nMask=0;
5990     qint64 _nStartOffset=nOffset;
5991 
5992     for(int i=0;i<8;i++)
5993     {
5994         if(i==0)
5995         {
5996             nFirstByte=read_uint8(nOffset);
5997             nOffset++;
5998             if((nFirstByte&0x80)==0)
5999             {
6000                 result.nValue=nFirstByte;
6001                 break;
6002             }
6003         }
6004         if(i==1)
6005         {
6006             nSecondByte=read_uint8(nOffset);
6007             nOffset++;
6008             if((nFirstByte&0x40)==0)
6009             {
6010                 result.nValue=(((quint32)nFirstByte&0x3F)<<8)|nSecondByte;
6011                 break;
6012             }
6013             nMask=read_uint8(nOffset);
6014             nOffset++;
6015             result.nValue=nSecondByte|((quint32)nMask<<8);
6016             nMask=0x20;
6017         }
6018         if(i==2)
6019         {
6020             if((nFirstByte&nMask)==0)
6021             {
6022                 quint64 nHighPart=nFirstByte&(nMask-1);
6023                 result.nValue|=(nHighPart<<(8*i));
6024                 break;
6025             }
6026 
6027             quint8 nByte=read_uint8(nOffset);
6028             nOffset++;
6029             result.nValue|=((quint64)nByte)<<(8*i);
6030             nMask>>=1;
6031         }
6032     }
6033 
6034     result.nByteSize=nOffset-_nStartOffset;
6035 
6036     return result;
6037 }
6038 
getListFromFile(QString sFileName)6039 QList<QString> XBinary::getListFromFile(QString sFileName)
6040 {
6041     QList<QString> listResult;
6042 
6043     QFile file;
6044     file.setFileName(sFileName);
6045 
6046     if(file.open(QIODevice::ReadOnly))
6047     {
6048         QTextStream in(&file);
6049         while(!in.atEnd())
6050         {
6051             QString sLine=in.readLine().trimmed();
6052             if(sLine!="")
6053             {
6054                 listResult.append(sLine);
6055             }
6056         }
6057 
6058         file.close();
6059     }
6060 
6061     return listResult;
6062 }
6063 
getOverlaySize()6064 qint64 XBinary::getOverlaySize()
6065 {
6066     _MEMORY_MAP memoryMap=getMemoryMap();
6067 
6068     return getOverlaySize(&memoryMap);
6069 }
6070 
getOverlaySize(XBinary::_MEMORY_MAP * pMemoryMap)6071 qint64 XBinary::getOverlaySize(XBinary::_MEMORY_MAP *pMemoryMap)
6072 {
6073     qint64 nSize=getSize();
6074     qint64 nOverlayOffset=getOverlayOffset(pMemoryMap);
6075     qint64 nDelta=0;
6076 
6077     if(nOverlayOffset>0)
6078     {
6079         nDelta=nSize-nOverlayOffset;
6080     }
6081 
6082     return qMax(nDelta,(qint64)0);
6083 }
6084 
getOverlayOffset()6085 qint64 XBinary::getOverlayOffset()
6086 {
6087     _MEMORY_MAP memoryMap=getMemoryMap();
6088 
6089     return getOverlayOffset(&memoryMap);
6090 }
6091 
getOverlayOffset(XBinary::_MEMORY_MAP * pMemoryMap)6092 qint64 XBinary::getOverlayOffset(XBinary::_MEMORY_MAP *pMemoryMap)
6093 {
6094     qint64 nResult=-1;
6095     qint64 nRawSize=_calculateRawSize(pMemoryMap);
6096 
6097     if(nRawSize)
6098     {
6099         nResult=nRawSize;
6100     }
6101 
6102     return nResult;
6103 }
6104 
isOverlayPresent()6105 bool XBinary::isOverlayPresent()
6106 {
6107     _MEMORY_MAP memoryMap=getMemoryMap();
6108 
6109     return isOverlayPresent(&memoryMap);
6110 }
6111 
isOverlayPresent(XBinary::_MEMORY_MAP * pMemoryMap)6112 bool XBinary::isOverlayPresent(XBinary::_MEMORY_MAP *pMemoryMap)
6113 {
6114     return (getOverlaySize(pMemoryMap)!=0);
6115 }
6116 
compareOverlay(QString sSignature,qint64 nOffset)6117 bool XBinary::compareOverlay(QString sSignature, qint64 nOffset)
6118 {
6119     _MEMORY_MAP memoryMap=getMemoryMap();
6120 
6121     return compareOverlay(&memoryMap,sSignature,nOffset);
6122 }
6123 
compareOverlay(XBinary::_MEMORY_MAP * pMemoryMap,QString sSignature,qint64 nOffset)6124 bool XBinary::compareOverlay(XBinary::_MEMORY_MAP *pMemoryMap, QString sSignature, qint64 nOffset)
6125 {
6126     bool bResult=false;
6127 
6128     if(isOverlayPresent(pMemoryMap))
6129     {
6130         qint64 nOverlayOffset=getOverlayOffset(pMemoryMap)+nOffset;
6131 
6132         bResult=compareSignature(pMemoryMap,sSignature,nOverlayOffset);
6133     }
6134 
6135     return bResult;
6136 }
6137 
addOverlay(char * pData,qint64 nDataSize)6138 bool XBinary::addOverlay(char *pData, qint64 nDataSize)
6139 {
6140     bool bResult=false;
6141 
6142     qint64 nRawSize=getOverlayOffset();
6143 
6144     if(resize(getDevice(),nRawSize+nDataSize))
6145     {
6146         if(nDataSize)
6147         {
6148             write_array(nRawSize,pData,nDataSize);
6149 
6150             bResult=true;
6151         }
6152     }
6153 
6154     return bResult;
6155 }
6156 
removeOverlay()6157 bool XBinary::removeOverlay()
6158 {
6159     return addOverlay(0,0);
6160 }
6161 
isSignatureInLoadSegmentPresent(qint32 nLoadSegment,QString sSignature)6162 bool XBinary::isSignatureInLoadSegmentPresent(qint32 nLoadSegment, QString sSignature)
6163 {
6164     _MEMORY_MAP memoryMap=getMemoryMap();
6165 
6166     return isSignatureInLoadSegmentPresent(&memoryMap,nLoadSegment,sSignature);
6167 }
6168 
isSignatureInLoadSegmentPresent(XBinary::_MEMORY_MAP * pMemoryMap,qint32 nLoadSegment,QString sSignature)6169 bool XBinary::isSignatureInLoadSegmentPresent(XBinary::_MEMORY_MAP *pMemoryMap, qint32 nLoadSegment, QString sSignature)
6170 {
6171     bool bResult=false;
6172 
6173     int nNumberOfRecords=pMemoryMap->listRecords.count();
6174 
6175     for(int i=0;i<nNumberOfRecords;i++)
6176     {
6177         if((pMemoryMap->listRecords.at(i).type==MMT_LOADSEGMENT)&&(pMemoryMap->listRecords.at(i).nLoadSection==nLoadSegment))
6178         {
6179             if(pMemoryMap->listRecords.at(i).nOffset!=-1)
6180             {
6181                 bResult=isSignaturePresent(pMemoryMap,pMemoryMap->listRecords.at(i).nOffset,pMemoryMap->listRecords.at(i).nSize,sSignature);
6182 
6183                 break;
6184             }
6185         }
6186     }
6187 
6188     return bResult;
6189 }
6190 
getStringCollision(QList<QString> * pListStrings,QString sString1,QString sString2)6191 QString XBinary::getStringCollision(QList<QString> *pListStrings, QString sString1, QString sString2)
6192 {
6193     // TODO Check&optimize
6194     QString sResult;
6195 
6196     int nNumberOfStrings=pListStrings->count();
6197 
6198     QString sRoot1;
6199     QString sRoot2;
6200 
6201     for(int i=0;i<nNumberOfStrings;i++)
6202     {
6203         QString sCurrentString=pListStrings->at(i);
6204 
6205         if(sCurrentString.contains(sString1))
6206         {
6207             sRoot1=sCurrentString.section(sString1,0,0);
6208         }
6209 
6210         if((sRoot1!="")&&sCurrentString.contains(sString2))
6211         {
6212             sRoot2=sCurrentString.section(sString2,0,0);
6213 
6214             break;
6215         }
6216     }
6217 
6218     if((sRoot1!="")&&(sRoot1==sRoot2))
6219     {
6220         sResult=sRoot1;
6221     }
6222 
6223     return sResult;
6224 }
6225 
writeToFile(QString sFileName,QByteArray baData)6226 bool XBinary::writeToFile(QString sFileName, QByteArray baData)
6227 {
6228     bool bResult=false;
6229 
6230     QFile file;
6231     file.setFileName(sFileName);
6232 
6233     if(file.open(QIODevice::ReadWrite))
6234     {
6235         file.resize(0);
6236 
6237         file.write(baData.data(),baData.size());
6238 
6239         file.close();
6240         bResult=true;
6241     }
6242 
6243     return bResult;
6244 }
6245 
writeToFile(QString sFileName,QIODevice * pDevice)6246 bool XBinary::writeToFile(QString sFileName, QIODevice *pDevice)
6247 {
6248     bool bResult=false;
6249 
6250     if(createFile(sFileName,pDevice->size()))
6251     {
6252         QFile file;
6253         file.setFileName(sFileName);
6254 
6255         if(file.open(QIODevice::ReadWrite))
6256         {
6257             bResult=copyDeviceMemory(pDevice,0,&file,0,pDevice->size(),READWRITE_BUFFER_SIZE);
6258 
6259             file.close();
6260         }
6261     }
6262 
6263     return bResult;
6264 }
6265 
appendToFile(QString sFileName,QString sString)6266 bool XBinary::appendToFile(QString sFileName, QString sString)
6267 {
6268     bool bResult=false;
6269 
6270     QFile file;
6271     file.setFileName(sFileName);
6272 
6273     if(file.open(QIODevice::ReadWrite|QIODevice::Append))
6274     {
6275         sString+="\r\n"; // TODO Linux
6276         file.write(sString.toUtf8());
6277 
6278         file.close();
6279         bResult=true;
6280     }
6281 
6282     return bResult;
6283 }
6284 
clearFile(QString sFileName)6285 bool XBinary::clearFile(QString sFileName)
6286 {
6287     bool bResult=false;
6288 
6289     QFile file;
6290     file.setFileName(sFileName);
6291 
6292     if(file.open(QIODevice::ReadWrite))
6293     {
6294         file.resize(0);
6295 
6296         file.close();
6297         bResult=true;
6298     }
6299 
6300     return bResult;
6301 }
6302 
getStringNumberFromList(QList<QString> * pListStrings,QString sString,bool * pbIsStop)6303 qint32 XBinary::getStringNumberFromList(QList<QString> *pListStrings, QString sString, bool *pbIsStop)
6304 {
6305     bool _bIsStop=false;
6306 
6307     if(pbIsStop==nullptr)
6308     {
6309         pbIsStop=&_bIsStop;
6310     }
6311 
6312     qint32 nResult=-1;
6313 
6314     qint32 nNumberOfRecords=pListStrings->count();
6315 
6316     for(qint32 i=0;(i<nNumberOfRecords)&&(!(*pbIsStop));i++)
6317     {
6318         if(pListStrings->at(i)==sString)
6319         {
6320             nResult=i;
6321 
6322             break;
6323         }
6324     }
6325 
6326     return nResult;
6327 }
6328 
getStringNumberFromListExp(QList<QString> * pListStrings,QString sString,bool * pbIsStop)6329 qint32 XBinary::getStringNumberFromListExp(QList<QString> *pListStrings, QString sString, bool *pbIsStop)
6330 {
6331     bool _bIsStop=false;
6332 
6333     if(pbIsStop==nullptr)
6334     {
6335         pbIsStop=&_bIsStop;
6336     }
6337 
6338     qint32 nResult=-1;
6339 
6340     qint32 nNumberOfRecords=pListStrings->count();
6341 
6342     for(qint32 i=0;(i<nNumberOfRecords)&&(!(*pbIsStop));i++)
6343     {
6344         if(isRegExpPresent(sString,pListStrings->at(i)))
6345         {
6346             nResult=i;
6347 
6348             break;
6349         }
6350     }
6351 
6352     return nResult;
6353 }
6354 
isStringInListPresent(QList<QString> * pListStrings,QString sString,bool * pbIsStop)6355 bool XBinary::isStringInListPresent(QList<QString> *pListStrings, QString sString, bool *pbIsStop)
6356 {
6357     return (getStringNumberFromList(pListStrings,sString,pbIsStop)!=-1);
6358 }
6359 
isStringInListPresentExp(QList<QString> * pListStrings,QString sString,bool * pbIsStop)6360 bool XBinary::isStringInListPresentExp(QList<QString> *pListStrings, QString sString, bool *pbIsStop)
6361 {
6362     return (getStringNumberFromListExp(pListStrings,sString,pbIsStop)!=-1);
6363 }
6364 
getStringByIndex(QList<QString> * pListStrings,int nIndex,qint32 nNumberOfStrings)6365 QString XBinary::getStringByIndex(QList<QString> *pListStrings, int nIndex, qint32 nNumberOfStrings)
6366 {
6367     QString sResult;
6368 
6369     if(nNumberOfStrings==-1)
6370     {
6371         nNumberOfStrings=pListStrings->count();
6372     }
6373 
6374     if((nIndex>0)&&(nIndex<nNumberOfStrings))
6375     {
6376         sResult=pListStrings->at(nIndex);
6377     }
6378 
6379     return sResult;
6380 }
6381 
isStringUnicode(QString sString,qint32 nMaxCheckSize)6382 bool XBinary::isStringUnicode(QString sString, qint32 nMaxCheckSize)
6383 {
6384     // TODO Optimize
6385     // TODO Check
6386     bool bResult=false;
6387 
6388     if(nMaxCheckSize==-1)
6389     {
6390         nMaxCheckSize=sString.size();
6391     }
6392     else
6393     {
6394         nMaxCheckSize=qMin(sString.size(),nMaxCheckSize);
6395     }
6396 
6397     for(int i=0;i<nMaxCheckSize;i++)
6398     {
6399         unsigned char cChar=sString.at(i).toLatin1();
6400         if((cChar>127)||(cChar<27))
6401         {
6402             bResult=true;
6403             break;
6404         }
6405     }
6406 
6407     return bResult;
6408 }
6409 
elfHash(const quint8 * pData)6410 quint32 XBinary::elfHash(const quint8 *pData)
6411 {
6412     quint32 nResult=0;
6413 
6414     while(*pData)
6415     {
6416         nResult=(nResult<<4)+(*pData);
6417 
6418         quint32 nHigh=nResult&0xF0000000;
6419 
6420         if(nHigh)
6421         {
6422             nResult^=(nResult>>24);
6423         }
6424 
6425         nResult&=(~nHigh);
6426 
6427         pData++;
6428     }
6429 
6430     return nResult;
6431 }
6432 
getVersionString(QString sString)6433 QString XBinary::getVersionString(QString sString)
6434 {
6435     QString sResult;
6436 
6437     int nSize=sString.size();
6438 
6439     for(int i=0;i<nSize;i++)
6440     {
6441         QChar c=sString.at(i);
6442 
6443         if(((QChar('9')>=c)&&(c>=QChar('0')))||(c==QChar('.')))
6444         {
6445             sResult.append(c);
6446         }
6447         else
6448         {
6449             break;
6450         }
6451     }
6452 
6453     return sResult;
6454 }
6455 
getVersionIntValue(QString sString)6456 qint64 XBinary::getVersionIntValue(QString sString)
6457 {
6458     qint64 nResult=0;
6459 
6460     int nNumberOfDots=sString.count(QChar('.'));
6461 
6462     for(int i=0;i<(nNumberOfDots+1);i++)
6463     {
6464         nResult*=10;
6465 
6466         nResult+=sString.section(QChar('.'),i,i).toLongLong();
6467     }
6468 
6469     return nResult;
6470 }
6471 
checkStringNumber(QString sString,quint32 nMin,quint32 nMax)6472 bool XBinary::checkStringNumber(QString sString, quint32 nMin, quint32 nMax)
6473 {
6474     bool bResult=false;
6475 
6476     quint32 nValue=sString.toUInt();
6477 
6478     bResult=((nValue>=nMin)&&(nValue<=nMax));
6479 
6480     return bResult;
6481 }
6482 
valueToTimeString(quint64 nValue,XBinary::DT_TYPE type)6483 QString XBinary::valueToTimeString(quint64 nValue, XBinary::DT_TYPE type)
6484 {
6485     QString sResult;
6486 
6487     // TODO more
6488     if(type==DT_TYPE_POSIX)
6489     {
6490         QDateTime dt;
6491         dt.setMSecsSinceEpoch(nValue*1000);
6492 
6493         sResult=dt.toString("yyyy-MM-dd hh:mm:ss");
6494     }
6495 
6496     return sResult;
6497 }
6498 
isX86asm(QString sArch)6499 bool XBinary::isX86asm(QString sArch)
6500 {
6501     bool bResult=false;
6502 
6503     sArch=sArch.toUpper();
6504 
6505     // TODO Check
6506     if( (sArch=="8086")||
6507         (sArch=="80286")||
6508         (sArch=="80386")||
6509         (sArch=="80486")||
6510         (sArch=="80586")||
6511         (sArch=="386")||
6512         (sArch=="I386")||
6513         (sArch=="AMD64")||
6514         (sArch=="X86_64"))
6515     {
6516         bResult=true;
6517     }
6518 
6519     return bResult;
6520 }
6521 
disasmIdToString(XBinary::DM disasmMode)6522 QString XBinary::disasmIdToString(XBinary::DM disasmMode)
6523 {
6524     QString sResult="Unknown"; // mb TODO translate
6525 
6526     switch(disasmMode)
6527     {
6528         case DM_X86_16:             sResult=QString("X86-16");          break;
6529         case DM_X86_32:             sResult=QString("X86-32");          break;
6530         case DM_X86_64:             sResult=QString("X86-64");          break;
6531         case DM_ARM_LE:             sResult=QString("ARM");             break;
6532         case DM_ARM_BE:             sResult=QString("ARM BE");          break;
6533         case DM_ARM64_LE:           sResult=QString("ARM64");           break;
6534         case DM_ARM64_BE:           sResult=QString("ARM64 BE");        break;
6535         case DM_CORTEXM:            sResult=QString("CORTEXM");         break;
6536         case DM_THUMB_LE:           sResult=QString("THUMB");           break;
6537         case DM_THUMB_BE:           sResult=QString("THUMB BE");        break;
6538         case DM_MIPS_LE:            sResult=QString("MIPS");            break;
6539         case DM_MIPS_BE:            sResult=QString("MIPS BE");         break;
6540         case DM_MIPS64_LE:          sResult=QString("MIPS64");          break;
6541         case DM_MIPS64_BE:          sResult=QString("MIPS64 BE");       break;
6542         case DM_PPC_LE:             sResult=QString("PPC");             break;
6543         case DM_PPC_BE:             sResult=QString("PPC BE");          break;
6544         case DM_PPC64_LE:           sResult=QString("PPC64");           break;
6545         case DM_PPC64_BE:           sResult=QString("PPC64 BE");        break;
6546         case DM_SPARC:              sResult=QString("SPARC");           break;
6547         case DM_S390X:              sResult=QString("S390X");           break;
6548         case DM_XCORE:              sResult=QString("XCORE");           break;
6549         case DM_M68K:               sResult=QString("M68K");            break;
6550         case DM_M68K40:             sResult=QString("M68K40");          break;
6551         case DM_TMS320C64X:         sResult=QString("TMS320C64X");      break;
6552         case DM_M6800:              sResult=QString("M6800");           break;
6553         case DM_M6801:              sResult=QString("M6801");           break;
6554         case DM_M6805:              sResult=QString("M6805");           break;
6555         case DM_M6808:              sResult=QString("M6808");           break;
6556         case DM_M6809:              sResult=QString("M6809");           break;
6557         case DM_M6811:              sResult=QString("M6811");           break;
6558         case DM_CPU12:              sResult=QString("CPU12");           break;
6559         case DM_HD6301:             sResult=QString("HD6301");          break;
6560         case DM_HD6309:             sResult=QString("HD6309");          break;
6561         case DM_HCS08:              sResult=QString("HCS08");           break;
6562         case DM_EVM:                sResult=QString("EVM");             break;
6563         case DM_RISKV32:            sResult=QString("RISKV32");         break;
6564         case DM_RISKV64:            sResult=QString("RISKV64");         break;
6565         case DM_RISKVC:             sResult=QString("RISKVC");          break;
6566 //        case DM_MOS65XX:            sResult=QString("MOS65XX");         break;
6567     }
6568 
6569     return sResult;
6570 }
6571 
getDisasmMode(XBinary::_MEMORY_MAP * pMemoryMap)6572 XBinary::DM XBinary::getDisasmMode(XBinary::_MEMORY_MAP *pMemoryMap)
6573 {
6574     XBinary::DM dmResult=DM_X86_16;
6575 
6576     if(pMemoryMap->sArch=="PPC")
6577     {
6578         if(pMemoryMap->bIsBigEndian)
6579         {
6580             dmResult=DM_PPC_BE;
6581         }
6582         else
6583         {
6584             dmResult=DM_PPC_LE;
6585         }
6586     }
6587     else if(pMemoryMap->sArch=="PPC64")
6588     {
6589         if(pMemoryMap->bIsBigEndian)
6590         {
6591             dmResult=DM_PPC64_BE;
6592         }
6593         else
6594         {
6595             dmResult=DM_PPC64_LE;
6596         }
6597     }
6598     else if(pMemoryMap->sArch=="MIPS")
6599     {
6600         if(pMemoryMap->bIsBigEndian)
6601         {
6602             dmResult=DM_MIPS_BE;
6603         }
6604         else
6605         {
6606             dmResult=DM_MIPS_LE;
6607         }
6608     }
6609     else if(pMemoryMap->sArch=="ARM")
6610     {
6611         if(pMemoryMap->bIsBigEndian)
6612         {
6613             dmResult=DM_ARM_BE;
6614         }
6615         else
6616         {
6617             dmResult=DM_ARM_LE;
6618         }
6619     }
6620     else if((pMemoryMap->sArch=="AARCH64")||
6621             (pMemoryMap->sArch=="ARM64"))
6622     {
6623         if(pMemoryMap->bIsBigEndian)
6624         {
6625             dmResult=DM_ARM64_BE;
6626         }
6627         else
6628         {
6629             dmResult=DM_ARM64_LE;
6630         }
6631     }
6632     else if(pMemoryMap->sArch=="8086") // TODO
6633     {
6634         dmResult=DM_X86_16;
6635     }
6636     else if((pMemoryMap->sArch=="386")||
6637             (pMemoryMap->sArch=="I386")||
6638             (pMemoryMap->sArch=="486"))
6639     {
6640         dmResult=DM_X86_32;
6641     }
6642     else if((pMemoryMap->sArch=="AMD64")||
6643             (pMemoryMap->sArch=="X86_64"))
6644     {
6645         dmResult=DM_X86_64;
6646     }
6647     else if((pMemoryMap->sArch=="68K")||
6648             (pMemoryMap->sArch=="MC680x0")||
6649             (pMemoryMap->sArch=="MC68030"))
6650     {
6651         dmResult=DM_M68K;
6652     }
6653     else if(pMemoryMap->sArch=="MC68040")
6654     {
6655         dmResult=DM_M68K40;
6656     }
6657     else if(pMemoryMap->sArch=="SPARC")
6658     {
6659         dmResult=DM_SPARC;
6660     }
6661     else if(pMemoryMap->sArch=="EM_RISC_V")
6662     {
6663         if(pMemoryMap->mode==MODE_64)
6664         {
6665             dmResult=DM_RISKV64;
6666         }
6667         else
6668         {
6669             dmResult=DM_RISKV32;
6670         }
6671     }
6672     // TODO SH
6673 
6674     return dmResult;
6675 }
6676 
getDisasmFamily(XBinary::DM disasmMode)6677 XBinary::DMFAMILY XBinary::getDisasmFamily(XBinary::DM disasmMode)
6678 {
6679     DMFAMILY result=DMFAMILY_UNKNOWN;
6680 
6681     if((disasmMode==DM_X86_16)||(disasmMode==DM_X86_32)||(disasmMode==DM_X86_64))
6682     {
6683         result=DMFAMILY_X86;
6684     }
6685     else if((disasmMode==DM_ARM_BE)||(disasmMode==DM_ARM_LE))
6686     {
6687         result=DMFAMILY_ARM;
6688     }
6689     else if((disasmMode==DM_ARM64_BE)||(disasmMode==DM_ARM64_LE))
6690     {
6691         result=DMFAMILY_ARM64;
6692     }
6693     else if((disasmMode==DM_MIPS64_BE)||(disasmMode==DM_MIPS64_LE)||
6694             (disasmMode==DM_MIPS_BE)||(disasmMode==DM_MIPS_LE))
6695     {
6696         result=DMFAMILY_MIPS;
6697     }
6698     else if((disasmMode==DM_PPC64_BE)||(disasmMode==DM_PPC64_LE)||
6699             (disasmMode==DM_PPC_BE)||(disasmMode==DM_PPC_LE))
6700     {
6701         result=DMFAMILY_PPC;
6702     }
6703     else if(disasmMode==DM_SPARC)
6704     {
6705         result=DMFAMILY_SPARC;
6706     }
6707     else if(disasmMode==DM_S390X)
6708     {
6709         result=DMFAMILY_SYSZ;
6710     }
6711     else if(disasmMode==DM_XCORE)
6712     {
6713         result=DMFAMILY_XCORE;
6714     }
6715     else if((disasmMode==DM_M68K)||(disasmMode==DM_M68K40))
6716     {
6717         result=DMFAMILY_M68K;
6718     }
6719     else if((disasmMode==DM_M6800)||(disasmMode==DM_M6801)||
6720             (disasmMode==DM_M6805)||(disasmMode==DM_M6808)||
6721             (disasmMode==DM_M6809)||(disasmMode==DM_M6811)||
6722             (disasmMode==DM_CPU12)||(disasmMode==DM_HD6301)||
6723             (disasmMode==DM_HD6309)||(disasmMode==DM_HCS08))
6724     {
6725         result=DMFAMILY_M68OK;
6726     }
6727     else if((disasmMode==DM_RISKV32)||(disasmMode==DM_RISKV64)||(disasmMode==DM_RISKVC))
6728     {
6729         result=DMFAMILY_RISCV;
6730     }
6731     else if(disasmMode==DM_EVM)
6732     {
6733         result=DMFAMILY_EVM;
6734     }
6735 
6736     return result;
6737 }
6738 
checkFileType(XBinary::FT fileTypeMain,XBinary::FT fileTypeOptional)6739 bool XBinary::checkFileType(XBinary::FT fileTypeMain, XBinary::FT fileTypeOptional)
6740 {
6741     bool bResult=false;
6742 
6743     if((fileTypeMain==FT_LE)&&((fileTypeOptional==FT_LE)||(fileTypeOptional==FT_LX)))
6744     {
6745         bResult=true;
6746     }
6747     else if((fileTypeMain==FT_PE)&&((fileTypeOptional==FT_PE)||(fileTypeOptional==FT_PE32)||(fileTypeOptional==FT_PE64)))
6748     {
6749         bResult=true;
6750     }
6751     else if((fileTypeMain==FT_ELF)&&((fileTypeOptional==FT_ELF)||(fileTypeOptional==FT_ELF32)||(fileTypeOptional==FT_ELF64)))
6752     {
6753         bResult=true;
6754     }
6755     else if((fileTypeMain==FT_MACHO)&&((fileTypeOptional==FT_MACHO)||(fileTypeOptional==FT_MACHO32)||(fileTypeOptional==FT_MACHO64)))
6756     {
6757         bResult=true;
6758     }
6759     else if(fileTypeMain==fileTypeOptional)
6760     {
6761         bResult=true;
6762     }
6763 
6764     return  bResult;
6765 }
6766 
filterFileTypes(QSet<XBinary::FT> * pStFileTypes)6767 void XBinary::filterFileTypes(QSet<XBinary::FT> *pStFileTypes)
6768 {
6769     // TODO Check!
6770     // TODO optimize! new Types create remove function
6771     if( pStFileTypes->contains(XBinary::FT_MSDOS)||
6772         pStFileTypes->contains(XBinary::FT_NE)||
6773         pStFileTypes->contains(XBinary::FT_LE)||
6774         pStFileTypes->contains(XBinary::FT_LX)||
6775         pStFileTypes->contains(XBinary::FT_PE)||
6776         pStFileTypes->contains(XBinary::FT_PE32)||
6777         pStFileTypes->contains(XBinary::FT_PE64)||
6778         pStFileTypes->contains(XBinary::FT_ELF)||
6779         pStFileTypes->contains(XBinary::FT_ELF32)||
6780         pStFileTypes->contains(XBinary::FT_ELF64)||
6781         pStFileTypes->contains(XBinary::FT_MACHO)||
6782         pStFileTypes->contains(XBinary::FT_MACHO32)||
6783         pStFileTypes->contains(XBinary::FT_MACHO64)||
6784         pStFileTypes->contains(XBinary::FT_DEX)||
6785         pStFileTypes->contains(XBinary::FT_ZIP))
6786     {
6787         pStFileTypes->remove(XBinary::FT_BINARY);
6788     }
6789     else
6790     {
6791         pStFileTypes->insert(XBinary::FT_COM);
6792     }
6793 }
6794 
filterFileTypes(QSet<XBinary::FT> * pStFileTypes,XBinary::FT fileType)6795 void XBinary::filterFileTypes(QSet<XBinary::FT> *pStFileTypes, XBinary::FT fileType)
6796 {
6797     // TODO Check!
6798     QSet<XBinary::FT> stFileTypesNew;
6799 
6800     if(fileType==XBinary::FT_PE)
6801     {
6802         if(pStFileTypes->contains(XBinary::FT_PE)) stFileTypesNew.insert(XBinary::FT_PE);
6803         if(pStFileTypes->contains(XBinary::FT_PE32)) stFileTypesNew.insert(XBinary::FT_PE32);
6804         if(pStFileTypes->contains(XBinary::FT_PE64)) stFileTypesNew.insert(XBinary::FT_PE64);
6805     }
6806     else if(fileType==XBinary::FT_ELF)
6807     {
6808         if(pStFileTypes->contains(XBinary::FT_ELF)) stFileTypesNew.insert(XBinary::FT_ELF);
6809         if(pStFileTypes->contains(XBinary::FT_ELF32)) stFileTypesNew.insert(XBinary::FT_ELF32);
6810         if(pStFileTypes->contains(XBinary::FT_ELF64)) stFileTypesNew.insert(XBinary::FT_ELF64);
6811     }
6812     else if(fileType==XBinary::FT_MACHO)
6813     {
6814         if(pStFileTypes->contains(XBinary::FT_MACHO)) stFileTypesNew.insert(XBinary::FT_MACHO);
6815         if(pStFileTypes->contains(XBinary::FT_MACHO32)) stFileTypesNew.insert(XBinary::FT_MACHO32);
6816         if(pStFileTypes->contains(XBinary::FT_MACHO64)) stFileTypesNew.insert(XBinary::FT_MACHO64);
6817     }
6818     else
6819     {
6820         if(pStFileTypes->contains(fileType)) stFileTypesNew.insert(fileType);
6821     }
6822 
6823     *pStFileTypes=stFileTypesNew;
6824 }
6825 
isFileTypePresent(QSet<XBinary::FT> * pStFileTypes,QSet<XBinary::FT> * pStAvailableFileTypes)6826 bool XBinary::isFileTypePresent(QSet<XBinary::FT> *pStFileTypes, QSet<XBinary::FT> *pStAvailableFileTypes)
6827 {
6828     bool bResult=false;
6829 
6830     QSet<XBinary::FT>::iterator i=pStFileTypes->begin();
6831 
6832     while(i!=pStFileTypes->end())
6833     {
6834         if(pStAvailableFileTypes->contains(*i))
6835         {
6836             bResult=true;
6837 
6838             break;
6839         }
6840 
6841         i++;
6842     }
6843 
6844     return bResult;
6845 }
6846 
procentInit(qint64 nMaxValue,bool bTimer)6847 XBinary::PROCENT XBinary::procentInit(qint64 nMaxValue,bool bTimer)
6848 {
6849     PROCENT result={};
6850     result.bTimer=bTimer;
6851 
6852     result.nMaxValue=nMaxValue;
6853 
6854     if(!(result.bTimer))
6855     {
6856         result.nMaxProcent=1;
6857 
6858         if(result.nMaxValue>0x100000000)
6859         {
6860             result.nMaxProcent=100;
6861         }
6862         else if(result.nMaxValue>0x100000)
6863         {
6864             result.nMaxProcent=10;
6865         }
6866         else if(result.nMaxValue>0x1000)
6867         {
6868             result.nMaxProcent=5;
6869         }
6870     }
6871     else
6872     {
6873         result.timer.start();
6874         result.nMaxProcent=100;
6875     }
6876 
6877     return result;
6878 }
6879 
procentSetCurrentValue(XBinary::PROCENT * pProcent,qint64 nCurrentValue)6880 bool XBinary::procentSetCurrentValue(XBinary::PROCENT *pProcent, qint64 nCurrentValue)
6881 {
6882     bool bResult=false;
6883 
6884     pProcent->nCurrentValue=nCurrentValue;
6885 
6886     if(!(pProcent->bTimer))
6887     {
6888         if(pProcent->nCurrentValue>((pProcent->nCurrentProcent+1)*(pProcent->nMaxValue/pProcent->nMaxProcent)))
6889         {
6890             pProcent->nCurrentProcent++;
6891             bResult=true;
6892         }
6893     }
6894     else
6895     {
6896         if(pProcent->timer.elapsed()>=1000) // TODO Check speed
6897         {
6898             pProcent->timer.restart();
6899 
6900             qint32 _nCurrent=(pProcent->nCurrentValue*100)/(pProcent->nMaxValue);
6901 
6902             pProcent->nCurrentProcent=_nCurrent;
6903             bResult=true;
6904         }
6905     }
6906 
6907     return bResult;
6908 }
6909 
getTotalOSSize(QList<OFFSETSIZE> * pListOS)6910 qint64 XBinary::getTotalOSSize(QList<OFFSETSIZE> *pListOS)
6911 {
6912     qint64 nResult=0;
6913 
6914     int nNumberOfRecords=pListOS->count();
6915 
6916     for(int i=0;i<nNumberOfRecords;i++)
6917     {
6918         nResult+=pListOS->at(i).nSize;
6919     }
6920 
6921     return nResult;
6922 }
6923 
getWidthModeFromSize(quint64 nSize)6924 XBinary::MODE XBinary::getWidthModeFromSize(quint64 nSize)
6925 {
6926     MODE result=MODE_32;
6927 
6928     if(((quint64)nSize)>=0xFFFFFFFF)
6929     {
6930         result=MODE_64;
6931     }
6932     else if(((quint64)nSize)>=0xFFFF)
6933     {
6934         result=MODE_32;
6935     }
6936     else if(((quint64)nSize)>=0xFF)
6937     {
6938         result=MODE_16;
6939     }
6940     else
6941     {
6942         result=MODE_8;
6943     }
6944 
6945     return result;
6946 }
6947 
getWidthModeFromMemoryMap(XBinary::_MEMORY_MAP * pMemoryMap)6948 XBinary::MODE XBinary::getWidthModeFromMemoryMap(XBinary::_MEMORY_MAP *pMemoryMap)
6949 {
6950     MODE result=MODE_32;
6951 
6952     qint64 nMax=qMax(pMemoryMap->nModuleAddress+pMemoryMap->nImageSize,pMemoryMap->nRawSize);
6953 
6954     result=getWidthModeFromSize(nMax);
6955 
6956     return result;
6957 }
6958 
getWidthModeFromByteSize(quint32 nByteSize)6959 XBinary::MODE XBinary::getWidthModeFromByteSize(quint32 nByteSize)
6960 {
6961     MODE result=MODE_32;
6962 
6963     if(nByteSize==2)
6964     {
6965         result=MODE_8;
6966     }
6967     else if(nByteSize==4)
6968     {
6969         result=MODE_16;
6970     }
6971     else if(nByteSize==8)
6972     {
6973         result=MODE_32;
6974     }
6975     else if(nByteSize==16)
6976     {
6977         result=MODE_64;
6978     }
6979 
6980     return result;
6981 }
6982 
isAnsiSymbol(quint8 cCode,bool bExtra)6983 bool XBinary::isAnsiSymbol(quint8 cCode, bool bExtra)
6984 {
6985     bool bResult=false;
6986 
6987     if(!bExtra)
6988     {
6989         if((cCode>=20)&&(cCode<0x80))
6990         {
6991             bResult=true;
6992         }
6993     }
6994     else
6995     {
6996         if(cCode>=20)
6997         {
6998             bResult=true;
6999         }
7000     }
7001 
7002     return bResult;
7003 }
7004 
isUTF8Symbol(quint8 cCode,qint32 * pnWidth)7005 bool XBinary::isUTF8Symbol(quint8 cCode, qint32 *pnWidth)
7006 {
7007     bool bResult=false;
7008 
7009     if(cCode>=20)
7010     {
7011         if((cCode>>7)==0)
7012         {
7013             *pnWidth=1;
7014             bResult=true;
7015         }
7016         else if((cCode>>5)==0x6)
7017         {
7018             *pnWidth=2;
7019             bResult=true;
7020         }
7021         else if((cCode>>4)==0xE)
7022         {
7023             *pnWidth=3;
7024             bResult=true;
7025         }
7026         else if((cCode>>3)==0x1E)
7027         {
7028             *pnWidth=4;
7029             bResult=true;
7030         }
7031         else if((cCode>>6)==0x2) // Rest bytes
7032         {
7033             *pnWidth=0;
7034             bResult=true;
7035         }
7036     }
7037 
7038     return bResult;
7039 }
7040 
isUnicodeSymbol(quint16 nCode,bool bExtra)7041 bool XBinary::isUnicodeSymbol(quint16 nCode, bool bExtra)
7042 {
7043     bool bResult=false;
7044 
7045     if(!bExtra)
7046     {
7047         if((nCode>=20)&&(nCode<0x80))
7048         {
7049             bResult=true;
7050         }
7051     }
7052     else
7053     {
7054         if((nCode>=20)&&(nCode<=0xFF))
7055         {
7056             bResult=true;
7057         }
7058         else if((nCode>=0x0400)&&(nCode<=0x04FF)) // Cyrillic
7059         {
7060             bResult=true;
7061         }
7062     }
7063 
7064     return bResult;
7065 }
7066 
getStringFromIndex(qint64 nOffset,qint64 nSize,int nIndex)7067 QString XBinary::getStringFromIndex(qint64 nOffset, qint64 nSize, int nIndex)
7068 {
7069     QString sResult;
7070 
7071     if(nIndex<nSize)
7072     {
7073         sResult=read_ansiString(nOffset+nIndex);
7074     }
7075 
7076     return sResult;
7077 }
7078 
getAllFilesFromDirectory(QString sDirectory,QString sExtension)7079 QList<QString> XBinary::getAllFilesFromDirectory(QString sDirectory, QString sExtension)
7080 {
7081     QDir directory(sDirectory);
7082 
7083     return directory.entryList(QStringList()<<sExtension,QDir::Files);
7084 }
7085 
getOpcodes(qint64 nOffset,qint64 nStartAddress,qint64 nSize,quint32 nType)7086 QList<XBinary::OPCODE> XBinary::getOpcodes(qint64 nOffset, qint64 nStartAddress, qint64 nSize, quint32 nType)
7087 {
7088     QList<OPCODE> listResult;
7089 
7090     OFFSETSIZE offsetSize=convertOffsetAndSize(nOffset,nSize);
7091 
7092     nOffset=offsetSize.nOffset;
7093     nSize=offsetSize.nSize;
7094 
7095     if(nOffset!=-1)
7096     {
7097         char *pBuffer=new char[READWRITE_BUFFER_SIZE];
7098 
7099         while(nSize>0)
7100         {
7101             qint64 nTempSize=qMin((qint64)READWRITE_BUFFER_SIZE,nSize);
7102 
7103             if(read_array(nOffset,pBuffer,nTempSize)!=nTempSize)
7104             {
7105                 _errorMessage(tr("Read error"));
7106 
7107                 break;
7108             }
7109 
7110             qint64 nOpcodesSize=0;
7111             OPCODE_STATUS opcodeStatus=OPCODE_STATUS_SUCCESS;
7112 
7113             for(int i=0;i<nTempSize;)
7114             {
7115                 qint64 _nSize=readOpcodes(nType,pBuffer+i,nStartAddress+i,nTempSize-i,&listResult,&opcodeStatus);
7116 
7117                 i+=_nSize;
7118                 nOpcodesSize+=_nSize;
7119 
7120                 if((_nSize==0)||(opcodeStatus==OPCODE_STATUS_END))
7121                 {
7122                     break;
7123                 }
7124             }
7125 
7126             if((nOpcodesSize==0)||(opcodeStatus==OPCODE_STATUS_END))
7127             {
7128 //                _errorMessage(tr("Read error"));
7129                 break;
7130             }
7131 
7132             nSize-=nOpcodesSize;
7133             nOffset+=nOpcodesSize;
7134             nStartAddress+=nOpcodesSize;
7135         }
7136 
7137         delete[] pBuffer;
7138     }
7139 
7140     return listResult;
7141 }
7142 
readOpcodes(quint32 nType,char * pData,qint64 nStartAddress,qint64 nSize,QList<OPCODE> * pListOpcodes,OPCODE_STATUS * pOpcodeStatus)7143 qint64 XBinary::readOpcodes(quint32 nType, char *pData, qint64 nStartAddress, qint64 nSize, QList<OPCODE> *pListOpcodes, OPCODE_STATUS *pOpcodeStatus)
7144 {
7145     Q_UNUSED(nType)
7146     Q_UNUSED(pData)
7147     Q_UNUSED(nStartAddress)
7148     Q_UNUSED(nSize)
7149     Q_UNUSED(pListOpcodes)
7150 
7151     *pOpcodeStatus=OPCODE_STATUS_END;
7152 
7153     return false;
7154 }
7155 
_read_opcode_uleb128(OPCODE * pOpcode,char ** ppData,qint64 * pnSize,qint64 * pnAddress,qint64 * pnResult,QString sPrefix)7156 bool XBinary::_read_opcode_uleb128(OPCODE *pOpcode, char **ppData, qint64 *pnSize, qint64 *pnAddress, qint64 *pnResult, QString sPrefix)
7157 {
7158     bool bResult=false;
7159 
7160     if(*pnSize>0)
7161     {
7162         PACKED_INT uleb128=_read_uleb128(*ppData,*pnSize);
7163 
7164         if(uleb128.bIsValid)
7165         {
7166             pOpcode->nAddress=*pnAddress;
7167             pOpcode->nSize=uleb128.nByteSize;
7168             pOpcode->sName=QString("%1(%2)").arg(sPrefix,QString::number((qint64)uleb128.nValue));
7169 
7170             *pnSize-=pOpcode->nSize;
7171             *ppData+=pOpcode->nSize;
7172             *pnResult+=pOpcode->nSize;
7173             *pnAddress+=pOpcode->nSize;
7174 
7175             bResult=true;
7176         }
7177     }
7178 
7179     return bResult;
7180 }
7181 
_read_opcode_ansiString(XBinary::OPCODE * pOpcode,char ** ppData,qint64 * pnSize,qint64 * pnAddress,qint64 * pnResult,QString sPrefix)7182 bool XBinary::_read_opcode_ansiString(XBinary::OPCODE *pOpcode, char **ppData, qint64 *pnSize, qint64 *pnAddress, qint64 *pnResult, QString sPrefix)
7183 {
7184     bool bResult=false;
7185 
7186     if(*pnSize>0)
7187     {
7188         QString sString=*ppData;
7189 
7190         if(sString.size()<(*pnSize)) // We need cstring with \0
7191         {
7192             pOpcode->nAddress=*pnAddress;
7193             pOpcode->nSize=sString.size()+1;
7194             pOpcode->sName=QString("%1(\"%2\")").arg(sPrefix,sString);
7195 
7196             *pnSize-=pOpcode->nSize;
7197             *ppData+=pOpcode->nSize;
7198             *pnResult+=pOpcode->nSize;
7199             *pnAddress+=pOpcode->nSize;
7200 
7201             bResult=true;
7202         }
7203     }
7204 
7205     return bResult;
7206 }
7207 
get_uint32_list(qint64 nOffset,qint32 nNumberOfRecords,bool bIsBigEndian)7208 QList<quint32> XBinary::get_uint32_list(qint64 nOffset, qint32 nNumberOfRecords, bool bIsBigEndian)
7209 {
7210     QList<quint32> listResult;
7211 
7212     for(int i=0;i<nNumberOfRecords;i++)
7213     {
7214         quint32 nRecord=read_uint32(nOffset+i*sizeof(quint32),bIsBigEndian);
7215 
7216         listResult.append(nRecord);
7217     }
7218 
7219     return listResult;
7220 }
7221 
get_uint64_list(qint64 nOffset,qint32 nNumberOfRecords,bool bIsBigEndian)7222 QList<quint64> XBinary::get_uint64_list(qint64 nOffset, qint32 nNumberOfRecords, bool bIsBigEndian)
7223 {
7224     QList<quint64> listResult;
7225 
7226     for(int i=0;i<nNumberOfRecords;i++)
7227     {
7228         quint64 nRecord=read_uint64(nOffset+i*sizeof(quint64),bIsBigEndian);
7229 
7230         listResult.append(nRecord);
7231     }
7232 
7233     return listResult;
7234 }
7235 
_isOffsetsCrossed(qint64 nOffset1,qint64 nSize1,qint64 nOffset2,qint64 nSize2)7236 bool XBinary::_isOffsetsCrossed(qint64 nOffset1, qint64 nSize1, qint64 nOffset2, qint64 nSize2)
7237 {
7238     bool bResult=false;
7239 
7240     if(((nOffset2>=nOffset1)&&((nOffset1+nSize1)>nOffset2))||((nOffset1>=nOffset2)&&((nOffset2+nSize2)>nOffset1)))
7241     {
7242         bResult=true;
7243     }
7244 
7245     return bResult;
7246 }
7247 
_isReplaced(qint64 nOffset,qint64 nSize,QList<XBinary::MEMORY_REPLACE> * pListMemoryReplace)7248 bool XBinary::_isReplaced(qint64 nOffset, qint64 nSize, QList<XBinary::MEMORY_REPLACE> *pListMemoryReplace)
7249 {
7250     bool bResult=false;
7251 
7252     int nNumberOfRecords=pListMemoryReplace->count();
7253 
7254     for(int i=0;i<nNumberOfRecords;i++)
7255     {
7256         if(_isOffsetsCrossed(nOffset,nSize,pListMemoryReplace->at(i).nOffset,pListMemoryReplace->at(i).nSize))
7257         {
7258             bResult=true;
7259             break;
7260         }
7261     }
7262 
7263     return bResult;
7264 }
7265 
_replaceMemory(qint64 nDataOffset,char * pData,qint64 nDataSize,QList<XBinary::MEMORY_REPLACE> * pListMemoryReplace)7266 bool XBinary::_replaceMemory(qint64 nDataOffset, char *pData, qint64 nDataSize, QList<XBinary::MEMORY_REPLACE> *pListMemoryReplace)
7267 {
7268     bool bResult=false;
7269 
7270     int nNumberOfRecords=pListMemoryReplace->count();
7271 
7272     for(int i=0;i<nNumberOfRecords;i++)
7273     {
7274         if(_isOffsetsCrossed(nDataOffset,nDataSize,pListMemoryReplace->at(i).nOffset,pListMemoryReplace->at(i).nSize))
7275         {
7276             MEMORY_REPLACE memoryReplace=pListMemoryReplace->at(i);
7277 
7278             for(int j=0;j<memoryReplace.nSize;j++)
7279             {
7280                 bResult=true;
7281 
7282                 pData[(memoryReplace.nOffset+j)-nDataOffset]=memoryReplace.baOriginal.data()[j];
7283 
7284                 if((memoryReplace.nOffset+j)>(nDataOffset+nDataSize))
7285                 {
7286                     break;
7287                 }
7288             }
7289         }
7290     }
7291 
7292     return bResult;
7293 }
7294 
getSymbolRecords(XBinary::_MEMORY_MAP * pMemoryMap,SYMBOL_TYPE symbolType)7295 QList<XBinary::SYMBOL_RECORD> XBinary::getSymbolRecords(XBinary::_MEMORY_MAP *pMemoryMap,SYMBOL_TYPE symbolType)
7296 {
7297     Q_UNUSED(pMemoryMap)
7298     Q_UNUSED(symbolType)
7299 
7300     QList<XBinary::SYMBOL_RECORD> listResult;
7301 
7302     return listResult;
7303 }
7304 
findSymbolByAddress(QList<SYMBOL_RECORD> * pListSymbolRecords,qint64 nAddress)7305 XBinary::SYMBOL_RECORD XBinary::findSymbolByAddress(QList<SYMBOL_RECORD> *pListSymbolRecords, qint64 nAddress)
7306 {
7307     SYMBOL_RECORD result={};
7308 
7309     qint32 nNumberOfRecords=pListSymbolRecords->count();
7310 
7311     for(int i=0;i<nNumberOfRecords;i++)
7312     {
7313         if(pListSymbolRecords->at(i).nAddress==nAddress)
7314         {
7315             result=pListSymbolRecords->at(i);
7316 
7317             break;
7318         }
7319     }
7320 
7321     return result;
7322 }
7323 
findSymbolByName(QList<SYMBOL_RECORD> * pListSymbolRecords,QString sName)7324 XBinary::SYMBOL_RECORD XBinary::findSymbolByName(QList<SYMBOL_RECORD> *pListSymbolRecords, QString sName)
7325 {
7326     SYMBOL_RECORD result={};
7327 
7328     qint32 nNumberOfRecords=pListSymbolRecords->count();
7329 
7330     for(int i=0;i<nNumberOfRecords;i++)
7331     {
7332         if(pListSymbolRecords->at(i).sName==sName)
7333         {
7334             result=pListSymbolRecords->at(i);
7335 
7336             break;
7337         }
7338     }
7339 
7340     return result;
7341 }
7342 
findSymbolByOrdinal(QList<SYMBOL_RECORD> * pListSymbolRecords,qint32 nOrdinal)7343 XBinary::SYMBOL_RECORD XBinary::findSymbolByOrdinal(QList<SYMBOL_RECORD> *pListSymbolRecords, qint32 nOrdinal)
7344 {
7345     SYMBOL_RECORD result={};
7346 
7347     qint32 nNumberOfRecords=pListSymbolRecords->count();
7348 
7349     for(int i=0;i<nNumberOfRecords;i++)
7350     {
7351         if(pListSymbolRecords->at(i).nOrdinal==nOrdinal)
7352         {
7353             result=pListSymbolRecords->at(i);
7354 
7355             break;
7356         }
7357     }
7358 
7359     return result;
7360 }
7361 
generateUUID()7362 QString XBinary::generateUUID()
7363 {
7364     return QUuid::createUuid().toString().remove("{").remove("}");
7365 }
7366 
appendText(QString sResult,QString sString,QString sSeparate)7367 QString XBinary::appendText(QString sResult, QString sString, QString sSeparate)
7368 {
7369     if(sString!="")
7370     {
7371         if(sResult!="") sResult+=sSeparate;
7372         sResult+=sString;
7373     }
7374 
7375     return sResult;
7376 }
7377 
getSignatureRecords(QString sSignature)7378 QList<XBinary::SIGNATURE_RECORD> XBinary::getSignatureRecords(QString sSignature)
7379 {
7380     // TODO Error checks!
7381     QList<SIGNATURE_RECORD> listResult;
7382 
7383     int nSignatureSize=sSignature.size();
7384 
7385     for(int i=0; i<nSignatureSize;)
7386     {
7387         if(sSignature.at(i)==QChar('.'))
7388         {
7389             i+=_getSignatureRelOffsetFix(&listResult,sSignature,i);
7390         }
7391         else if(sSignature.at(i)==QChar('+'))
7392         {
7393             i+=_getSignatureDelta(&listResult,sSignature,i);
7394         }
7395         else if(sSignature.at(i)==QChar('$'))
7396         {
7397             i+=_getSignatureRelOffset(&listResult,sSignature,i);
7398         }
7399         else if(sSignature.at(i)==QChar('#')) // TODO Check []
7400         {
7401             i+=_getSignatureAddress(&listResult,sSignature,i);
7402         }
7403         else
7404         {
7405             int nBytes=_getSignatureBytes(&listResult,sSignature,i);
7406 
7407             if(nBytes)
7408             {
7409                 i+=nBytes;
7410             }
7411             else
7412             {
7413                 break;
7414             }
7415         }
7416     }
7417 
7418     return listResult;
7419 }
7420 
_compareSignature(_MEMORY_MAP * pMemoryMap,QList<XBinary::SIGNATURE_RECORD> * pListSignatureRecords,qint64 nOffset)7421 bool XBinary::_compareSignature(_MEMORY_MAP *pMemoryMap, QList<XBinary::SIGNATURE_RECORD> *pListSignatureRecords, qint64 nOffset)
7422 {
7423     // TODO optimize
7424     int nNumberOfSignatures=pListSignatureRecords->count();
7425 
7426     for(int i=0; i<nNumberOfSignatures; i++)
7427     {
7428         qint64 _nAddress=0;
7429 
7430         switch(pListSignatureRecords->at(i).st)
7431         {
7432             case XBinary::ST_COMPAREBYTES:
7433                 {
7434                     QByteArray baData=read_array(nOffset,pListSignatureRecords->at(i).baData.size());
7435 
7436                     if(baData.size()!=pListSignatureRecords->at(i).baData.size())
7437                     {
7438                         return false;
7439                     }
7440 
7441                     if(!compareMemory(baData.data(),(char *)(pListSignatureRecords->at(i).baData.data()),baData.size()))
7442                     {
7443                         return false;
7444                     }
7445 
7446                     nOffset+=baData.size();
7447                 }
7448                 break;
7449 
7450             case XBinary::ST_FINDBYTES:
7451                 {
7452                     qint64 nResult=find_byteArray(nOffset,pListSignatureRecords->at(i).nFindDelta+pListSignatureRecords->at(i).baData.size(),pListSignatureRecords->at(i).baData);
7453 
7454                     if(nResult==-1)
7455                     {
7456                         return false;
7457                     }
7458 
7459                     nOffset=nResult+pListSignatureRecords->at(i).baData.size();
7460                 }
7461                 break;
7462 
7463             case XBinary::ST_RELOFFSETFIX:
7464                 // TODO Check
7465                 nOffset+=pListSignatureRecords->at(i).nBaseAddress;
7466                 break;
7467 
7468             case XBinary::ST_RELOFFSET:
7469                 _nAddress=offsetToAddress(pMemoryMap,nOffset);
7470 
7471                 switch(pListSignatureRecords->at(i).nSizeOfAddr)
7472                 {
7473                     case 1:
7474                         _nAddress+=1+read_int8(nOffset);
7475                         break;
7476 
7477                     case 2:
7478                         _nAddress+=2+read_int16(nOffset); // TODO mb BE<->LE
7479                         break;
7480 
7481                     case 4:
7482                         _nAddress+=4+read_int32(nOffset); // TODO mb BE<->LE
7483                         break;
7484 
7485                     case 8:
7486                         _nAddress+=8+read_int64(nOffset); // TODO mb BE<->LE
7487                         break;
7488                 }
7489 
7490                 nOffset=addressToOffset(pMemoryMap,_nAddress);
7491 
7492                 break;
7493 
7494             case XBinary::ST_ADDRESS:
7495                 switch(pListSignatureRecords->at(i).nSizeOfAddr)
7496                 {
7497                     case 1:
7498                         _nAddress=read_uint8(nOffset);
7499                         break;
7500 
7501                     case 2:
7502                         _nAddress=read_uint16(nOffset); // TODO mb BE<->LE
7503                         break;
7504 
7505                     case 4:
7506                         _nAddress=read_uint32(nOffset); // TODO mb BE<->LE
7507                         break;
7508 
7509                     case 8:
7510                         _nAddress=read_uint64(nOffset); // TODO mb BE<->LE
7511                         break;
7512                 }
7513 
7514                 // TODO Base address!!!
7515 
7516                 nOffset=addressToOffset(pMemoryMap,_nAddress); // TODO!
7517                 break;
7518         }
7519 
7520         if(!isOffsetValid(pMemoryMap,nOffset))
7521         {
7522             return false;
7523         }
7524     }
7525     //    CompareBytes,
7526     //    RelOffsetFix,
7527     //    RelOffset,
7528     //    Address
7529 
7530     return true;
7531 }
7532 
_getSignatureRelOffsetFix(QList<XBinary::SIGNATURE_RECORD> * pListSignatureRecords,QString sSignature,int nStartIndex)7533 int XBinary::_getSignatureRelOffsetFix(QList<XBinary::SIGNATURE_RECORD> *pListSignatureRecords, QString sSignature, int nStartIndex)
7534 {
7535     int nResult=0;
7536     int nSignatureSize=sSignature.size();
7537 
7538     for(int i=nStartIndex; i<nSignatureSize; i++)
7539     {
7540         if(sSignature.at(i)==QChar('.'))
7541         {
7542             nResult++;
7543         }
7544         else
7545         {
7546             break;
7547         }
7548     }
7549 
7550     if(nResult)
7551     {
7552         SIGNATURE_RECORD record={};
7553 
7554         record.st=XBinary::ST_RELOFFSETFIX;
7555         record.nSizeOfAddr=0;
7556         record.nBaseAddress=nResult/2;
7557 
7558         pListSignatureRecords->append(record);
7559     }
7560 
7561     return nResult;
7562 }
7563 
_getSignatureDelta(QList<XBinary::SIGNATURE_RECORD> * pListSignatureRecords,QString sSignature,int nStartIndex)7564 int XBinary::_getSignatureDelta(QList<XBinary::SIGNATURE_RECORD> *pListSignatureRecords, QString sSignature, int nStartIndex)
7565 {
7566     // TODO Check!!!
7567     int nResult=0;
7568     int nSignatureSize=sSignature.size();
7569 
7570     for(int i=nStartIndex; i<nSignatureSize; i++)
7571     {
7572         if(sSignature.at(i)==QChar('+'))
7573         {
7574             nResult++;
7575         }
7576         else
7577         {
7578             break;
7579         }
7580     }
7581 
7582     if(nResult)
7583     {
7584         QList<XBinary::SIGNATURE_RECORD> _listSignatureRecords;
7585         qint32 nTemp=_getSignatureBytes(&_listSignatureRecords,sSignature,nStartIndex+nResult);
7586 
7587         if(_listSignatureRecords.count())
7588         {
7589             SIGNATURE_RECORD record={};
7590 
7591             record.st=XBinary::ST_FINDBYTES;
7592             record.nSizeOfAddr=0;
7593             record.nBaseAddress=0;
7594             record.baData=_listSignatureRecords.at(0).baData;
7595             record.nFindDelta=32*nResult;
7596 
7597             pListSignatureRecords->append(record);
7598 
7599             nResult+=nTemp;
7600         }
7601     }
7602 
7603     return nResult;
7604 }
7605 
_getSignatureRelOffset(QList<XBinary::SIGNATURE_RECORD> * pListSignatureRecords,QString sSignature,int nStartIndex)7606 int XBinary::_getSignatureRelOffset(QList<XBinary::SIGNATURE_RECORD> *pListSignatureRecords, QString sSignature, int nStartIndex)
7607 {
7608     int nResult=0;
7609 
7610     int nSignatureSize=sSignature.size();
7611 
7612     for(int i=nStartIndex; i<nSignatureSize; i++)
7613     {
7614         if(sSignature.at(i)==QChar('$'))
7615         {
7616             nResult++;
7617         }
7618         else
7619         {
7620             break;
7621         }
7622     }
7623 
7624     if(nResult)
7625     {
7626         SIGNATURE_RECORD record={};
7627 
7628         record.st=XBinary::ST_RELOFFSET;
7629         record.nSizeOfAddr=nResult/2;
7630         record.nBaseAddress=0;
7631 
7632         pListSignatureRecords->append(record);
7633     }
7634 
7635     return nResult;
7636 }
7637 
_getSignatureAddress(QList<XBinary::SIGNATURE_RECORD> * pListSignatureRecords,QString sSignature,int nStartIndex)7638 int XBinary::_getSignatureAddress(QList<XBinary::SIGNATURE_RECORD> *pListSignatureRecords, QString sSignature, int nStartIndex)
7639 {
7640     int nResult=0;
7641 
7642     int nSignatureSize=sSignature.size();
7643     QString sBaseAddress;
7644     bool bIsBaseAddress=false;
7645     int nSizeOfAddress=0;
7646 
7647     for(int i=nStartIndex; i<nSignatureSize; i++)
7648     {
7649         if(sSignature.at(i)==QChar('#'))
7650         {
7651             nResult++;
7652             nSizeOfAddress++;
7653         }
7654         else if(sSignature.at(i)==QChar('['))
7655         {
7656             nResult++;
7657             bIsBaseAddress=true;
7658         }
7659         else if(sSignature.at(i)==QChar(']'))
7660         {
7661             nResult++;
7662             bIsBaseAddress=false;
7663         }
7664         else if(bIsBaseAddress)
7665         {
7666             nResult++;
7667             sBaseAddress.append(sSignature.at(i));
7668         }
7669         else
7670         {
7671             break;
7672         }
7673     }
7674 
7675     if(nResult)
7676     {
7677         SIGNATURE_RECORD record={};
7678 
7679         record.st=XBinary::ST_ADDRESS;
7680         record.nSizeOfAddr=nSizeOfAddress/2;
7681         record.nBaseAddress=sBaseAddress.toInt(0,16);
7682 
7683         pListSignatureRecords->append(record);
7684     }
7685 
7686     return nResult;
7687 }
7688 
_getSignatureBytes(QList<XBinary::SIGNATURE_RECORD> * pListSignatureRecords,QString sSignature,int nStartIndex)7689 int XBinary::_getSignatureBytes(QList<XBinary::SIGNATURE_RECORD> *pListSignatureRecords, QString sSignature, int nStartIndex)
7690 {
7691     int nResult=0;
7692 
7693     int nSignatureSize=sSignature.size();
7694     QString sBytes;
7695 
7696     for(int i=nStartIndex; i<nSignatureSize; i++)
7697     {
7698         if( ((sSignature.at(i)>=QChar('a'))&&(sSignature.at(i)<=QChar('f'))) ||
7699             (((sSignature.at(i)>=QChar('0'))&&(sSignature.at(i)<=QChar('9')))))
7700         {
7701             nResult++;
7702             sBytes.append(sSignature.at(i));
7703         }
7704         else
7705         {
7706             // TODO: invalid symbols
7707             // Check
7708             break;
7709         }
7710     }
7711 
7712     if(nResult)
7713     {
7714         SIGNATURE_RECORD record={};
7715 
7716         record.st=XBinary::ST_COMPAREBYTES;
7717         record.nSizeOfAddr=0;
7718         record.nBaseAddress=0;
7719         record.baData=QByteArray::fromHex(sBytes.toUtf8()); // TODO Check
7720 
7721         pListSignatureRecords->append(record);
7722     }
7723 
7724     return nResult;
7725 }
7726 
_searchProgressMinimumChanged(qint32 nMaximum)7727 void XBinary::_searchProgressMinimumChanged(qint32 nMaximum)
7728 {
7729     if(!g_bIsProcessSignalsDisable)
7730     {
7731         emit searchProgressMinimumChanged(nMaximum);
7732     }
7733 }
7734 
_searchProgressMaximumChanged(qint32 nMaximum)7735 void XBinary::_searchProgressMaximumChanged(qint32 nMaximum)
7736 {
7737     if(!g_bIsProcessSignalsDisable)
7738     {
7739         emit searchProgressMinimumChanged(nMaximum);
7740     }
7741 }
7742 
_searchProgressValueChanged(qint32 nValue)7743 void XBinary::_searchProgressValueChanged(qint32 nValue)
7744 {
7745     if(!g_bIsProcessSignalsDisable)
7746     {
7747         emit searchProgressValueChanged(nValue);
7748     }
7749 }
7750 
_dumpProgressMinimumChanged(qint32 nMaximum)7751 void XBinary::_dumpProgressMinimumChanged(qint32 nMaximum)
7752 {
7753     if(!g_bIsProcessSignalsDisable)
7754     {
7755         emit dumpProgressMinimumChanged(nMaximum);
7756     }
7757 }
7758 
_dumpProgressMaximumChanged(qint32 nMaximum)7759 void XBinary::_dumpProgressMaximumChanged(qint32 nMaximum)
7760 {
7761     if(!g_bIsProcessSignalsDisable)
7762     {
7763         emit dumpProgressMaximumChanged(nMaximum);
7764     }
7765 }
7766 
_dumpProgressValueChanged(qint32 nValue)7767 void XBinary::_dumpProgressValueChanged(qint32 nValue)
7768 {
7769     if(!g_bIsProcessSignalsDisable)
7770     {
7771         emit dumpProgressValueChanged(nValue);
7772     }
7773 }
7774 
_entropyProgressMinimumChanged(qint32 nMaximum)7775 void XBinary::_entropyProgressMinimumChanged(qint32 nMaximum)
7776 {
7777     if(!g_bIsProcessSignalsDisable)
7778     {
7779         emit entropyProgressMinimumChanged(nMaximum);
7780     }
7781 }
7782 
_entropyProgressMaximumChanged(qint32 nMaximum)7783 void XBinary::_entropyProgressMaximumChanged(qint32 nMaximum)
7784 {
7785     if(!g_bIsProcessSignalsDisable)
7786     {
7787         emit entropyProgressMaximumChanged(nMaximum);
7788     }
7789 }
7790 
_entropyProgressValueChanged(qint32 nValue)7791 void XBinary::_entropyProgressValueChanged(qint32 nValue)
7792 {
7793     if(!g_bIsProcessSignalsDisable)
7794     {
7795         emit entropyProgressValueChanged(nValue);
7796     }
7797 }
7798 
_hashProgressMinimumChanged(qint32 nMaximum)7799 void XBinary::_hashProgressMinimumChanged(qint32 nMaximum)
7800 {
7801     if(!g_bIsProcessSignalsDisable)
7802     {
7803         emit hashProgressMinimumChanged(nMaximum);
7804     }
7805 }
7806 
_hashProgressMaximumChanged(qint32 nMaximum)7807 void XBinary::_hashProgressMaximumChanged(qint32 nMaximum)
7808 {
7809     if(!g_bIsProcessSignalsDisable)
7810     {
7811         emit hashProgressMaximumChanged(nMaximum);
7812     }
7813 }
7814 
_hashProgressValueChanged(qint32 nValue)7815 void XBinary::_hashProgressValueChanged(qint32 nValue)
7816 {
7817     if(!g_bIsProcessSignalsDisable)
7818     {
7819         emit hashProgressValueChanged(nValue);
7820     }
7821 }
7822 
getPhysSize(char * pBuffer,qint64 nSize)7823 qint64 XBinary::getPhysSize(char *pBuffer, qint64 nSize)
7824 {
7825     while(nSize>0)
7826     {
7827         char *pOffset=pBuffer+nSize-1;
7828 
7829         if(*pOffset)
7830         {
7831             break;
7832         }
7833 
7834         nSize--;
7835     }
7836 
7837     return nSize;
7838 }
7839 
isEmptyData(char * pBuffer,qint64 nSize)7840 bool XBinary::isEmptyData(char *pBuffer, qint64 nSize) // TODO dwords
7841 {
7842     bool bResult=true;
7843 
7844     for(qint64 i=0; i<nSize; i++)
7845     {
7846         char *pOffset=(pBuffer+i);
7847 
7848         if(*pOffset)
7849         {
7850             bResult=false;
7851             break;
7852         }
7853     }
7854 
7855     return bResult;
7856 }
7857 
_isOffsetValid(qint64 nOffset)7858 bool XBinary::_isOffsetValid(qint64 nOffset)
7859 {
7860     qint64 nFileSize=getSize();
7861 
7862     return (nOffset<nFileSize);
7863 }
7864 
isAddressPhysical(qint64 nAddress)7865 bool XBinary::isAddressPhysical(qint64 nAddress)
7866 {
7867     _MEMORY_MAP memoryMap=getMemoryMap();
7868 
7869     return isAddressPhysical(&memoryMap,nAddress);
7870 }
7871