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