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