##// END OF EJS Templates
removed elf_getphdrnum need for old Ubuntu versions...
Jeandet Alexis -
r7:4c09cf9ebb16 default
parent child
Show More
@@ -1,1077 +1,1080
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the SocExplorer Software
3 3 -- Copyright (C) 2014, Plasma Physics Laboratory - CNRS
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 2 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------*/
19 19 /*-- Author :
20 20 Alexis Jeandet
21 21 -- Mail :
22 22 alexis.jeandet@member.fsf.org
23 23 ----------------------------------------------------------------------------*/
24 24 #include "elffile.h"
25 25 #include "srecfile.h"
26 26 #include "binaryfile.h"
27 27 #include <stdint.h>
28 28
29 29 ElfFile::ElfFile()
30 30 :abstractBinFile()
31 31 {
32 32 this->opened = false;
33 33 this->type_elf = false;
34 34 this->elfFile = (int)NULL;
35 35 this->e = NULL;
36 36 }
37 37
38 38 ElfFile::ElfFile(const QString &File)
39 39 :abstractBinFile()
40 40 {
41 41 this->opened = false;
42 42 this->type_elf = false;
43 43 this->elfFile = (int)NULL;
44 44 this->e = NULL;
45 45 this->p_fileName = File;
46 46 openFile(File);
47 47 }
48 48
49 49 ElfFile::~ElfFile()
50 50 {
51 51 closeFile();
52 52 if(scn)free(scn);
53 53 if(data)free(data);
54 54 for(int i=0;i<this->sections.count();i++)
55 55 {
56 56 delete this->sections.at(i);
57 57 }
58 58 this->sections.clear();
59 59 for(int i=0;i<this->Segments.count();i++)
60 60 {
61 61 free(this->Segments.at(i));
62 62 }
63 63 this->Segments.clear();
64 64 for(int i=0;i<symbols.count();i++)
65 65 {
66 66 delete this->symbols.at(i);
67 67 }
68 68 this->symbols.clear();
69 69 }
70 70
71 71 bool ElfFile::openFile(const QString &File)
72 72 {
73 73 this->p_fileName = File;
74 74 this->closeFile();
75 75 if(elf_version(EV_CURRENT)==EV_NONE)return 0;
76 76 #ifdef _ELF_WINDOWS_
77 77 this->elfFile = open(File.toStdString().c_str(),O_RDONLY|O_BINARY ,0);
78 78 #else
79 79 this->elfFile = open(File.toStdString().c_str(),O_RDONLY ,0);
80 80 #endif
81 81 if(this->elfFile==(int)NULL)return 0;
82 82 this->e = elf_begin(this->elfFile,ELF_C_READ,NULL);
83 83 if(this->e==NULL)return 0;
84 84 this->ek = elf_kind(this->e);
85 85 gelf_getehdr (this->e, &this->ehdr );
86 86 elf_getshdrstrndx (this->e, &this->shstrndx);
87 87 this->updateSegments();
88 88 this->updateSections();
89 89 this->updateSymbols();
90 90 this->opened = true;
91 91 return 1;
92 92 }
93 93
94 94 bool ElfFile::isopened()
95 95 {
96 96 return this->opened;
97 97 }
98 98
99 99 int ElfFile::closeFile()
100 100 {
101 101 if(this->elfFile!=(int)NULL)
102 102 {
103 103 if(this->e!=NULL)
104 104 {
105 105 elf_end(this->e);
106 106 this->e = NULL;
107 107 }
108 108 close(this->elfFile);
109 109 this->elfFile = (int)NULL;
110 110 }
111 111 this->opened = false;
112 112 return 0;
113 113 }
114 114
115 115
116 116 QList<codeFragment*> ElfFile::getFragments(QStringList fragmentList)
117 117 {
118 118 QList<codeFragment*> fragments;
119 119 if (isopened())
120 120 {
121 121 for(int i =0;i<fragmentList.count();i++)
122 122 {
123 123 fragments.append(getFragment(fragmentList.at(i)));
124 124 }
125 125 }
126 126 return fragments;
127 127 }
128 128
129 129 QList<codeFragment*> ElfFile::getFragments()
130 130 {
131 131 return getFragments(QStringList()<<".data"<<".text");
132 132 }
133 133
134 134 codeFragment *ElfFile::getFragment(const QString &name)
135 135 {
136 136 codeFragment* fragment= new codeFragment();
137 137 for(int i=0;i<getSectionCount();i++)
138 138 {
139 139 if(getSectionName(i) == name)
140 140 {
141 141 fragment->data =NULL;
142 142 fragment->size = getSectionDatasz(i);
143 143 fragment->address = getSectionPaddr(i);
144 144 getSectionData(i,&fragment->data);
145 145 }
146 146 }
147 147 return fragment;
148 148 }
149 149
150 150
151 151
152 152
153 153
154 154
155 155
156 156 QString elfresolveMachine(Elf64_Half e_machine)
157 157 {
158 158 QString machineName;
159 159 //Update from with bash script don't write it by yourself!
160 160 switch(e_machine)
161 161 {
162 162 case EM_NONE:
163 163 machineName = " No machine ";
164 164 break;
165 165 case EM_M32:
166 166 machineName = " AT&T WE 32100 ";
167 167 break;
168 168 case EM_SPARC:
169 169 machineName = " SUN SPARC ";
170 170 break;
171 171 case EM_386:
172 172 machineName = " Intel 80386 ";
173 173 break;
174 174 case EM_68K:
175 175 machineName = " Motorola m68k family ";
176 176 break;
177 177 case EM_88K:
178 178 machineName = " Motorola m88k family ";
179 179 break;
180 180 case EM_860:
181 181 machineName = " Intel 80860 ";
182 182 break;
183 183 case EM_MIPS:
184 184 machineName = " MIPS R3000 big-endian ";
185 185 break;
186 186 case EM_S370:
187 187 machineName = " IBM System/370 ";
188 188 break;
189 189 case EM_MIPS_RS3_LE:
190 190 machineName = " MIPS R3000 little-endian ";
191 191 break;
192 192 case EM_PARISC:
193 193 machineName = " HPPA ";
194 194 break;
195 195 case EM_VPP500:
196 196 machineName = " Fujitsu VPP500 ";
197 197 break;
198 198 case EM_SPARC32PLUS:
199 199 machineName = " Sun's \"v8plus\" ";
200 200 break;
201 201 case EM_960:
202 202 machineName = " Intel 80960 ";
203 203 break;
204 204 case EM_PPC:
205 205 machineName = " PowerPC ";
206 206 break;
207 207 case EM_PPC64:
208 208 machineName = " PowerPC 64-bit ";
209 209 break;
210 210 case EM_S390:
211 211 machineName = " IBM S390 ";
212 212 break;
213 213 case EM_V800:
214 214 machineName = " NEC V800 series ";
215 215 break;
216 216 case EM_FR20:
217 217 machineName = " Fujitsu FR20 ";
218 218 break;
219 219 case EM_RH32:
220 220 machineName = " TRW RH-32 ";
221 221 break;
222 222 case EM_RCE:
223 223 machineName = " Motorola RCE ";
224 224 break;
225 225 case EM_ARM:
226 226 machineName = " ARM ";
227 227 break;
228 228 case EM_FAKE_ALPHA:
229 229 machineName = " Digital Alpha ";
230 230 break;
231 231 case EM_SH:
232 232 machineName = " Hitachi SH ";
233 233 break;
234 234 case EM_SPARCV9:
235 235 machineName = " SPARC v9 64-bit ";
236 236 break;
237 237 case EM_TRICORE:
238 238 machineName = " Siemens Tricore ";
239 239 break;
240 240 case EM_ARC:
241 241 machineName = " Argonaut RISC Core ";
242 242 break;
243 243 case EM_H8_300:
244 244 machineName = " Hitachi H8/300 ";
245 245 break;
246 246 case EM_H8_300H:
247 247 machineName = " Hitachi H8/300H ";
248 248 break;
249 249 case EM_H8S:
250 250 machineName = " Hitachi H8S ";
251 251 break;
252 252 case EM_H8_500:
253 253 machineName = " Hitachi H8/500 ";
254 254 break;
255 255 case EM_IA_64:
256 256 machineName = " Intel Merced ";
257 257 break;
258 258 case EM_MIPS_X:
259 259 machineName = " Stanford MIPS-X ";
260 260 break;
261 261 case EM_COLDFIRE:
262 262 machineName = " Motorola Coldfire ";
263 263 break;
264 264 case EM_68HC12:
265 265 machineName = " Motorola M68HC12 ";
266 266 break;
267 267 case EM_MMA:
268 268 machineName = " Fujitsu MMA Multimedia Accelerator";
269 269 break;
270 270 case EM_PCP:
271 271 machineName = " Siemens PCP ";
272 272 break;
273 273 case EM_NCPU:
274 274 machineName = " Sony nCPU embeeded RISC ";
275 275 break;
276 276 case EM_NDR1:
277 277 machineName = " Denso NDR1 microprocessor ";
278 278 break;
279 279 case EM_STARCORE:
280 280 machineName = " Motorola Start*Core processor ";
281 281 break;
282 282 case EM_ME16:
283 283 machineName = " Toyota ME16 processor ";
284 284 break;
285 285 case EM_ST100:
286 286 machineName = " STMicroelectronic ST100 processor ";
287 287 break;
288 288 case EM_TINYJ:
289 289 machineName = " Advanced Logic Corp. Tinyj emb.fam";
290 290 break;
291 291 case EM_X86_64:
292 292 machineName = " AMD x86-64 architecture ";
293 293 break;
294 294 case EM_PDSP:
295 295 machineName = " Sony DSP Processor ";
296 296 break;
297 297 case EM_FX66:
298 298 machineName = " Siemens FX66 microcontroller ";
299 299 break;
300 300 case EM_ST9PLUS:
301 301 machineName = " STMicroelectronics ST9+ 8/16 mc ";
302 302 break;
303 303 case EM_ST7:
304 304 machineName = " STmicroelectronics ST7 8 bit mc ";
305 305 break;
306 306 case EM_68HC16:
307 307 machineName = " Motorola MC68HC16 microcontroller ";
308 308 break;
309 309 case EM_68HC11:
310 310 machineName = " Motorola MC68HC11 microcontroller ";
311 311 break;
312 312 case EM_68HC08:
313 313 machineName = " Motorola MC68HC08 microcontroller ";
314 314 break;
315 315 case EM_68HC05:
316 316 machineName = " Motorola MC68HC05 microcontroller ";
317 317 break;
318 318 case EM_SVX:
319 319 machineName = " Silicon Graphics SVx ";
320 320 break;
321 321 case EM_ST19:
322 322 machineName = " STMicroelectronics ST19 8 bit mc ";
323 323 break;
324 324 case EM_VAX:
325 325 machineName = " Digital VAX ";
326 326 break;
327 327 case EM_CRIS:
328 328 machineName = " Axis Communications 32-bit embedded processor ";
329 329 break;
330 330 case EM_JAVELIN:
331 331 machineName = " Infineon Technologies 32-bit embedded processor ";
332 332 break;
333 333 case EM_FIREPATH:
334 334 machineName = " Element 14 64-bit DSP Processor ";
335 335 break;
336 336 case EM_ZSP:
337 337 machineName = " LSI Logic 16-bit DSP Processor ";
338 338 break;
339 339 case EM_MMIX:
340 340 machineName = " Donald Knuth's educational 64-bit processor ";
341 341 break;
342 342 case EM_HUANY:
343 343 machineName = " Harvard University machine-independent object files ";
344 344 break;
345 345 case EM_PRISM:
346 346 machineName = " SiTera Prism ";
347 347 break;
348 348 case EM_AVR:
349 349 machineName = " Atmel AVR 8-bit microcontroller ";
350 350 break;
351 351 case EM_FR30:
352 352 machineName = " Fujitsu FR30 ";
353 353 break;
354 354 case EM_D10V:
355 355 machineName = " Mitsubishi D10V ";
356 356 break;
357 357 case EM_D30V:
358 358 machineName = " Mitsubishi D30V ";
359 359 break;
360 360 case EM_V850:
361 361 machineName = " NEC v850 ";
362 362 break;
363 363 case EM_M32R:
364 364 machineName = " Mitsubishi M32R ";
365 365 break;
366 366 case EM_MN10300:
367 367 machineName = " Matsushita MN10300 ";
368 368 break;
369 369 case EM_MN10200:
370 370 machineName = " Matsushita MN10200 ";
371 371 break;
372 372 case EM_PJ:
373 373 machineName = " picoJava ";
374 374 break;
375 375 case EM_OPENRISC:
376 376 machineName = " OpenRISC 32-bit embedded processor ";
377 377 break;
378 378 case EM_ARC_A5:
379 379 machineName = " ARC Cores Tangent-A5 ";
380 380 break;
381 381 case EM_XTENSA:
382 382 machineName = " Tensilica Xtensa Architecture ";
383 383 break;
384 384 case EM_AARCH64:
385 385 machineName = " ARM AARCH64 ";
386 386 break;
387 387 case EM_TILEPRO:
388 388 machineName = " Tilera TILEPro ";
389 389 break;
390 390 case EM_MICROBLAZE:
391 391 machineName = " Xilinx MicroBlaze ";
392 392 break;
393 393 case EM_TILEGX:
394 394 machineName = " Tilera TILE-Gx ";
395 395 break;
396 396 case EM_NUM:
397 397 machineName = "";
398 398 break;
399 399 default:
400 400 machineName ="Unknow Machine";
401 401 break;
402 402 }
403 403 return machineName;
404 404 }
405 405
406 406
407 407
408 408
409 409 QString ElfFile::getClass()
410 410 {
411 411 if(this->e!=NULL)
412 412 {
413 413 int eclass = gelf_getclass(this->e);
414 414 if(eclass==ELFCLASS32)return "ELF32";
415 415 if(eclass==ELFCLASS64)return "ELF64";
416 416 }
417 417 return "none";
418 418 }
419 419
420 420
421 421 bool ElfFile::iself()
422 422 {
423 423 return (this->getType()!="Unknow");
424 424 }
425 425
426 426 QString ElfFile::getArchitecture()
427 427 {
428 428 if(this->e!=NULL)
429 429 {
430 430 return elfresolveMachine(this->ehdr.e_machine);
431 431 }
432 432 return "";
433 433 }
434 434
435 435
436 436 QString ElfFile::getType()
437 437 {
438 438 QString kind("");
439 439 if(this->e!=NULL)
440 440 {
441 441 switch(this->ek)
442 442 {
443 443 case ELF_K_AR:
444 444 kind = "Archive";
445 445 break;
446 446 case ELF_K_ELF:
447 447 kind = "Elf";
448 448 break;
449 449 case ELF_K_COFF:
450 450 kind = "COFF";
451 451 break;
452 452 case ELF_K_NUM:
453 453 kind = "NUM";
454 454 break;
455 455 case ELF_K_NONE:
456 456 kind = "Data";
457 457 break;
458 458 default:
459 459 kind = "Unknow";
460 460 break;
461 461 }
462 462 }
463 463 return kind;
464 464 }
465 465
466 466 QString ElfFile::getEndianness()
467 467 {
468 468 if(this->e!=NULL)
469 469 {
470 470 if(this->ehdr.e_ident[EI_DATA]==ELFDATA2LSB)return "2's complement, little endian";
471 471 if(this->ehdr.e_ident[EI_DATA]==ELFDATA2MSB)return "2's complement, big endian";
472 472 }
473 473 return "none";
474 474 }
475 475
476 476 QString ElfFile::getABI()
477 477 {
478 478 if(this->e!=NULL)
479 479 {
480 480 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_NONE)return "UNIX System V ABI";
481 481 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_SYSV)return "Alias";
482 482 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_HPUX)return "HP-UX";
483 483 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_NETBSD)return "NetBSD";
484 484 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_LINUX)return "Object uses GNU ELF extensions";
485 485 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_SOLARIS)return "Sun Solaris";
486 486 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_AIX)return "IBM AIX";
487 487 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_IRIX)return "SGI Irix";
488 488 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_FREEBSD)return "FreeBSD";
489 489 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_TRU64)return "Compaq TRU64 UNIX";
490 490 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_MODESTO)return " Novell Modesto";
491 491 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_OPENBSD)return "OpenBSD";
492 492 #ifdef ELFOSABI_ARM_AEABI
493 493 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_ARM_AEABI)return "ARM EABI";
494 494 #endif
495 495 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_ARM)return "ARM";
496 496 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_STANDALONE)return "Standalone (embedded) application";
497 497 }
498 498 return "none";
499 499 }
500 500
501 501
502 502 qint64 ElfFile::getVersion()
503 503 {
504 504 if(this->e!=NULL)
505 505 {
506 506 return this->ehdr.e_version;
507 507 }
508 508 return -1;
509 509 }
510 510
511 511 qint64 ElfFile::getEntryPointAddress()
512 512 {
513 513 if(this->e!=NULL)
514 514 {
515 515 return this->ehdr.e_entry;
516 516 }
517 517 return -1;
518 518 }
519 519
520 520
521 521 int ElfFile::getSectionCount()
522 522 {
523 523 return (int)this->SectionCount;
524 524 }
525 525
526 526 int ElfFile::getSymbolCount()
527 527 {
528 528 return (int)this->SymbolCount;
529 529 }
530 530
531 531
532 532 int ElfFile::getSegmentCount()
533 533 {
534 534 return (int)this->SegmentCount;
535 535 }
536 536
537 537
538 538 QString ElfFile::getSegmentType(int index)
539 539 {
540 540 QString type("");
541 541 if(this->e!=NULL)
542 542 {
543 543 if(index < this->Segments.count())
544 544 {
545 545 switch(this->Segments.at(index)->p_type)
546 546 {
547 547 case PT_NULL:
548 548 type = "Program header table entry unused";
549 549 break;
550 550 case PT_LOAD:
551 551 type = "Loadable program segment";
552 552 break;
553 553 case PT_DYNAMIC :
554 554 type = "Dynamic linking information";
555 555 break;
556 556 case PT_INTERP:
557 557 type ="Program interpreter";
558 558 break;
559 559 case PT_NOTE:
560 560 type = "Auxiliary information";
561 561 break;
562 562 case PT_SHLIB:
563 563 type = "Reserved";
564 564 break;
565 565 case PT_PHDR:
566 566 type = "Entry for header table itself";
567 567 break;
568 568 case PT_TLS:
569 569 type = "Thread-local storage segment";
570 570 break;
571 571 case PT_NUM:
572 572 type = "Number of defined types";
573 573 break;
574 574 case PT_LOOS:
575 575 type = "Start of OS-specific";
576 576 break;
577 577 case PT_SUNWSTACK:
578 578 type = "Stack segment";
579 579 break;
580 580 case PT_LOPROC:
581 581 type = "Start of processor-specific";
582 582 break;
583 583 case PT_HIPROC:
584 584 type = "End of processor-specific";
585 585 break;
586 586 default:
587 587 type = "Unknow Section Type";
588 588 break;
589 589 }
590 590 }
591 591 }
592 592
593 593 return type;
594 594 }
595 595
596 596
597 597 qint64 ElfFile::getSegmentOffset(int index)
598 598 {
599 599 qint64 Offset = -1;
600 600 if(this->e!=NULL)
601 601 {
602 602 if(index < this->Segments.count())
603 603 {
604 604 Offset = (qint64)this->Segments.at(index)->p_offset;
605 605 }
606 606 }
607 607 return Offset;
608 608 }
609 609
610 610
611 611 qint64 ElfFile::getSegmentVaddr(int index)
612 612 {
613 613 int64_t Vaddr = 0;
614 614 if(this->e!=NULL)
615 615 {
616 616 if(index < this->Segments.count())
617 617 {
618 618 Vaddr = (int64_t)this->Segments.at(index)->p_vaddr;
619 619 }
620 620 }
621 621 return Vaddr;
622 622 }
623 623
624 624
625 625 qint64 ElfFile::getSegmentPaddr(int index)
626 626 {
627 627 int64_t Paddr=0;
628 628 if(this->e!=NULL)
629 629 {
630 630 if(index < this->Segments.count())
631 631 {
632 632 Paddr = (int64_t)this->Segments.at(index)->p_paddr;
633 633 }
634 634 }
635 635 return Paddr;
636 636 }
637 637
638 638 qint64 ElfFile::getSectionPaddr(int index)
639 639 {
640 640 int64_t Paddr=0;
641 641 if(this->e!=NULL)
642 642 {
643 643 if(index < this->sections.count())
644 644 {
645 645 Paddr = (int64_t)this->sections.at(index)->section_header->sh_addr;
646 646 }
647 647 }
648 648 return Paddr;
649 649 }
650 650
651 651
652 652 qint64 ElfFile::getSegmentFilesz(int index)
653 653 {
654 654 int64_t FileSz=0;
655 655 if(this->e!=NULL)
656 656 {
657 657 if(index < this->Segments.count())
658 658 {
659 659 FileSz = (int64_t)this->Segments.at(index)->p_filesz;
660 660 }
661 661 }
662 662 return FileSz;
663 663 }
664 664
665 665 qint64 ElfFile::getSectionDatasz(int index)
666 666 {
667 667 int64_t DataSz=0;
668 668 if(this->e!=NULL)
669 669 {
670 670 if(index < this->sections.count())
671 671 {
672 672 if(this->sections.at(index)->section_header->sh_type==SHT_NOBITS)
673 673 {
674 674 DataSz=0;
675 675 }
676 676 else
677 677 {
678 678 DataSz = (int64_t)this->sections.at(index)->data->d_size;
679 679 }
680 680 }
681 681 }
682 682 return DataSz;
683 683 }
684 684
685 685 bool ElfFile::getSectionData(int index, char **buffer)
686 686 {
687 687 if(this->e!=NULL)
688 688 {
689 689 if(index < this->sections.count())
690 690 {
691 691 *buffer = (char *)malloc(this->sections.at(index)->data->d_size);
692 692 memcpy(*buffer,this->sections.at(index)->data->d_buf,this->sections.at(index)->data->d_size);
693 693 return true;
694 694 }
695 695 }
696 696 return false;
697 697 }
698 698
699 699
700 700 qint64 ElfFile::getSegmentMemsz(int index)
701 701 {
702 702 int64_t MemSz=0;
703 703 if(this->e!=NULL)
704 704 {
705 705 if(index < this->Segments.count())
706 706 {
707 707 MemSz = (int64_t)this->Segments.at(index)->p_memsz;
708 708 }
709 709 }
710 710 return MemSz;
711 711 }
712 712
713 713 qint64 ElfFile::getSectionMemsz(int index)
714 714 {
715 715 int64_t MemSz=0;
716 716 if(this->e!=NULL)
717 717 {
718 718 if(index < this->sections.count())
719 719 {
720 720 MemSz = (int64_t)this->sections.at(index)->section_header->sh_size;
721 721 }
722 722 }
723 723 return MemSz;
724 724 }
725 725
726 726
727 727 QString ElfFile::getSegmentFlags(int index)
728 728 {
729 729 QString flags("");
730 730 if(this->e!=NULL)
731 731 {
732 732 if(index < this->Segments.count())
733 733 {
734 734 if((this->Segments.at(index)->p_flags&PF_X) == PF_X)flags+="x";
735 735 if((this->Segments.at(index)->p_flags&PF_W) == PF_W)flags+="w";
736 736 if((this->Segments.at(index)->p_flags&PF_R) == PF_R)flags+="r";
737 737 if((this->Segments.at(index)->p_flags&PF_MASKOS) == PF_MASKOS)flags+=" OS-specific";
738 738 if((this->Segments.at(index)->p_flags&PF_MASKPROC) == PF_MASKPROC)flags+=" Processor-specific";
739 739 }
740 740 }
741 741 return flags;
742 742 }
743 743
744 744
745 745 QString ElfFile::getSectionName(int index)
746 746 {
747 747 if((index<sections.count()) && (index>=0))
748 748 {
749 749 char* nameChr = elf_strptr(this->e , this->shstrndx , this->sections.at(index)->section_header->sh_name);
750 750 return QString(nameChr);
751 751 }
752 752 return "";
753 753 }
754 754
755 755
756 756 void ElfFile::updateSections()
757 757 {
758 758 for(int i=0;i<this->sections.count();i++)
759 759 {
760 760 delete this->sections.at(i);
761 761 }
762 762 this->sections.clear();
763 763 this->scn = elf_nextscn (this->e , NULL );
764 764 this->SectionCount = 0;
765 765 while( this->scn != NULL )
766 766 {
767 767 GElf_Shdr* shdr = (GElf_Shdr*)malloc(sizeof(GElf_Shdr));
768 768 gelf_getshdr ( this->scn , shdr );
769 769 Elf_Data* data = elf_getdata(this->scn, NULL);
770 770 this->sections.append(new Elf_Section(data,shdr));
771 771 this->SectionCount+=1;
772 772 this->scn = elf_nextscn(e , scn);
773 773 }
774 774 }
775 775
776 776
777 777 void ElfFile::updateSegments()
778 778 {
779 elf_getphdrnum (this->e , &this->SegmentCount);
780 779 for(int i=0;i<this->Segments.count();i++)
781 780 {
782 781 free(this->Segments.at(i));
783 782 }
784 783 this->Segments.clear();
785 for(int i=0;i<(int)this->SegmentCount;i++)
784 this->SegmentCount = 0;
785 GElf_Phdr* header=(GElf_Phdr*)malloc(sizeof(GElf_Phdr));
786 while ( header == gelf_getphdr(this->e ,this->SegmentCount, header ))
786 787 {
787 GElf_Phdr* header=(GElf_Phdr*)malloc(sizeof(GElf_Phdr));
788 gelf_getphdr (this->e , i , header );
789 788 this->Segments.append(header);
789 this->SegmentCount++;
790 header=(GElf_Phdr*)malloc(sizeof(GElf_Phdr));
790 791 }
792 this->SegmentCount = this->Segments.count();
793 free(header);
791 794 }
792 795
793 796 void ElfFile::updateSymbols()
794 797 {
795 798 for(int i=0;i<symbols.count();i++)
796 799 {
797 800 delete this->symbols.at(i);
798 801 }
799 802 this->symbols.clear();
800 803 updateSections(); //Useless in most case but safer to do it
801 804 for(int i=0;i<(int)SectionCount;i++)
802 805 {
803 806 //First find Symbol table
804 807 if(this->getSectionName(i)==".symtab")
805 808 {
806 809 Elf_Section* sec = sections.at(i);
807 810 this->SymbolCount = sec->section_header->sh_size / sec->section_header->sh_entsize;
808 811 //Then list all symbols
809 812 for(int j=0;j<(int)this->SymbolCount;j++)
810 813 {
811 814 GElf_Sym* esym = (GElf_Sym*)malloc(sizeof(GElf_Sym));
812 815 gelf_getsym(sec->data, j, esym);
813 816 QString name = elf_strptr(this->e,sec->section_header->sh_link,esym->st_name);
814 817 Elf_Symbol* sym = new Elf_Symbol(name,esym);
815 818 symbols.append(sym);
816 819 }
817 820 }
818 821 }
819 822
820 823 }
821 824
822 825
823 826
824 827 QString ElfFile::getSectionType(int index)
825 828 {
826 829 QString type("");
827 830 if(this->e!=NULL)
828 831 {
829 832 if(index < this->sections.count())
830 833 {
831 834 switch(this->sections.at(index)->section_header->sh_type)
832 835 {
833 836 case SHT_NULL : type = "Section header table entry unused"; break;
834 837 case SHT_PROGBITS : type = "Program data"; break;
835 838 case SHT_SYMTAB : type = "Symbol table"; break;
836 839 case SHT_STRTAB : type = "String table"; break;
837 840 case SHT_RELA : type = "Relocation entries with addends"; break;
838 841 case SHT_HASH : type = "Symbol hash table"; break;
839 842 case SHT_DYNAMIC : type = "Dynamic linking information"; break;
840 843 case SHT_NOTE : type = "Notes"; break;
841 844 case SHT_NOBITS :type = "Program space with no data (bss)"; break;
842 845 case SHT_REL :type = "Relocation entries, no addends"; break;
843 846 case SHT_SHLIB : type = "Reserved"; break;
844 847 case SHT_DYNSYM : type = "Dynamic linker symbol table"; break;
845 848 case SHT_INIT_ARRAY : type = "Array of constructors"; break;
846 849 case SHT_FINI_ARRAY : type = "Array of destructors"; break;
847 850 case SHT_PREINIT_ARRAY : type = "Array of pre-constructors"; break;
848 851 case SHT_GROUP : type = "Section group"; break;
849 852 case SHT_SYMTAB_SHNDX : type = "Extended section indeces"; break;
850 853 case SHT_NUM : type = "Number of defined types. "; break;
851 854 case SHT_LOOS : type = "Start OS-specific. "; break;
852 855 case SHT_LOSUNW : type = "Sun-specific low bound. "; break;
853 856 case SHT_SUNW_COMDAT : type = " "; break;
854 857 case SHT_SUNW_syminfo : type = " "; break;
855 858 case SHT_GNU_verdef : type = "Version definition section. "; break;
856 859 case SHT_GNU_verneed : type = "Version needs section. "; break;
857 860 case SHT_GNU_versym : type = "Version symbol table. "; break;
858 861 case SHT_LOPROC : type = "Start of processor-specific"; break;
859 862 case SHT_HIPROC : type = "End of processor-specific"; break;
860 863 case SHT_HIUSER : type = "End of application-specific"; break;
861 864 }
862 865 }
863 866 }
864 867 return type;
865 868 }
866 869
867 870 int ElfFile::getSectionIndex(QString name)
868 871 {
869 872 if(this->e!=NULL)
870 873 {
871 874 for(int i=0;i<sections.count();i++)
872 875 {
873 876 if(getSectionName(i)==name)
874 877 return i;
875 878 }
876 879 }
877 880 return -1;
878 881 }
879 882
880 883 bool ElfFile::sectionIsNobits(int index)
881 884 {
882 885 if(this->e!=NULL)
883 886 {
884 887 if(index < this->sections.count())
885 888 {
886 889 return this->sections.at(index)->section_header->sh_type== SHT_NOBITS;
887 890 }
888 891 }
889 892 return false;
890 893 }
891 894
892 895 QString ElfFile::getSymbolName(int index)
893 896 {
894 897 if(this->e!=NULL)
895 898 {
896 899 if(index < this->symbols.count())
897 900 {
898 901 return symbols.at(index)->name;
899 902 }
900 903 }
901 904 return "";
902 905 }
903 906
904 907 QString ElfFile::getSymbolType(int index)
905 908 {
906 909 if(this->e!=NULL)
907 910 {
908 911 if(index < this->symbols.count())
909 912 {
910 913 int type = GELF_ST_TYPE(symbols.at(index)->sym->st_info);
911 914 switch(type)
912 915 {
913 916 case STT_NOTYPE:
914 917 return "No Type";
915 918 break;
916 919 case STT_OBJECT:
917 920 return "Object";
918 921 break;
919 922 case STT_FUNC:
920 923 return "Function";
921 924 break;
922 925 case STT_SECTION:
923 926 return "Section";
924 927 break;
925 928 case STT_FILE:
926 929 return "File";
927 930 break;
928 931 case STT_COMMON:
929 932 return "Common data object";
930 933 break;
931 934 case STT_TLS:
932 935 return "Thread-local data object";
933 936 break;
934 937 case STT_NUM:
935 938 return "Number of defined types";
936 939 break;
937 940 case STT_LOOS:
938 941 return "Start of OS-specific";
939 942 break;
940 943 case STT_HIOS:
941 944 return "End of OS-specific";
942 945 break;
943 946 case STT_LOPROC:
944 947 return "Start of processor-specific";
945 948 break;
946 949 case STT_HIPROC:
947 950 return "End of processor-specific";
948 951 break;
949 952 default:
950 953 return "none";
951 954 break;
952 955 }
953 956 }
954 957 }
955 958 return "none";
956 959 }
957 960
958 961 quint64 ElfFile::getSymbolSize(int index)
959 962 {
960 963 if(this->e!=NULL)
961 964 {
962 965 if((index < this->symbols.count()) && (index>=0))
963 966 {
964 967 return symbols.at(index)->sym->st_size;
965 968 }
966 969 }
967 970 return 0;
968 971 }
969 972
970 973 QString ElfFile::getSymbolSectionName(int index)
971 974 {
972 975 if(this->e!=NULL)
973 976 {
974 977 if((index < this->symbols.count()) && (index>=0))
975 978 {
976 979 return getSectionName(symbols.at(index)->sym->st_shndx-1);
977 980 }
978 981 }
979 982 return "none";
980 983 }
981 984
982 985 int ElfFile::getSymbolSectionIndex(int index)
983 986 {
984 987 if(this->e!=NULL)
985 988 {
986 989 if((index < this->symbols.count()) && (index>=0))
987 990 {
988 991 return symbols.at(index)->sym->st_shndx;
989 992 }
990 993 }
991 994 return 0;
992 995 }
993 996
994 997 quint64 ElfFile::getSymbolAddress(int index)
995 998 {
996 999 if(this->e!=NULL)
997 1000 {
998 1001 if((index < this->symbols.count()) && (index>=0))
999 1002 {
1000 1003 return symbols.at(index)->sym->st_value;
1001 1004 }
1002 1005 }
1003 1006 return 0;
1004 1007 }
1005 1008
1006 1009 QString ElfFile::getSymbolLinkType(int index)
1007 1010 {
1008 1011 if(this->e!=NULL)
1009 1012 {
1010 1013 if(index < this->symbols.count())
1011 1014 {
1012 1015 int btype = GELF_ST_BIND(symbols.at(index)->sym->st_info);
1013 1016 switch(btype)
1014 1017 {
1015 1018 case STB_LOCAL:
1016 1019 return "Local";
1017 1020 break;
1018 1021 case STB_GLOBAL:
1019 1022 return "Global";
1020 1023 break;
1021 1024 case STB_WEAK:
1022 1025 return "Weak";
1023 1026 break;
1024 1027 case STB_NUM:
1025 1028 return "Number of defined types";
1026 1029 break;
1027 1030 case STB_LOOS:
1028 1031 return "Start of OS-specific";
1029 1032 break;
1030 1033 case STB_HIOS:
1031 1034 return "End of OS-specific";
1032 1035 break;
1033 1036 case STB_LOPROC:
1034 1037 return "Start of processor-specific";
1035 1038 break;
1036 1039 case STB_HIPROC:
1037 1040 return "End of processor-specific";
1038 1041 break;
1039 1042 default:
1040 1043 return "none";
1041 1044 break;
1042 1045 }
1043 1046 }
1044 1047 }
1045 1048 return "none";
1046 1049 }
1047 1050
1048 1051 bool ElfFile::isElf(const QString &File)
1049 1052 {
1050 1053 int file =0;
1051 1054 #ifdef _ELF_WINDOWS_
1052 1055 file = open(File.toStdString().c_str(),O_RDONLY|O_BINARY ,0);
1053 1056 #else
1054 1057 file = open(File.toStdString().c_str(),O_RDONLY ,0);
1055 1058 #endif
1056 1059 char Magic[4];
1057 1060 if(file!=-1)
1058 1061 {
1059 1062 size_t res = read(file,Magic,4);
1060 1063 close(file);
1061 1064 if((res==4) && (Magic[0]==0x7f) && (Magic[1]==0x45) && (Magic[2]==0x4c) && (Magic[3]==0x46))
1062 1065 {
1063 1066 return true;
1064 1067 }
1065 1068 }
1066 1069 return false;
1067 1070 }
1068 1071
1069 1072 bool ElfFile::toSrec(const QString &File)
1070 1073 {
1071 1074 return srecFile::toSrec(this->getFragments(),File);
1072 1075 }
1073 1076
1074 1077 bool ElfFile::toBinary(const QString &File)
1075 1078 {
1076 1079 return binaryFile::toBinary(getFragments(),File);
1077 1080 }
@@ -1,524 +1,527
1 1 /*------------------------------------------------------------------------------
2 2 -- This file is a part of the SocExplorer Software
3 3 -- Copyright (C) 2013, Plasma Physics Laboratory - CNRS
4 4 --
5 5 -- This program is free software; you can redistribute it and/or modify
6 6 -- it under the terms of the GNU General Public License as published by
7 7 -- the Free Software Foundation; either version 3 of the License, or
8 8 -- (at your option) any later version.
9 9 --
10 10 -- This program is distributed in the hope that it will be useful,
11 11 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
12 12 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 13 -- GNU General Public License for more details.
14 14 --
15 15 -- You should have received a copy of the GNU General Public License
16 16 -- along with this program; if not, write to the Free Software
17 17 -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 18 -------------------------------------------------------------------------------*/
19 19 /*-- Author : Alexis Jeandet
20 20 -- Mail : alexis.jeandet@lpp.polytechnique.fr
21 21 ----------------------------------------------------------------------------*/
22 22 #include "elfparser.h"
23 23 #include <sys/types.h>
24 24 #include <sys/stat.h>
25 25 #include <fcntl.h>
26 26 #include <unistd.h>
27 27
28 28 extern QString elfresolveMachine(Elf64_Half e_machine);
29 29
30 30
31 31 elfparser::elfparser()
32 32 {
33 33 this->opened = false;
34 34 this->type_elf = false;
35 35 this->elfFile = (int)NULL;
36 36 this->e = NULL;
37 37 }
38 38
39 39
40 40 int elfparser::setFilename(const QString &name)
41 41 {
42 42 this->closeFile();
43 43 if(elf_version(EV_CURRENT)==EV_NONE)return 0;
44 44 #ifdef _ELF_WINDOWS_
45 45 this->elfFile = open(name.toStdString().c_str(),O_RDONLY|O_BINARY ,0);
46 46 #else
47 47 this->elfFile = open(name.toStdString().c_str(),O_RDONLY ,0);
48 48 #endif
49 49 if(this->elfFile==(int)NULL)return 0;
50 50 this->e = elf_begin(this->elfFile,ELF_C_READ,NULL);
51 51 if(this->e==NULL)return 0;
52 52 this->ek = elf_kind(this->e);
53 53 gelf_getehdr (this->e, &this->ehdr );
54 54 elf_getshdrstrndx (this->e, &this->shstrndx);
55 55 this->updateSegments();
56 56 this->updateSections();
57 57 return 1;
58 58 }
59 59
60 60
61 61 int elfparser::closeFile()
62 62 {
63 63 if(this->elfFile!=(int)NULL)
64 64 {
65 65 if(this->e!=NULL)
66 66 {
67 67 elf_end(this->e);
68 68 this->e = NULL;
69 69 }
70 70 close(this->elfFile);
71 71 this->elfFile = (int)NULL;
72 72 }
73 73 return 0;
74 74 }
75 75
76 76 QString elfparser::getClass()
77 77 {
78 78 if(this->e!=NULL)
79 79 {
80 80 int eclass = gelf_getclass(this->e);
81 81 if(eclass==ELFCLASS32)return "ELF32";
82 82 if(eclass==ELFCLASS64)return "ELF64";
83 83 }
84 84 return "none";
85 85 }
86 86
87 87
88 88 bool elfparser::isopened()
89 89 {
90 90 return this->opened;
91 91 }
92 92
93 93
94 94 bool elfparser::iself()
95 95 {
96 96 return this->type_elf;
97 97 }
98 98
99 99
100 100 QString elfparser::getArchitecture()
101 101 {
102 102 if(this->e!=NULL)
103 103 {
104 104 return elfresolveMachine(this->ehdr.e_machine);
105 105 }
106 106 return "";
107 107 }
108 108
109 109
110 110 QString elfparser::getType()
111 111 {
112 112 QString kind("");
113 113 if(this->e!=NULL)
114 114 {
115 115 switch(this->ek)
116 116 {
117 117 case ELF_K_AR:
118 118 kind = "Archive";
119 119 break;
120 120 case ELF_K_ELF:
121 121 kind = "Elf";
122 122 break;
123 123 case ELF_K_COFF:
124 124 kind = "COFF";
125 125 break;
126 126 case ELF_K_NUM:
127 127 kind = "NUM";
128 128 break;
129 129 case ELF_K_NONE:
130 130 kind = "Data";
131 131 break;
132 132 default:
133 133 kind = "Unknow";
134 134 break;
135 135 }
136 136 }
137 137 return kind;
138 138 }
139 139
140 140 QString elfparser::getEndianness()
141 141 {
142 142 if(this->e!=NULL)
143 143 {
144 144 if(this->ehdr.e_ident[EI_DATA]==ELFDATA2LSB)return "2's complement, little endian";
145 145 if(this->ehdr.e_ident[EI_DATA]==ELFDATA2MSB)return "2's complement, big endian";
146 146 }
147 147 return "none";
148 148 }
149 149
150 150 QString elfparser::getABI()
151 151 {
152 152 if(this->e!=NULL)
153 153 {
154 154 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_NONE)return "UNIX System V ABI";
155 155 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_SYSV)return "Alias";
156 156 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_HPUX)return "HP-UX";
157 157 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_NETBSD)return "NetBSD";
158 158 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_LINUX)return "Object uses GNU ELF extensions";
159 159 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_SOLARIS)return "Sun Solaris";
160 160 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_AIX)return "IBM AIX";
161 161 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_IRIX)return "SGI Irix";
162 162 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_FREEBSD)return "FreeBSD";
163 163 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_TRU64)return "Compaq TRU64 UNIX";
164 164 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_MODESTO)return " Novell Modesto";
165 165 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_OPENBSD)return "OpenBSD";
166 166 #ifdef ELFOSABI_ARM_AEABI
167 167 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_ARM_AEABI)return "ARM EABI";
168 168 #endif
169 169 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_ARM)return "ARM";
170 170 if(this->ehdr.e_ident[EI_OSABI]==ELFOSABI_STANDALONE)return "Standalone (embedded) application";
171 171 }
172 172 return "none";
173 173 }
174 174
175 175
176 176 qint64 elfparser::getVersion()
177 177 {
178 178 if(this->e!=NULL)
179 179 {
180 180 return this->ehdr.e_version;
181 181 }
182 182 return -1;
183 183 }
184 184
185 185 qint64 elfparser::getEntryPointAddress()
186 186 {
187 187 if(this->e!=NULL)
188 188 {
189 189 return this->ehdr.e_entry;
190 190 }
191 191 return -1;
192 192 }
193 193
194 194
195 195 int elfparser::getSectioncount()
196 196 {
197 197 return (int)this->SectionCount;
198 198 }
199 199
200 200
201 201 int elfparser::getSegmentcount()
202 202 {
203 203 return (int)this->SegmentCount;
204 204 }
205 205
206 206
207 207 QString elfparser::getSegmentType(int index)
208 208 {
209 209 QString type("");
210 210 if(this->e!=NULL)
211 211 {
212 212 if(index < this->Segments.count())
213 213 {
214 214 switch(this->Segments.at(index)->p_type)
215 215 {
216 216 case PT_NULL:
217 217 type = "Program header table entry unused";
218 218 break;
219 219 case PT_LOAD:
220 220 type = "Loadable program segment";
221 221 break;
222 222 case PT_DYNAMIC :
223 223 type = "Dynamic linking information";
224 224 break;
225 225 case PT_INTERP:
226 226 type ="Program interpreter";
227 227 break;
228 228 case PT_NOTE:
229 229 type = "Auxiliary information";
230 230 break;
231 231 case PT_SHLIB:
232 232 type = "Reserved";
233 233 break;
234 234 case PT_PHDR:
235 235 type = "Entry for header table itself";
236 236 break;
237 237 case PT_TLS:
238 238 type = "Thread-local storage segment";
239 239 break;
240 240 case PT_NUM:
241 241 type = "Number of defined types";
242 242 break;
243 243 case PT_LOOS:
244 244 type = "Start of OS-specific";
245 245 break;
246 246 case PT_SUNWSTACK:
247 247 type = "Stack segment";
248 248 break;
249 249 case PT_LOPROC:
250 250 type = "Start of processor-specific";
251 251 break;
252 252 case PT_HIPROC:
253 253 type = "End of processor-specific";
254 254 break;
255 255 default:
256 256 type = "Unknow Section Type";
257 257 break;
258 258 }
259 259 }
260 260 }
261 261
262 262 return type;
263 263 }
264 264
265 265
266 266 qint64 elfparser::getSegmentOffset(int index)
267 267 {
268 268 qint64 Offset=-1;
269 269 if(this->e!=NULL)
270 270 {
271 271 if(index < this->Segments.count())
272 272 {
273 273 Offset = (qint64)this->Segments.at(index)->p_offset;
274 274 }
275 275 }
276 276 return Offset;
277 277 }
278 278
279 279
280 280 qint64 elfparser::getSegmentVaddr(int index)
281 281 {
282 282 int64_t Vaddr = 0;
283 283 if(this->e!=NULL)
284 284 {
285 285 if(index < this->Segments.count())
286 286 {
287 287 Vaddr = (int64_t)this->Segments.at(index)->p_vaddr;
288 288 }
289 289 }
290 290 return Vaddr;
291 291 }
292 292
293 293
294 294 qint64 elfparser::getSegmentPaddr(int index)
295 295 {
296 296 int64_t Paddr=0;
297 297 if(this->e!=NULL)
298 298 {
299 299 if(index < this->Segments.count())
300 300 {
301 301 Paddr = (int64_t)this->Segments.at(index)->p_paddr;
302 302 }
303 303 }
304 304 return Paddr;
305 305 }
306 306
307 307 qint64 elfparser::getSectionPaddr(int index)
308 308 {
309 309 int64_t Paddr=0;
310 310 if(this->e!=NULL)
311 311 {
312 312 if(index < this->sections.count())
313 313 {
314 314 Paddr = (int64_t)this->sections.at(index)->section_header->sh_addr;
315 315 }
316 316 }
317 317 return Paddr;
318 318 }
319 319
320 320
321 321 qint64 elfparser::getSegmentFilesz(int index)
322 322 {
323 323 int64_t FileSz=0;
324 324 if(this->e!=NULL)
325 325 {
326 326 if(index < this->Segments.count())
327 327 {
328 328 FileSz = (int64_t)this->Segments.at(index)->p_filesz;
329 329 }
330 330 }
331 331 return FileSz;
332 332 }
333 333
334 334 qint64 elfparser::getSectionDatasz(int index)
335 335 {
336 336 int64_t DataSz=0;
337 337 if(this->e!=NULL)
338 338 {
339 339 if(index < this->sections.count())
340 340 {
341 341 DataSz = (int64_t)this->sections.at(index)->data->d_size;
342 342 }
343 343 }
344 344 return DataSz;
345 345 }
346 346
347 347 bool elfparser::getSectionData(int index, char **buffer)
348 348 {
349 349 if(this->e!=NULL)
350 350 {
351 351 if(index < this->sections.count())
352 352 {
353 353 *buffer = (char *)this->sections.at(index)->data->d_buf;
354 354 return true;
355 355 }
356 356 }
357 357 return false;
358 358 }
359 359
360 360
361 361 qint64 elfparser::getSegmentMemsz(int index)
362 362 {
363 363 int64_t MemSz=0;
364 364 if(this->e!=NULL)
365 365 {
366 366 if(index < this->Segments.count())
367 367 {
368 368 MemSz = (int64_t)this->Segments.at(index)->p_memsz;
369 369 }
370 370 }
371 371 return MemSz;
372 372 }
373 373
374 374 qint64 elfparser::getSectionMemsz(int index)
375 375 {
376 376 int64_t MemSz=0;
377 377 if(this->e!=NULL)
378 378 {
379 379 if(index < this->sections.count())
380 380 {
381 381 MemSz = (int64_t)this->sections.at(index)->section_header->sh_size;
382 382 }
383 383 }
384 384 return MemSz;
385 385 }
386 386
387 387
388 388 QString elfparser::getSegmentFlags(int index)
389 389 {
390 390 QString flags("");
391 391 if(this->e!=NULL)
392 392 {
393 393 if(index < this->Segments.count())
394 394 {
395 395 if((this->Segments.at(index)->p_flags&PF_X) == PF_X)flags+="x";
396 396 if((this->Segments.at(index)->p_flags&PF_W) == PF_W)flags+="w";
397 397 if((this->Segments.at(index)->p_flags&PF_R) == PF_R)flags+="r";
398 398 if((this->Segments.at(index)->p_flags&PF_MASKOS) == PF_MASKOS)flags+=" OS-specific";
399 399 if((this->Segments.at(index)->p_flags&PF_MASKPROC) == PF_MASKPROC)flags+=" Processor-specific";
400 400 }
401 401 }
402 402 return flags;
403 403 }
404 404
405 405
406 406 QString elfparser::getSectionName(int index)
407 407 {
408 408 char* nameChr = elf_strptr(this->e , this->shstrndx , this->sections.at(index)->section_header->sh_name);
409 409 return QString(nameChr);
410 410 }
411 411
412 412
413 413 void elfparser::updateSections()
414 414 {
415 415 for(int i=0;i<this->sections.count();i++)
416 416 {
417 417 delete this->sections.at(i);
418 418 }
419 419 this->sections.clear();
420 420 this->scn = elf_nextscn (this->e , NULL );
421 421 this->SectionCount = 0;
422 422 while( this->scn != NULL )
423 423 {
424 424 GElf_Shdr* shdr = (GElf_Shdr*)malloc(sizeof(GElf_Shdr));
425 425 gelf_getshdr ( this->scn , shdr );
426 426 Elf_Data* data = elf_getdata(this->scn, NULL);
427 427 this->sections.append(new Elf_Section(data,shdr));
428 428 this->SectionCount+=1;
429 429 this->scn = elf_nextscn(e , scn);
430 430 }
431 431 }
432 432
433 433
434 434 void elfparser::updateSegments()
435 435 {
436 elf_getphdrnum (this->e , &this->SegmentCount);
437 436 for(int i=0;i<this->Segments.count();i++)
438 437 {
439 438 free(this->Segments.at(i));
440 439 }
441 440 this->Segments.clear();
442 for(int i=0;i<(int)this->SegmentCount;i++)
441 this->SegmentCount = 0;
442 GElf_Phdr* header=(GElf_Phdr*)malloc(sizeof(GElf_Phdr));
443 while ( header == gelf_getphdr(this->e ,this->SegmentCount, header ))
443 444 {
444 GElf_Phdr* header=(GElf_Phdr*)malloc(sizeof(GElf_Phdr));
445 gelf_getphdr (this->e , i , header );
446 445 this->Segments.append(header);
446 this->SegmentCount++;
447 header=(GElf_Phdr*)malloc(sizeof(GElf_Phdr));
447 448 }
449 this->SegmentCount = this->Segments.count();
450 free(header);
448 451 }
449 452
450 453
451 454
452 455
453 456
454 457 QString elfparser::getSectionType(int index)
455 458 {
456 459 QString type("");
457 460 if(this->e!=NULL)
458 461 {
459 462 if(index < this->Segments.count())
460 463 {
461 464 switch(this->Segments.at(index)->p_type)
462 465 {
463 466 case SHT_NULL : type = "Section header table entry unused"; break;
464 467 case SHT_PROGBITS : type = "Program data"; break;
465 468 case SHT_SYMTAB : type = "Symbol table"; break;
466 469 case SHT_STRTAB : type = "String table"; break;
467 470 case SHT_RELA : type = "Relocation entries with addends"; break;
468 471 case SHT_HASH : type = "Symbol hash table"; break;
469 472 case SHT_DYNAMIC : type = "Dynamic linking information"; break;
470 473 case SHT_NOTE : type = "Notes"; break;
471 474 case SHT_NOBITS :type = "Program space with no data (bss)"; break;
472 475 case SHT_REL :type = "Relocation entries, no addends"; break;
473 476 case SHT_SHLIB : type = "Reserved"; break;
474 477 case SHT_DYNSYM : type = "Dynamic linker symbol table"; break;
475 478 case SHT_INIT_ARRAY : type = "Array of constructors"; break;
476 479 case SHT_FINI_ARRAY : type = "Array of destructors"; break;
477 480 case SHT_PREINIT_ARRAY : type = "Array of pre-constructors"; break;
478 481 case SHT_GROUP : type = "Section group"; break;
479 482 case SHT_SYMTAB_SHNDX : type = "Extended section indeces"; break;
480 483 case SHT_NUM : type = "Number of defined types. "; break;
481 484 case SHT_LOOS : type = "Start OS-specific. "; break;
482 485 case SHT_LOSUNW : type = "Sun-specific low bound. "; break;
483 486 case SHT_SUNW_COMDAT : type = " "; break;
484 487 case SHT_SUNW_syminfo : type = " "; break;
485 488 case SHT_GNU_verdef : type = "Version definition section. "; break;
486 489 case SHT_GNU_verneed : type = "Version needs section. "; break;
487 490 case SHT_GNU_versym : type = "Version symbol table. "; break;
488 491 case SHT_LOPROC : type = "Start of processor-specific"; break;
489 492 case SHT_HIPROC : type = "End of processor-specific"; break;
490 493 case SHT_HIUSER : type = "End of application-specific"; break;
491 494 }
492 495 }
493 496 }
494 497 return type;
495 498 }
496 499
497 500 bool elfparser::isElf(const QString &File)
498 501 {
499 502 int file =0;
500 503 #ifdef _ELF_WINDOWS_
501 504 file = open(File.toStdString().c_str(),O_RDONLY|O_BINARY ,0);
502 505 #else
503 506 file = open(File.toStdString().c_str(),O_RDONLY ,0);
504 507 #endif
505 508 char Magic[4];
506 509 if(file!=-1)
507 510 {
508 511 size_t res = read(file,Magic,4);
509 512 close(file);
510 513 if((res == 4) && (Magic[0]==0x7f) && (Magic[1]==0x45) && (Magic[2]==0x4c) && (Magic[3]==0x46))
511 514 {
512 515 return true;
513 516 }
514 517 }
515 518 return false;
516 519 }
517 520
518 521
519 522
520 523
521 524
522 525
523 526
524 527
General Comments 0
You need to be logged in to leave comments. Login now