1 // copyright (c) 2019-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 "xdex.h"
22 
XDEX(QIODevice * pDevice)23 XDEX::XDEX(QIODevice *pDevice): XBinary(pDevice)
24 {
25 
26 }
27 
getMode(QIODevice * pDevice)28 XBinary::MODE XDEX::getMode(QIODevice *pDevice)
29 {
30     XDEX xdex(pDevice);
31 
32     return xdex.getMode();
33 }
34 
isValid()35 bool XDEX::isValid()
36 {
37     bool bIsValid=false;
38 
39     bIsValid=compareSignature("'dex\n'......00");
40 
41     return bIsValid;
42 }
43 
_getVersion()44 quint32 XDEX::_getVersion()
45 {
46     quint32 nVersion=0;
47 
48     QString sVersion=read_ansiString(4);
49 
50     nVersion=sVersion.toUInt();
51 
52     return nVersion;
53 }
54 
getVersion()55 QString XDEX::getVersion()
56 {
57     return read_ansiString(4);
58 }
59 
isBigEndian()60 bool XDEX::isBigEndian()
61 {
62     quint32 nEndian=read_uint32(offsetof(XDEX_DEF::HEADER,endian_tag));
63 
64     return (nEndian!=0x12345678);
65 
66     //    return false; // TODO Check. There are dex files with nEndian!=0x12345678, but LE
67 }
68 
getMode()69 XBinary::MODE XDEX::getMode()
70 {
71     return MODE_32;
72 }
73 
getArch()74 QString XDEX::getArch()
75 {
76     return "Dalvik";
77 }
78 
getFileType()79 XBinary::FT XDEX::getFileType()
80 {
81     return FT_DEX;
82 }
83 
getType()84 int XDEX::getType()
85 {
86     return TYPE_UNKNOWN;
87 }
88 
typeIdToString(int nType)89 QString XDEX::typeIdToString(int nType)
90 {
91     QString sResult="Unknown"; // mb TODO translate
92 
93     switch(nType)
94     {
95         case TYPE_UNKNOWN:      sResult=QString("Unknown");     break; // mb TODO translate
96     }
97 
98     return sResult;
99 }
100 
getMemoryMap()101 XBinary::_MEMORY_MAP XDEX::getMemoryMap()
102 {
103     _MEMORY_MAP result={};
104 
105     qint64 nTotalSize=getSize();
106 
107     result.nModuleAddress=getModuleAddress();
108     result.nRawSize=nTotalSize;
109     result.nImageSize=nTotalSize;
110     result.fileType=FT_DEX;
111     result.mode=getMode();
112     result.sArch=getArch();
113     result.bIsBigEndian=isBigEndian();
114     result.sType=getTypeAsString();
115 
116     qint32 nIndex=0;
117 
118     XDEX_DEF::HEADER header=getHeader();
119 
120     _MEMORY_RECORD recordHeader={};
121     recordHeader.nAddress=-1;
122     recordHeader.segment=ADDRESS_SEGMENT_FLAT;
123     recordHeader.nOffset=0;
124     recordHeader.nSize=header.header_size;
125     recordHeader.nIndex=nIndex++;
126     recordHeader.type=MMT_HEADER;
127     recordHeader.sName=tr("Header");
128 
129     result.listRecords.append(recordHeader);
130 
131     if(header.link_size)
132     {
133         _MEMORY_RECORD record={};
134         record.nAddress=-1;
135         record.segment=ADDRESS_SEGMENT_FLAT;
136         record.nOffset=header.link_off;
137         record.nSize=header.link_size;
138         record.nIndex=nIndex++;
139         record.type=MMT_FILESEGMENT;
140         record.sName="link";
141 
142         result.listRecords.append(record);
143     }
144 
145     if(header.string_ids_size)
146     {
147         _MEMORY_RECORD record={};
148         record.nAddress=-1;
149         record.segment=ADDRESS_SEGMENT_FLAT;
150         record.nOffset=header.string_ids_off;
151         record.nSize=(header.string_ids_size)*sizeof(XDEX_DEF::STRING_ITEM_ID);
152         record.nIndex=nIndex++;
153         record.type=MMT_FILESEGMENT;
154         record.sName="string_ids";
155 
156         result.listRecords.append(record);
157     }
158 
159     if(header.type_ids_size)
160     {
161         _MEMORY_RECORD record={};
162         record.nAddress=-1;
163         record.segment=ADDRESS_SEGMENT_FLAT;
164         record.nOffset=header.type_ids_off;
165         record.nSize=(header.type_ids_size)*sizeof(XDEX_DEF::TYPE_ITEM_ID);
166         record.nIndex=nIndex++;
167         record.type=MMT_FILESEGMENT;
168         record.sName="type_ids";
169 
170         result.listRecords.append(record);
171     }
172 
173     if(header.proto_ids_size)
174     {
175         _MEMORY_RECORD record={};
176         record.nAddress=-1;
177         record.segment=ADDRESS_SEGMENT_FLAT;
178         record.nOffset=header.proto_ids_off;
179         record.nSize=(header.proto_ids_size)*sizeof(XDEX_DEF::PROTO_ITEM_ID);
180         record.nIndex=nIndex++;
181         record.type=MMT_FILESEGMENT;
182         record.sName="proto_ids";
183 
184         result.listRecords.append(record);
185     }
186 
187     if(header.field_ids_size)
188     {
189         _MEMORY_RECORD record={};
190         record.nAddress=-1;
191         record.segment=ADDRESS_SEGMENT_FLAT;
192         record.nOffset=header.field_ids_off;
193         record.nSize=(header.field_ids_size)*sizeof(XDEX_DEF::FIELD_ITEM_ID);
194         record.nIndex=nIndex++;
195         record.type=MMT_FILESEGMENT;
196         record.sName="field_ids";
197 
198         result.listRecords.append(record);
199     }
200 
201     if(header.method_ids_size)
202     {
203         _MEMORY_RECORD record={};
204         record.nAddress=-1;
205         record.segment=ADDRESS_SEGMENT_FLAT;
206         record.nOffset=header.method_ids_off;
207         record.nSize=(header.method_ids_size)*sizeof(XDEX_DEF::METHOD_ITEM_ID);
208         record.nIndex=nIndex++;
209         record.type=MMT_FILESEGMENT;
210         record.sName="method_ids";
211 
212         result.listRecords.append(record);
213     }
214 
215     if(header.class_defs_size)
216     {
217         _MEMORY_RECORD record={};
218         record.nAddress=-1;
219         record.segment=ADDRESS_SEGMENT_FLAT;
220         record.nOffset=header.class_defs_off;
221         record.nSize=(header.class_defs_size)*sizeof(XDEX_DEF::CLASS_ITEM_DEF);
222         record.nIndex=nIndex++;
223         record.type=MMT_FILESEGMENT;
224         record.sName="class_defs";
225 
226         result.listRecords.append(record);
227     }
228 
229     if(header.data_size)
230     {
231         _MEMORY_RECORD record={};
232         record.nAddress=-1;
233         record.segment=ADDRESS_SEGMENT_FLAT;
234         record.nOffset=header.data_off;
235         record.nSize=header.data_size;
236         record.nIndex=nIndex++;
237         record.type=MMT_FILESEGMENT;
238         record.sName="data";
239 
240         result.listRecords.append(record);
241     }
242 
243     if((header.data_off+header.data_size)<header.file_size)
244     {
245         _MEMORY_RECORD recordOverlay={};
246         recordOverlay.nAddress=-1;
247         recordOverlay.segment=ADDRESS_SEGMENT_FLAT;
248         recordOverlay.nOffset=(header.data_off+header.data_size);
249         recordOverlay.nSize=nTotalSize-(header.data_off+header.data_size);
250         recordOverlay.nIndex=nIndex++;
251         recordOverlay.type=MMT_OVERLAY;
252         recordOverlay.sName=tr("Overlay");
253 
254         result.listRecords.append(recordOverlay);
255     }
256 
257     return result;
258 }
259 
getHeader_magic()260 quint32 XDEX::getHeader_magic()
261 {
262     return read_uint32(offsetof(XDEX_DEF::HEADER,magic),false);
263 }
264 
getHeader_version()265 quint32 XDEX::getHeader_version()
266 {
267     return read_uint32(offsetof(XDEX_DEF::HEADER,version),false);
268 }
269 
getHeader_checksum()270 quint32 XDEX::getHeader_checksum()
271 {
272     return read_uint32(offsetof(XDEX_DEF::HEADER,checksum),isBigEndian());
273 }
274 
getHeader_signature()275 QByteArray XDEX::getHeader_signature()
276 {
277     return read_array(offsetof(XDEX_DEF::HEADER,signature),20);
278 }
279 
getHeader_file_size()280 quint32 XDEX::getHeader_file_size()
281 {
282     return read_uint32(offsetof(XDEX_DEF::HEADER,file_size),isBigEndian());
283 }
284 
getHeader_header_size()285 quint32 XDEX::getHeader_header_size()
286 {
287     return read_uint32(offsetof(XDEX_DEF::HEADER,header_size),isBigEndian());
288 }
289 
getHeader_endian_tag()290 quint32 XDEX::getHeader_endian_tag()
291 {
292     return read_uint32(offsetof(XDEX_DEF::HEADER,endian_tag));
293 }
294 
getHeader_link_size()295 quint32 XDEX::getHeader_link_size()
296 {
297     return read_uint32(offsetof(XDEX_DEF::HEADER,link_size),isBigEndian());
298 }
299 
getHeader_link_off()300 quint32 XDEX::getHeader_link_off()
301 {
302     return read_uint32(offsetof(XDEX_DEF::HEADER,link_off),isBigEndian());
303 }
304 
getHeader_map_off()305 quint32 XDEX::getHeader_map_off()
306 {
307     return read_uint32(offsetof(XDEX_DEF::HEADER,map_off),isBigEndian());
308 }
309 
getHeader_string_ids_size()310 quint32 XDEX::getHeader_string_ids_size()
311 {
312     return read_uint32(offsetof(XDEX_DEF::HEADER,string_ids_size),isBigEndian());
313 }
314 
getHeader_string_ids_off()315 quint32 XDEX::getHeader_string_ids_off()
316 {
317     return read_uint32(offsetof(XDEX_DEF::HEADER,string_ids_off),isBigEndian());
318 }
319 
getHeader_type_ids_size()320 quint32 XDEX::getHeader_type_ids_size()
321 {
322     return read_uint32(offsetof(XDEX_DEF::HEADER,type_ids_size),isBigEndian());
323 }
324 
getHeader_type_ids_off()325 quint32 XDEX::getHeader_type_ids_off()
326 {
327     return read_uint32(offsetof(XDEX_DEF::HEADER,type_ids_off),isBigEndian());
328 }
329 
getHeader_proto_ids_size()330 quint32 XDEX::getHeader_proto_ids_size()
331 {
332     return read_uint32(offsetof(XDEX_DEF::HEADER,proto_ids_size),isBigEndian());
333 }
334 
getHeader_proto_ids_off()335 quint32 XDEX::getHeader_proto_ids_off()
336 {
337     return read_uint32(offsetof(XDEX_DEF::HEADER,proto_ids_off),isBigEndian());
338 }
339 
getHeader_field_ids_size()340 quint32 XDEX::getHeader_field_ids_size()
341 {
342     return read_uint32(offsetof(XDEX_DEF::HEADER,field_ids_size),isBigEndian());
343 }
344 
getHeader_field_ids_off()345 quint32 XDEX::getHeader_field_ids_off()
346 {
347     return read_uint32(offsetof(XDEX_DEF::HEADER,field_ids_off),isBigEndian());
348 }
349 
getHeader_method_ids_size()350 quint32 XDEX::getHeader_method_ids_size()
351 {
352     return read_uint32(offsetof(XDEX_DEF::HEADER,method_ids_size),isBigEndian());
353 }
354 
getHeader_method_ids_off()355 quint32 XDEX::getHeader_method_ids_off()
356 {
357     return read_uint32(offsetof(XDEX_DEF::HEADER,method_ids_off),isBigEndian());
358 }
359 
getHeader_class_defs_size()360 quint32 XDEX::getHeader_class_defs_size()
361 {
362     return read_uint32(offsetof(XDEX_DEF::HEADER,class_defs_size),isBigEndian());
363 }
364 
getHeader_class_defs_off()365 quint32 XDEX::getHeader_class_defs_off()
366 {
367     return read_uint32(offsetof(XDEX_DEF::HEADER,class_defs_off),isBigEndian());
368 }
369 
getHeader_data_size()370 quint32 XDEX::getHeader_data_size()
371 {
372     return read_uint32(offsetof(XDEX_DEF::HEADER,data_size),isBigEndian());
373 }
374 
getHeader_data_off()375 quint32 XDEX::getHeader_data_off()
376 {
377     return read_uint32(offsetof(XDEX_DEF::HEADER,data_off),isBigEndian());
378 }
379 
setHeader_magic(quint32 value)380 void XDEX::setHeader_magic(quint32 value)
381 {
382     write_uint32(offsetof(XDEX_DEF::HEADER,magic),value,false);
383 }
384 
setHeader_version(quint32 value)385 void XDEX::setHeader_version(quint32 value)
386 {
387     write_uint32(offsetof(XDEX_DEF::HEADER,version),value,false);
388 }
389 
setHeader_checksum(quint32 value)390 void XDEX::setHeader_checksum(quint32 value)
391 {
392     write_uint32(offsetof(XDEX_DEF::HEADER,checksum),value,isBigEndian());
393 }
394 
setHeader_file_size(quint32 value)395 void XDEX::setHeader_file_size(quint32 value)
396 {
397     write_uint32(offsetof(XDEX_DEF::HEADER,file_size),value,isBigEndian());
398 }
399 
setHeader_header_size(quint32 value)400 void XDEX::setHeader_header_size(quint32 value)
401 {
402     write_uint32(offsetof(XDEX_DEF::HEADER,header_size),value,isBigEndian());
403 }
404 
setHeader_endian_tag(quint32 value)405 void XDEX::setHeader_endian_tag(quint32 value)
406 {
407     write_uint32(offsetof(XDEX_DEF::HEADER,endian_tag),value);
408 }
409 
setHeader_link_size(quint32 value)410 void XDEX::setHeader_link_size(quint32 value)
411 {
412     write_uint32(offsetof(XDEX_DEF::HEADER,link_size),value,isBigEndian());
413 }
414 
setHeader_link_off(quint32 value)415 void XDEX::setHeader_link_off(quint32 value)
416 {
417     write_uint32(offsetof(XDEX_DEF::HEADER,link_off),value,isBigEndian());
418 }
419 
setHeader_map_off(quint32 value)420 void XDEX::setHeader_map_off(quint32 value)
421 {
422     write_uint32(offsetof(XDEX_DEF::HEADER,map_off),value,isBigEndian());
423 }
424 
setHeader_string_ids_size(quint32 value)425 void XDEX::setHeader_string_ids_size(quint32 value)
426 {
427     write_uint32(offsetof(XDEX_DEF::HEADER,string_ids_size),value,isBigEndian());
428 }
429 
setHeader_string_ids_off(quint32 value)430 void XDEX::setHeader_string_ids_off(quint32 value)
431 {
432     write_uint32(offsetof(XDEX_DEF::HEADER,string_ids_off),value,isBigEndian());
433 }
434 
setHeader_type_ids_size(quint32 value)435 void XDEX::setHeader_type_ids_size(quint32 value)
436 {
437     write_uint32(offsetof(XDEX_DEF::HEADER,type_ids_size),value,isBigEndian());
438 }
439 
setHeader_type_ids_off(quint32 value)440 void XDEX::setHeader_type_ids_off(quint32 value)
441 {
442     write_uint32(offsetof(XDEX_DEF::HEADER,type_ids_off),value,isBigEndian());
443 }
444 
setHeader_proto_ids_size(quint32 value)445 void XDEX::setHeader_proto_ids_size(quint32 value)
446 {
447     write_uint32(offsetof(XDEX_DEF::HEADER,proto_ids_size),value,isBigEndian());
448 }
449 
setHeader_proto_ids_off(quint32 value)450 void XDEX::setHeader_proto_ids_off(quint32 value)
451 {
452     write_uint32(offsetof(XDEX_DEF::HEADER,proto_ids_off),value,isBigEndian());
453 }
454 
setHeader_field_ids_size(quint32 value)455 void XDEX::setHeader_field_ids_size(quint32 value)
456 {
457     write_uint32(offsetof(XDEX_DEF::HEADER,field_ids_size),value,isBigEndian());
458 }
459 
setHeader_field_ids_off(quint32 value)460 void XDEX::setHeader_field_ids_off(quint32 value)
461 {
462     write_uint32(offsetof(XDEX_DEF::HEADER,field_ids_off),value,isBigEndian());
463 }
464 
setHeader_method_ids_size(quint32 value)465 void XDEX::setHeader_method_ids_size(quint32 value)
466 {
467     write_uint32(offsetof(XDEX_DEF::HEADER,method_ids_size),value,isBigEndian());
468 }
469 
setHeader_method_ids_off(quint32 value)470 void XDEX::setHeader_method_ids_off(quint32 value)
471 {
472     write_uint32(offsetof(XDEX_DEF::HEADER,method_ids_off),value,isBigEndian());
473 }
474 
setHeader_class_defs_size(quint32 value)475 void XDEX::setHeader_class_defs_size(quint32 value)
476 {
477     write_uint32(offsetof(XDEX_DEF::HEADER,class_defs_size),value,isBigEndian());
478 }
479 
setHeader_class_defs_off(quint32 value)480 void XDEX::setHeader_class_defs_off(quint32 value)
481 {
482     write_uint32(offsetof(XDEX_DEF::HEADER,class_defs_off),value,isBigEndian());
483 }
484 
setHeader_data_size(quint32 value)485 void XDEX::setHeader_data_size(quint32 value)
486 {
487     write_uint32(offsetof(XDEX_DEF::HEADER,data_size),value,isBigEndian());
488 }
489 
setHeader_data_off(quint32 value)490 void XDEX::setHeader_data_off(quint32 value)
491 {
492     write_uint32(offsetof(XDEX_DEF::HEADER,data_off),value,isBigEndian());
493 }
494 
getHeader()495 XDEX_DEF::HEADER XDEX::getHeader()
496 {
497     XDEX_DEF::HEADER result={};
498 
499     bool bIsBigEndian=isBigEndian();
500 
501     result.magic=read_uint32(offsetof(XDEX_DEF::HEADER,magic),false);
502     result.version=read_uint32(offsetof(XDEX_DEF::HEADER,version),false);
503     result.checksum=read_uint32(offsetof(XDEX_DEF::HEADER,checksum),bIsBigEndian);
504 //    result.signature=getHeader_signature();
505     result.file_size=read_uint32(offsetof(XDEX_DEF::HEADER,file_size),bIsBigEndian);
506     result.header_size=read_uint32(offsetof(XDEX_DEF::HEADER,header_size),bIsBigEndian);
507     result.endian_tag=read_uint32(offsetof(XDEX_DEF::HEADER,endian_tag),false);
508     result.link_size=read_uint32(offsetof(XDEX_DEF::HEADER,link_size),bIsBigEndian);
509     result.link_off=read_uint32(offsetof(XDEX_DEF::HEADER,link_off),bIsBigEndian);
510     result.map_off=read_uint32(offsetof(XDEX_DEF::HEADER,map_off),bIsBigEndian);
511     result.string_ids_size=read_uint32(offsetof(XDEX_DEF::HEADER,string_ids_size),bIsBigEndian);
512     result.string_ids_off=read_uint32(offsetof(XDEX_DEF::HEADER,string_ids_off),bIsBigEndian);
513     result.type_ids_size=read_uint32(offsetof(XDEX_DEF::HEADER,type_ids_size),bIsBigEndian);
514     result.type_ids_off=read_uint32(offsetof(XDEX_DEF::HEADER,type_ids_off),bIsBigEndian);
515     result.proto_ids_size=read_uint32(offsetof(XDEX_DEF::HEADER,proto_ids_size),bIsBigEndian);
516     result.proto_ids_off=read_uint32(offsetof(XDEX_DEF::HEADER,proto_ids_off),bIsBigEndian);
517     result.field_ids_size=read_uint32(offsetof(XDEX_DEF::HEADER,field_ids_size),bIsBigEndian);
518     result.field_ids_off=read_uint32(offsetof(XDEX_DEF::HEADER,field_ids_off),bIsBigEndian);
519     result.method_ids_size=read_uint32(offsetof(XDEX_DEF::HEADER,method_ids_size),bIsBigEndian);
520     result.method_ids_off=read_uint32(offsetof(XDEX_DEF::HEADER,method_ids_off),bIsBigEndian);
521     result.class_defs_size=read_uint32(offsetof(XDEX_DEF::HEADER,class_defs_size),bIsBigEndian);
522     result.class_defs_off=read_uint32(offsetof(XDEX_DEF::HEADER,class_defs_off),bIsBigEndian);
523     result.data_size=read_uint32(offsetof(XDEX_DEF::HEADER,data_size),bIsBigEndian);
524     result.data_off=read_uint32(offsetof(XDEX_DEF::HEADER,data_off),bIsBigEndian);
525 
526     return result;
527 }
528 
getHeaderSize()529 quint32 XDEX::getHeaderSize()
530 {
531     return sizeof(XDEX_DEF::HEADER);
532 }
533 
getMapItems()534 QList<XDEX_DEF::MAP_ITEM> XDEX::getMapItems()
535 {
536     QList<XDEX_DEF::MAP_ITEM> listResult;
537 
538     qint64 nOffset=getHeader_map_off();
539 
540     bool bIsBigEndian=isBigEndian();
541 
542     quint32 nCount=read_uint32(nOffset,bIsBigEndian);
543 
544     nOffset+=4;
545 
546     if(nCount<0x100)
547     {
548         for(quint32 i=0;i<nCount;i++)
549         {
550             XDEX_DEF::MAP_ITEM map_item={};
551 
552             map_item.nType=read_uint16(nOffset,bIsBigEndian);
553             map_item.nCount=read_uint32(nOffset+4,bIsBigEndian);
554             map_item.nOffset=read_uint32(nOffset+8,bIsBigEndian);
555 
556             listResult.append(map_item);
557 
558             nOffset+=12;
559         }
560     }
561 
562     return listResult;
563 }
564 
compareMapItems(QList<XDEX_DEF::MAP_ITEM> * pListMaps,QList<quint16> * pListIDs)565 bool XDEX::compareMapItems(QList<XDEX_DEF::MAP_ITEM> *pListMaps, QList<quint16> *pListIDs)
566 {
567     bool bResult=false;
568 
569     int nNumberOfMapItems=pListMaps->count();
570     int nNumberOfIDs=pListIDs->count();
571 
572     int nCurrentMapItem=0;
573     int nCurrentID=0;
574 
575     while((nCurrentMapItem<nNumberOfMapItems)&&(nCurrentID<nNumberOfIDs))
576     {
577         bResult=false;
578 
579         if(pListMaps->at(nCurrentMapItem).nType==pListIDs->at(nCurrentID))
580         {
581             bResult=true;
582             nCurrentMapItem++;
583             nCurrentID++;
584         }
585         else
586         {
587             nCurrentID++;
588         }
589     }
590 
591     bResult=(bResult)&&(nCurrentMapItem==qMin(nNumberOfMapItems,nNumberOfIDs));
592 
593     return bResult;
594 }
595 
getMapItemsHash()596 quint64 XDEX::getMapItemsHash()
597 {
598     quint64 nResult=0;
599 
600     QList<XDEX_DEF::MAP_ITEM> listMapItems=getMapItems();
601 
602     int nNumberOfMapItems=listMapItems.count();
603 
604     for(int i=0;i<nNumberOfMapItems;i++)
605     {
606         nResult+=(quint64)i*getStringCustomCRC32(QString::number(listMapItems.at(i).nType));
607     }
608 
609     return nResult;
610 }
611 
isMapItemPresent(quint16 nType,QList<XDEX_DEF::MAP_ITEM> * pMapItems)612 bool XDEX::isMapItemPresent(quint16 nType,QList<XDEX_DEF::MAP_ITEM> *pMapItems)
613 {
614     bool bResult=false;
615 
616     int nNumberOfItems=pMapItems->count();
617 
618     for(int i=0;i<nNumberOfItems;i++)
619     {
620         if(pMapItems->at(i).nType==nType)
621         {
622             bResult=true;
623 
624             break;
625         }
626     }
627 
628     return bResult;
629 }
630 
getTypes()631 QMap<quint64, QString> XDEX::getTypes()
632 {
633     QMap<quint64, QString> mapResult;
634 
635     mapResult.insert(0x0000,"TYPE_HEADER_ITEM");
636     mapResult.insert(0x0001,"TYPE_STRING_ID_ITEM");
637     mapResult.insert(0x0002,"TYPE_TYPE_ID_ITEM");
638     mapResult.insert(0x0003,"TYPE_PROTO_ID_ITEM");
639     mapResult.insert(0x0004,"TYPE_FIELD_ID_ITEM");
640     mapResult.insert(0x0005,"TYPE_METHOD_ID_ITEM");
641     mapResult.insert(0x0006,"TYPE_CLASS_DEF_ITEM");
642     mapResult.insert(0x0007,"TYPE_CALL_SITE_ID_ITEM");
643     mapResult.insert(0x0008,"TYPE_METHOD_HANDLE_ITEM");
644     mapResult.insert(0x1000,"TYPE_MAP_LIST");
645     mapResult.insert(0x1001,"TYPE_TYPE_LIST");
646     mapResult.insert(0x1002,"TYPE_ANNOTATION_SET_REF_LIST");
647     mapResult.insert(0x1003,"TYPE_ANNOTATION_SET_ITEM");
648     mapResult.insert(0x2000,"TYPE_CLASS_DATA_ITEM");
649     mapResult.insert(0x2001,"TYPE_CODE_ITEM");
650     mapResult.insert(0x2002,"TYPE_STRING_DATA_ITEM");
651     mapResult.insert(0x2003,"TYPE_DEBUG_INFO_ITEM");
652     mapResult.insert(0x2004,"TYPE_ANNOTATION_ITEM");
653     mapResult.insert(0x2005,"TYPE_ENCODED_ARRAY_ITEM");
654     mapResult.insert(0x2006,"TYPE_ANNOTATIONS_DIRECTORY_ITEM");
655     mapResult.insert(0xF000,"TYPE_HIDDENAPI_CLASS_DATA_ITEM");
656 
657     return mapResult;
658 }
659 
getTypesS()660 QMap<quint64, QString> XDEX::getTypesS()
661 {
662     QMap<quint64, QString> mapResult;
663 
664     mapResult.insert(0x0000,"HEADER_ITEM");
665     mapResult.insert(0x0001,"STRING_ID_ITEM");
666     mapResult.insert(0x0002,"TYPE_ID_ITEM");
667     mapResult.insert(0x0003,"PROTO_ID_ITEM");
668     mapResult.insert(0x0004,"FIELD_ID_ITEM");
669     mapResult.insert(0x0005,"METHOD_ID_ITEM");
670     mapResult.insert(0x0006,"CLASS_DEF_ITEM");
671     mapResult.insert(0x0007,"CALL_SITE_ID_ITEM");
672     mapResult.insert(0x0008,"METHOD_HANDLE_ITEM");
673     mapResult.insert(0x1000,"MAP_LIST");
674     mapResult.insert(0x1001,"TYPE_LIST");
675     mapResult.insert(0x1002,"ANNOTATION_SET_REF_LIST");
676     mapResult.insert(0x1003,"ANNOTATION_SET_ITEM");
677     mapResult.insert(0x2000,"CLASS_DATA_ITEM");
678     mapResult.insert(0x2001,"CODE_ITEM");
679     mapResult.insert(0x2002,"STRING_DATA_ITEM");
680     mapResult.insert(0x2003,"DEBUG_INFO_ITEM");
681     mapResult.insert(0x2004,"ANNOTATION_ITEM");
682     mapResult.insert(0x2005,"ENCODED_ARRAY_ITEM");
683     mapResult.insert(0x2006,"ANNOTATIONS_DIRECTORY_ITEM");
684     mapResult.insert(0xF000,"HIDDENAPI_CLASS_DATA_ITEM");
685 
686     return mapResult;
687 }
688 
getMapItem(quint16 nType,QList<XDEX_DEF::MAP_ITEM> * pMapItems)689 XDEX_DEF::MAP_ITEM XDEX::getMapItem(quint16 nType, QList<XDEX_DEF::MAP_ITEM> *pMapItems)
690 {
691     XDEX_DEF::MAP_ITEM result={};
692 
693     int nCount=pMapItems->count();
694 
695     for(int i=0;i<nCount;i++)
696     {
697         if(pMapItems->at(i).nType==nType)
698         {
699             result=pMapItems->at(i);
700 
701             break;
702         }
703     }
704 
705     return result;
706 }
707 
getList_STRING_ITEM_ID()708 QList<XDEX_DEF::STRING_ITEM_ID> XDEX::getList_STRING_ITEM_ID()
709 {
710     QList<XDEX_DEF::MAP_ITEM> listMapItems=getMapItems();
711 
712     return getList_STRING_ITEM_ID(&listMapItems);
713 }
714 
getList_STRING_ITEM_ID(QList<XDEX_DEF::MAP_ITEM> * pListMapItems)715 QList<XDEX_DEF::STRING_ITEM_ID> XDEX::getList_STRING_ITEM_ID(QList<XDEX_DEF::MAP_ITEM> *pListMapItems)
716 {
717     QList<XDEX_DEF::STRING_ITEM_ID> listResult;
718 
719     bool bIsBigEndian=isBigEndian();
720 
721     XDEX_DEF::MAP_ITEM mapItem=getMapItem(XDEX_DEF::TYPE_STRING_ID_ITEM,pListMapItems);
722 
723     QByteArray baData=read_array(mapItem.nOffset,mapItem.nCount*sizeof(XDEX_DEF::STRING_ITEM_ID));
724     char *pData=baData.data();
725     int nSize=baData.size()/sizeof(XDEX_DEF::STRING_ITEM_ID);
726 
727     for(int i=0;i<nSize;i++)
728     {
729         qint64 nOffset=sizeof(XDEX_DEF::STRING_ITEM_ID)*i;
730 
731         XDEX_DEF::STRING_ITEM_ID record={};
732 
733         record.string_data_off=_read_int32(pData+nOffset+offsetof(XDEX_DEF::STRING_ITEM_ID,string_data_off),bIsBigEndian);
734 
735         listResult.append(record);
736     }
737 
738     return listResult;
739 }
740 
getList_TYPE_ITEM_ID()741 QList<XDEX_DEF::TYPE_ITEM_ID> XDEX::getList_TYPE_ITEM_ID()
742 {
743     QList<XDEX_DEF::MAP_ITEM> listMapItems=getMapItems();
744 
745     return getList_TYPE_ITEM_ID(&listMapItems);
746 }
747 
getList_TYPE_ITEM_ID(QList<XDEX_DEF::MAP_ITEM> * pListMapItems)748 QList<XDEX_DEF::TYPE_ITEM_ID> XDEX::getList_TYPE_ITEM_ID(QList<XDEX_DEF::MAP_ITEM> *pListMapItems)
749 {
750     QList<XDEX_DEF::TYPE_ITEM_ID> listResult;
751 
752     XDEX_DEF::MAP_ITEM mapItem=getMapItem(XDEX_DEF::TYPE_TYPE_ID_ITEM,pListMapItems);
753     bool bIsBigEndian=isBigEndian();
754 
755     QByteArray baData=read_array(mapItem.nOffset,mapItem.nCount*sizeof(XDEX_DEF::TYPE_ITEM_ID));
756     char *pData=baData.data();
757     int nSize=baData.size()/sizeof(XDEX_DEF::TYPE_ITEM_ID);
758 
759     for(int i=0;i<nSize;i++)
760     {
761         qint64 nOffset=sizeof(XDEX_DEF::TYPE_ITEM_ID)*i;
762 
763         XDEX_DEF::TYPE_ITEM_ID record={};
764 
765         record.descriptor_idx=_read_int32(pData+nOffset+offsetof(XDEX_DEF::TYPE_ITEM_ID,descriptor_idx),bIsBigEndian);
766 
767         listResult.append(record);
768     }
769 
770     return listResult;
771 }
772 
getList_PROTO_ITEM_ID(QList<XDEX_DEF::MAP_ITEM> * pListMapItems)773 QList<XDEX_DEF::PROTO_ITEM_ID> XDEX::getList_PROTO_ITEM_ID(QList<XDEX_DEF::MAP_ITEM> *pListMapItems)
774 {
775     QList<XDEX_DEF::PROTO_ITEM_ID> listResult;
776 
777     XDEX_DEF::MAP_ITEM mapItem=getMapItem(XDEX_DEF::TYPE_PROTO_ID_ITEM,pListMapItems);
778     bool bIsBigEndian=isBigEndian();
779 
780     QByteArray baData=read_array(mapItem.nOffset,mapItem.nCount*sizeof(XDEX_DEF::PROTO_ITEM_ID));
781     char *pData=baData.data();
782     int nSize=baData.size()/sizeof(XDEX_DEF::PROTO_ITEM_ID);
783 
784     for(int i=0;i<nSize;i++)
785     {
786         qint64 nOffset=sizeof(XDEX_DEF::PROTO_ITEM_ID)*i;
787 
788         XDEX_DEF::PROTO_ITEM_ID record={};
789 
790         record.shorty_idx=_read_int32(pData+nOffset+offsetof(XDEX_DEF::PROTO_ITEM_ID,shorty_idx),bIsBigEndian);
791         record.return_type_idx=_read_int32(pData+nOffset+offsetof(XDEX_DEF::PROTO_ITEM_ID,return_type_idx),bIsBigEndian);
792         record.parameters_off=_read_int32(pData+nOffset+offsetof(XDEX_DEF::PROTO_ITEM_ID,parameters_off),bIsBigEndian);
793 
794         listResult.append(record);
795     }
796 
797     return listResult;
798 }
799 
getList_FIELD_ITEM_ID(QList<XDEX_DEF::MAP_ITEM> * pListMapItems,bool * pbIsStop)800 QList<XDEX_DEF::FIELD_ITEM_ID> XDEX::getList_FIELD_ITEM_ID(QList<XDEX_DEF::MAP_ITEM> *pListMapItems, bool *pbIsStop)
801 {
802     bool _bIsStop=false;
803 
804     if(pbIsStop==nullptr)
805     {
806         pbIsStop=&_bIsStop;
807     }
808 
809     QList<XDEX_DEF::FIELD_ITEM_ID> listResult;
810 
811     XDEX_DEF::MAP_ITEM mapItem=getMapItem(XDEX_DEF::TYPE_FIELD_ID_ITEM,pListMapItems);
812     bool bIsBigEndian=isBigEndian();
813 
814     QByteArray baData=read_array(mapItem.nOffset,mapItem.nCount*sizeof(XDEX_DEF::FIELD_ITEM_ID));
815     char *pData=baData.data();
816     int nSize=baData.size()/sizeof(XDEX_DEF::FIELD_ITEM_ID);
817 
818     for(int i=0;(i<nSize)&&(!(*pbIsStop));i++)
819     {
820         qint64 nOffset=sizeof(XDEX_DEF::FIELD_ITEM_ID)*i;
821 
822         XDEX_DEF::FIELD_ITEM_ID record={};
823 
824         record.class_idx=_read_int16(pData+nOffset+offsetof(XDEX_DEF::FIELD_ITEM_ID,class_idx),bIsBigEndian);
825         record.type_idx=_read_int16(pData+nOffset+offsetof(XDEX_DEF::FIELD_ITEM_ID,type_idx),bIsBigEndian);
826         record.name_idx=_read_int32(pData+nOffset+offsetof(XDEX_DEF::FIELD_ITEM_ID,name_idx),bIsBigEndian);
827 
828         listResult.append(record);
829     }
830 
831     return listResult;
832 }
833 
getList_METHOD_ITEM_ID(QList<XDEX_DEF::MAP_ITEM> * pListMapItems,bool * pbIsStop)834 QList<XDEX_DEF::METHOD_ITEM_ID> XDEX::getList_METHOD_ITEM_ID(QList<XDEX_DEF::MAP_ITEM> *pListMapItems, bool *pbIsStop)
835 {
836     bool _bIsStop=false;
837 
838     if(pbIsStop==nullptr)
839     {
840         pbIsStop=&_bIsStop;
841     }
842 
843     QList<XDEX_DEF::METHOD_ITEM_ID> listResult;
844 
845     XDEX_DEF::MAP_ITEM mapItem=getMapItem(XDEX_DEF::TYPE_METHOD_ID_ITEM,pListMapItems);
846     bool bIsBigEndian=isBigEndian();
847 
848     QByteArray baData=read_array(mapItem.nOffset,mapItem.nCount*sizeof(XDEX_DEF::METHOD_ITEM_ID));
849     char *pData=baData.data();
850     int nSize=baData.size()/sizeof(XDEX_DEF::METHOD_ITEM_ID);
851 
852     for(int i=0;(i<nSize)&&(!(*pbIsStop));i++)
853     {
854         qint64 nOffset=sizeof(XDEX_DEF::METHOD_ITEM_ID)*i;
855 
856         XDEX_DEF::METHOD_ITEM_ID record={};
857 
858         record.class_idx=_read_int16(pData+nOffset+offsetof(XDEX_DEF::METHOD_ITEM_ID,class_idx),bIsBigEndian);
859         record.proto_idx=_read_int16(pData+nOffset+offsetof(XDEX_DEF::METHOD_ITEM_ID,proto_idx),bIsBigEndian);
860         record.name_idx=_read_int32(pData+nOffset+offsetof(XDEX_DEF::METHOD_ITEM_ID,name_idx),bIsBigEndian);
861 
862         listResult.append(record);
863     }
864 
865     return listResult;
866 }
867 
getList_CLASS_ITEM_DEF(QList<XDEX_DEF::MAP_ITEM> * pListMapItems)868 QList<XDEX_DEF::CLASS_ITEM_DEF> XDEX::getList_CLASS_ITEM_DEF(QList<XDEX_DEF::MAP_ITEM> *pListMapItems)
869 {
870     QList<XDEX_DEF::CLASS_ITEM_DEF> listResult;
871 
872     XDEX_DEF::MAP_ITEM mapItem=getMapItem(XDEX_DEF::TYPE_CLASS_DEF_ITEM,pListMapItems);
873     bool bIsBigEndian=isBigEndian();
874 
875     QByteArray baData=read_array(mapItem.nOffset,mapItem.nCount*sizeof(XDEX_DEF::CLASS_ITEM_DEF));
876     char *pData=baData.data();
877     int nSize=baData.size()/sizeof(XDEX_DEF::CLASS_ITEM_DEF);
878 
879     for(int i=0;i<nSize;i++)
880     {
881         qint64 nOffset=sizeof(XDEX_DEF::CLASS_ITEM_DEF)*i;
882 
883         XDEX_DEF::CLASS_ITEM_DEF record={};
884 
885         record.class_idx=_read_int32(pData+nOffset+offsetof(XDEX_DEF::CLASS_ITEM_DEF,class_idx),bIsBigEndian);
886         record.access_flags=_read_int32(pData+nOffset+offsetof(XDEX_DEF::CLASS_ITEM_DEF,access_flags),bIsBigEndian);
887         record.superclass_idx=_read_int32(pData+nOffset+offsetof(XDEX_DEF::CLASS_ITEM_DEF,superclass_idx),bIsBigEndian);
888         record.interfaces_off=_read_int32(pData+nOffset+offsetof(XDEX_DEF::CLASS_ITEM_DEF,interfaces_off),bIsBigEndian);
889         record.source_file_idx=_read_int32(pData+nOffset+offsetof(XDEX_DEF::CLASS_ITEM_DEF,source_file_idx),bIsBigEndian);
890         record.annotations_off=_read_int32(pData+nOffset+offsetof(XDEX_DEF::CLASS_ITEM_DEF,annotations_off),bIsBigEndian);
891         record.class_data_off=_read_int32(pData+nOffset+offsetof(XDEX_DEF::CLASS_ITEM_DEF,class_data_off),bIsBigEndian);
892         record.static_values_off=_read_int32(pData+nOffset+offsetof(XDEX_DEF::CLASS_ITEM_DEF,static_values_off),bIsBigEndian);
893 
894         listResult.append(record);
895     }
896 
897     return listResult;
898 }
899 
getStrings(QList<XDEX_DEF::MAP_ITEM> * pMapItems,bool * pbIsStop)900 QList<QString> XDEX::getStrings(QList<XDEX_DEF::MAP_ITEM> *pMapItems,bool *pbIsStop)
901 {
902     bool _bIsStop=false;
903 
904     if(pbIsStop==nullptr)
905     {
906         pbIsStop=&_bIsStop;
907     }
908 
909     QList<QString> listResult;
910 
911     bool bIsBigEndian=isBigEndian();
912 
913     XDEX_DEF::MAP_ITEM map_strings=getMapItem(XDEX_DEF::TYPE_STRING_ID_ITEM,pMapItems);
914 
915     QByteArray baData=read_array(getHeader_data_off(),getHeader_data_size());
916 
917     for(quint32 i=0;(i<map_strings.nCount)&&(!(*pbIsStop));i++)
918     {
919         QString sString=_getString(map_strings,i,bIsBigEndian,baData.data(),baData.size(),getHeader_data_off());
920 
921         listResult.append(sString);
922     }
923 
924     return listResult;
925 }
926 
_getString(XDEX_DEF::MAP_ITEM map_stringIdItem,quint32 nIndex,bool bIsBigEndian)927 QString XDEX::_getString(XDEX_DEF::MAP_ITEM map_stringIdItem, quint32 nIndex, bool bIsBigEndian)
928 {
929     QString sResult;
930 
931     if(nIndex<map_stringIdItem.nCount)
932     {
933         qint64 nOffset=map_stringIdItem.nOffset+sizeof(quint32)*nIndex;
934 
935         quint32 nStringsOffset=read_uint32(nOffset,bIsBigEndian);
936 
937         sResult=XBinary::_read_utf8String(nStringsOffset);
938     }
939 
940     return sResult;
941 }
942 
_getString(XDEX_DEF::MAP_ITEM map_stringIdItem,quint32 nIndex,bool bIsBigEndian,char * pData,qint32 nDataSize,qint32 nDataOffset)943 QString XDEX::_getString(XDEX_DEF::MAP_ITEM map_stringIdItem, quint32 nIndex, bool bIsBigEndian, char *pData, qint32 nDataSize, qint32 nDataOffset)
944 {
945     QString sResult;
946 
947     if(nIndex<map_stringIdItem.nCount)
948     {
949         qint64 nOffset=map_stringIdItem.nOffset+sizeof(quint32)*nIndex;
950 
951         qint32 nStringsOffset=(qint32)read_uint32(nOffset,bIsBigEndian);
952 
953         sResult=XBinary::_read_utf8String(nStringsOffset,pData,nDataSize,nDataOffset);
954     }
955 
956     return sResult;
957 }
958 
_getTypeItemtString(XDEX_DEF::MAP_ITEM map_stringIdItem,XDEX_DEF::MAP_ITEM map_typeItemId,quint32 nIndex,bool bIsBigEndian)959 QString XDEX::_getTypeItemtString(XDEX_DEF::MAP_ITEM map_stringIdItem, XDEX_DEF::MAP_ITEM map_typeItemId, quint32 nIndex, bool bIsBigEndian)
960 {
961     QString sResult;
962 
963     if(nIndex<map_typeItemId.nCount)
964     {
965         quint32 nID=read_uint32(map_typeItemId.nOffset+sizeof(quint32)*nIndex,bIsBigEndian);
966 
967         sResult=_getString(map_stringIdItem,nID,bIsBigEndian);
968     }
969 
970     return sResult;
971 }
972 
_getTypeList(qint64 nOffset,bool bIsBigEndian)973 QList<quint32> XDEX::_getTypeList(qint64 nOffset, bool bIsBigEndian)
974 {
975     QList<quint32> listResult;
976 
977     if(nOffset)
978     {
979         quint32 nCount=read_uint32(nOffset,bIsBigEndian);
980 
981         for(quint32 i=0;i<nCount;i++)
982         {
983             quint32 nType=read_uint32(nOffset+sizeof(quint32)*(1+i),bIsBigEndian);
984             listResult.append(nType);
985         }
986     }
987 
988     return listResult;
989 }
990 
getTypeItemStrings(QList<XDEX_DEF::MAP_ITEM> * pMapItems,QList<QString> * pListStrings,bool * pbIsStop)991 QList<QString> XDEX::getTypeItemStrings(QList<XDEX_DEF::MAP_ITEM> *pMapItems, QList<QString> *pListStrings, bool *pbIsStop)
992 {
993     QList<QString> listResult;
994 
995     bool _bIsStop=false;
996 
997     if(pbIsStop==nullptr)
998     {
999         pbIsStop=&_bIsStop;
1000     }
1001 
1002     bool bIsBigEndian=isBigEndian();
1003 
1004     int nStringsCount=pListStrings->count();
1005 
1006     XDEX_DEF::MAP_ITEM map_items=getMapItem(XDEX_DEF::TYPE_TYPE_ID_ITEM,pMapItems);
1007 
1008     for(quint32 i=0;(i<map_items.nCount)&&(!(*pbIsStop));i++)
1009     {
1010         quint32 nOffset=map_items.nOffset+sizeof(quint32)*i;
1011 
1012         quint32 nItem=read_uint32(nOffset,bIsBigEndian);
1013 
1014         if(((qint32)nItem>0)&&((qint32)nItem<nStringsCount))
1015         {
1016             QString sString=pListStrings->at(nItem);
1017 
1018             listResult.append(sString);
1019         }
1020 //        else
1021 //        {
1022 //            qDebug("Error");
1023 //        }
1024     }
1025 
1026     return listResult;
1027 }
1028 
getProtoIdItems(QList<XDEX_DEF::MAP_ITEM> * pMapItems)1029 void XDEX::getProtoIdItems(QList<XDEX_DEF::MAP_ITEM> *pMapItems)
1030 {
1031     bool bIsBigEndian=isBigEndian();
1032 
1033     XDEX_DEF::MAP_ITEM map_protoIdItem=getMapItem(XDEX_DEF::TYPE_PROTO_ID_ITEM,pMapItems);
1034     XDEX_DEF::MAP_ITEM map_typeIdItem=getMapItem(XDEX_DEF::TYPE_TYPE_ID_ITEM,pMapItems);
1035     XDEX_DEF::MAP_ITEM map_stringIdItem=getMapItem(XDEX_DEF::TYPE_STRING_ID_ITEM,pMapItems);
1036 
1037     for(quint32 i=0;i<map_protoIdItem.nCount;i++)
1038     {
1039         quint32 nOffset=map_protoIdItem.nOffset+sizeof(XDEX_DEF::PROTO_ITEM_ID)*i;
1040 
1041         XDEX_DEF::PROTO_ITEM_ID record={};
1042 
1043         record.shorty_idx=read_uint32(nOffset+offsetof(XDEX_DEF::PROTO_ITEM_ID,shorty_idx),bIsBigEndian);
1044         record.return_type_idx=read_uint32(nOffset+offsetof(XDEX_DEF::PROTO_ITEM_ID,return_type_idx),bIsBigEndian);
1045         record.parameters_off=read_uint32(nOffset+offsetof(XDEX_DEF::PROTO_ITEM_ID,parameters_off),bIsBigEndian);
1046 
1047         QString sProto=_getString(map_stringIdItem,record.shorty_idx,bIsBigEndian);
1048         QString sRet=_getTypeItemtString(map_stringIdItem,map_typeIdItem,record.return_type_idx,bIsBigEndian);
1049 
1050         QList<quint32> listParams=_getTypeList(record.parameters_off,bIsBigEndian);
1051 
1052 //        QString sDebugString=QString("%1 %2").arg(sRet,sProto);
1053 
1054 //        qDebug("%s", sDebugString.toLatin1().data());
1055     }
1056 }
1057 
getStringItemIdString(XDEX_DEF::STRING_ITEM_ID stringItemId)1058 QString XDEX::getStringItemIdString(XDEX_DEF::STRING_ITEM_ID stringItemId)
1059 {
1060     QString sResult;
1061 
1062     sResult=_read_utf8String(stringItemId.string_data_off);
1063 
1064     return sResult;
1065 }
1066 
getStringItemIdString(XDEX_DEF::STRING_ITEM_ID stringItemId,char * pData,qint32 nDataSize,qint32 nDataOffset)1067 QString XDEX::getStringItemIdString(XDEX_DEF::STRING_ITEM_ID stringItemId, char *pData, qint32 nDataSize, qint32 nDataOffset)
1068 {
1069     QString sResult;
1070 
1071     sResult=XBinary::_read_utf8String(stringItemId.string_data_off,pData,nDataSize,nDataOffset);
1072 
1073     return sResult;
1074 }
1075 
getTypeItemIdString(XDEX_DEF::TYPE_ITEM_ID typeItemId,XDEX_DEF::MAP_ITEM * pMapItemStrings)1076 QString XDEX::getTypeItemIdString(XDEX_DEF::TYPE_ITEM_ID typeItemId, XDEX_DEF::MAP_ITEM *pMapItemStrings)
1077 {
1078     QString sResult;
1079 
1080     bool bIsBigEndian=isBigEndian();
1081 
1082     sResult=_read_utf8String(read_uint32(pMapItemStrings->nOffset+sizeof(quint32)*typeItemId.descriptor_idx,bIsBigEndian));
1083 
1084     return sResult;
1085 }
1086 
getTypeItemIdString(XDEX_DEF::TYPE_ITEM_ID typeItemId,XDEX_DEF::MAP_ITEM * pMapItemStrings,char * pData,qint32 nDataSize,qint32 nDataOffset)1087 QString XDEX::getTypeItemIdString(XDEX_DEF::TYPE_ITEM_ID typeItemId, XDEX_DEF::MAP_ITEM *pMapItemStrings, char *pData, qint32 nDataSize, qint32 nDataOffset)
1088 {
1089     QString sResult;
1090 
1091     bool bIsBigEndian=isBigEndian();
1092 
1093     sResult=XBinary::_read_utf8String(read_uint32(pMapItemStrings->nOffset+sizeof(quint32)*typeItemId.descriptor_idx,bIsBigEndian),pData,nDataSize,nDataOffset);
1094 
1095     return sResult;
1096 }
1097 
getProtoItemIdString(XDEX_DEF::PROTO_ITEM_ID protoItemId,XDEX_DEF::MAP_ITEM * pMapItemStrings)1098 QString XDEX::getProtoItemIdString(XDEX_DEF::PROTO_ITEM_ID protoItemId, XDEX_DEF::MAP_ITEM *pMapItemStrings)
1099 {
1100     QString sResult;
1101 
1102     bool bIsBigEndian=isBigEndian();
1103 
1104     QString sPrototype=_read_utf8String(read_uint32(pMapItemStrings->nOffset+sizeof(quint32)*protoItemId.shorty_idx,bIsBigEndian));
1105     QString sReturn=_read_utf8String(read_uint32(pMapItemStrings->nOffset+sizeof(quint32)*protoItemId.return_type_idx,bIsBigEndian));
1106     sResult=QString("%1 %2()").arg(sReturn,sPrototype);
1107 
1108     return sResult;
1109 }
1110 
getHeaderMagics()1111 QMap<quint64, QString> XDEX::getHeaderMagics()
1112 {
1113     QMap<quint64, QString> mapResult;
1114 
1115     mapResult.insert(0x0A786564,"Magic");
1116 
1117     return mapResult;
1118 }
1119 
getHeaderVersions()1120 QMap<quint64, QString> XDEX::getHeaderVersions()
1121 {
1122     QMap<quint64, QString> mapResult;
1123 
1124     mapResult.insert(0x00353330,"035");
1125     // 036 invalid
1126     mapResult.insert(0x00373330,"037");
1127     mapResult.insert(0x00383330,"038");
1128     mapResult.insert(0x00393330,"039");
1129 
1130     return mapResult;
1131 }
1132 
getHeaderEndianTags()1133 QMap<quint64, QString> XDEX::getHeaderEndianTags()
1134 {
1135     QMap<quint64, QString> mapResult;
1136 
1137     mapResult.insert(0x12345678,"Little endian");
1138     mapResult.insert(0x78563412,"Big endian");
1139 
1140     return mapResult;
1141 }
1142 
isStringPoolSorted(QList<XDEX_DEF::MAP_ITEM> * pMapItems)1143 bool XDEX::isStringPoolSorted(QList<XDEX_DEF::MAP_ITEM> *pMapItems)
1144 {
1145     bool bResult=true;
1146 
1147     bool bIsBigEndian=isBigEndian();
1148 
1149     XDEX_DEF::MAP_ITEM map_strings=getMapItem(XDEX_DEF::TYPE_STRING_ID_ITEM,pMapItems);
1150 
1151     qint32 nPrevStringOffset=0;
1152 
1153     for(quint32 i=0;i<map_strings.nCount;i++)
1154     {
1155         qint64 nOffset=map_strings.nOffset+sizeof(quint32)*i;
1156 
1157         qint32 nStringOffset=(qint32)read_uint32(nOffset,bIsBigEndian);
1158 
1159         if(nStringOffset<nPrevStringOffset)
1160         {
1161             bResult=false;
1162 
1163             break;
1164         }
1165 
1166         nPrevStringOffset=nStringOffset;
1167     }
1168 
1169     return bResult;
1170 }
1171 
isFieldNamesUnicode(QList<XDEX_DEF::FIELD_ITEM_ID> * pListIDs,QList<QString> * pListStrings)1172 bool XDEX::isFieldNamesUnicode(QList<XDEX_DEF::FIELD_ITEM_ID> *pListIDs, QList<QString> *pListStrings)
1173 {
1174     bool bResult=false;
1175 
1176     int nNumberOfIds=pListIDs->count();
1177     int nNumberOfStrings=pListStrings->count();
1178 
1179     for(int i=0;i<nNumberOfIds;i++)
1180     {
1181         QString sString=getStringByIndex(pListStrings,pListIDs->at(i).name_idx,nNumberOfStrings);
1182 
1183         if(XBinary::isStringUnicode(sString))
1184         {
1185             bResult=true;
1186             break;
1187         }
1188     }
1189 
1190     return bResult;
1191 }
1192 
isMethodNamesUnicode(QList<XDEX_DEF::METHOD_ITEM_ID> * pListIDs,QList<QString> * pListStrings)1193 bool XDEX::isMethodNamesUnicode(QList<XDEX_DEF::METHOD_ITEM_ID> *pListIDs, QList<QString> *pListStrings)
1194 {
1195     bool bResult=false;
1196 
1197     int nNumberOfIds=pListIDs->count();
1198     int nNumberOfStrings=pListStrings->count();
1199 
1200     for(int i=0;i<nNumberOfIds;i++)
1201     {
1202         QString sString=getStringByIndex(pListStrings,pListIDs->at(i).name_idx,nNumberOfStrings);
1203 
1204         if(XBinary::isStringUnicode(sString))
1205         {
1206             bResult=true;
1207             break;
1208         }
1209     }
1210 
1211     return bResult;
1212 }
1213 
isStringPoolSorted()1214 bool XDEX::isStringPoolSorted()
1215 {
1216     QList<XDEX_DEF::MAP_ITEM> mapItems=getMapItems();
1217 
1218     return isStringPoolSorted(&mapItems);
1219 }
1220