1# coding=utf-8 2# Copyright 2018 Sascha Schirra 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions are met: 6# 7# 1. Redistributions of source code must retain the above copyright notice, this 8# list of conditions and the following disclaimer. 9# 10# 2. Redistributions in binary form must reproduce the above copyright notice, 11# this list of conditions and the following disclaimer in the documentation 12# and/or other materials provided with the distribution. 13# 14# 3. Neither the name of the copyright holder nor the names of its contributors 15# may be used to endorse or promote products derived from this software without 16# specific prior written permission. 17# 18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" A ND 19# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 30from .enum import Enum 31from .binary import * 32 33####################### Constants ############################ 34 35class ET(Enum): 36 NONE = 0x0 37 REL = 0x1 38 EXEC = 0x2 39 DYN = 0x3 40 CORE = 0x4 41 LOOS = 0xfe00 42 HIOS = 0xfeff 43 LOPROC = 0xff00 44 HIPROC = 0xffff 45 46 47class EM(Enum): 48 NONE = 0 # No machine 49 M32 = 1 # AT&T WE 32100 50 SPARC = 2 # SPARC 51 INTEL_386 = 3 # Intel 80386 52 MOTOROLA_68k = 4 # Motorola 68000 53 MOTOROLA_88K = 5 # Motorola 88000 54 INTEL_80860 = 7 # Intel 80860 55 MIPS = 8 # MIPS RS3000 56 S370 = 9 57 MIPS_RS3_LE = 10 58 59 PARISC = 15 60 VPP500 = 17 61 SPARC32PLUS = 18 62 INTEL_80960 = 19 63 PPC = 20 64 PPC64 = 21 65 S390 = 22 66 67 V800 = 36 68 FR20 = 37 69 RH32 = 38 70 RCE = 39 71 ARM = 40 72 FAKE_ALPHA = 41 73 SH = 42 74 SPARCV9 = 43 75 TRICORE = 44 76 ARC = 45 77 H8_300 = 46 78 H8_300H = 47 79 H8S = 48 80 H8_500 = 49 81 IA_64 = 50 82 MIPS_X = 51 83 COLDFIRE = 52 84 MOTOROLA_68HC12 = 53 85 MMA = 54 86 PCP = 55 87 NCPU = 56 88 NDR1 = 57 89 STARCORE = 58 90 ME16 = 59 91 ST100 = 60 92 TINYJ = 61 93 X86_64 = 62 94 FX66 = 66 95 ST9PLUS = 67 96 ST7 = 68 97 MOTOROLA_68HC16 = 69 98 MOTOROLA_68HC11 = 70 99 MOTOROLA_68HC08 = 71 100 MOTOROLA_68HC05 = 72 101 SVX = 73 102 ST19 = 74 103 VAX = 75 104 CRIS = 76 105 JAVELIN = 77 106 FIREPATH = 78 107 ZSP = 79 108 MMIX = 80 109 HUANY = 81 110 PRISM = 82 111 AVR = 83 112 FR30 = 84 113 D10V = 85 114 D30V = 86 115 V850 = 87 116 M32R = 88 117 MN10300 = 89 118 MN10200 = 90 119 PJ = 91 120 OPENRISC = 92 121 ARC_A5 = 93 122 XTENSA = 94 123 NUM = 95 124 ARM64 = 183 125 126 127class EI(Enum): 128 MAG0 = 0x0 129 MAG1 = 0x1 130 MAG2 = 0x2 131 MAG3 = 0x3 132 CLASS = 0x4 133 DATA = 0x5 134 VERSION = 0x6 135 OSABI = 0x7 136 ABIVERSION = 0x8 137 PAD = 0x9 138 NIDENT = 0xf 139 140 141class ELFOSABI(Enum): 142 SYSV = 0 143 HPUX = 1 144 STANDALONE = 255 145 146 147class ELFCLASS(Enum): 148 NONE = 0 149 BITS_32 = 1 150 BITS_64 = 2 151 152 153class ELFDATA(Enum): 154 NONE = 0 155 LSB = 1 156 MSB = 2 157 158 159class SHN(Enum): 160 UNDEF = 0 161 LOPROC = 0xff00 162 HIPROC = 0xff1f 163 LOOS = 0xff20 164 HIOS = 0xff3f 165 ABS = 0xfff1 166 COMMON = 0xfff2 167 HIRESERVE = 0xffff 168 169class SHF(Enum): 170 WRITE = 0x1 171 ALLOC = 0x2 172 EXECINSTR = 0x4 173 MASKPROC = 0xf0000000 174 175 176class SHT(Enum): 177 NULL = 0x0 178 PROGBITS = 0x1 179 SYMTAB = 0x2 180 STRTAB = 0x3 181 RELA = 0x4 182 HASH = 0x5 183 DYNAMIC = 0x6 184 NOTE = 0x7 185 NOBITS = 0x8 186 REL = 0x9 187 SHLIB = 0xa 188 DYNSYM = 0xb 189 INIT_ARRAY = 0xe 190 FINI_ARRAY = 0xf 191 PREINIT_ARRAY = 0x10 192 GROUP = 0x11 193 SYMTAB_SHNDX = 0x12 194 NUM = 0x13 195 LOOS = 0x60000000 196 GNU_HASH = 0x6ffffff6 197 GNU_LIBLIST = 0x6ffffff7 198 CHECKSUM = 0x6ffffff8 199 LOSUNW = 0x6ffffffa 200 SUNW_COMDAT = 0x6ffffffb 201 SUNW_syminfo = 0x6ffffffc 202 GNU_verdef = 0x6ffffffd 203 GNU_verneed = 0x6ffffffe 204 HIOS = 0x6fffffff 205 LOPROC = 0x70000000 206 HIPROC = 0x7fffffff 207 LOUSER = 0x80000000 208 HIUSER = 0x8fffffff 209 210 211class STT(Enum): 212 NOTYPE = 0 213 OBJECT = 1 214 FUNC = 2 215 SECTION = 3 216 FILE = 4 217 COMMON = 5 218 TLS = 6 219 NUM = 7 220 LOOS = 10 221 HIOS = 12 222 LOPROC = 13 223 HIPROC = 15 224 225 226class STB(Enum): 227 228 LOCAL = 0 229 GLOBAL = 1 230 WEAK = 2 231 NUM = 3 232 LOOS = 10 233 HIOS = 12 234 LOPROC = 13 235 HIPROC = 15 236 237class STV(Enum): 238 DEFAULT = 0 239 INTERNAL = 1 240 HIDDEN = 2 241 PROTECTED = 3 242 EXPORTED = 4 243 SINGLETON = 5 244 ELIMINATE = 6 245 246 247 248class PT(Enum): 249 NULL = 0 250 LOAD = 1 251 DYNAMIC = 2 252 INTERP = 3 253 NOTE = 4 254 SHLIB = 5 255 PHDR = 6 256 TLS = 7 257 NUM = 8 258 LOPROC = 0x70000000 259 HIPROC = 0x7fffffff 260 261 GNU_EH_FRAME = 0x6474e550 262 GNU_STACK = 0x6474e551 263 GNU_RELRO = 0x6474e552 264 265 266class R_386(Enum): 267 NONE = 0 268 R_32 = 1 269 PC32 = 2 270 GOT32 = 3 271 PLT32 = 4 272 COPY = 5 273 GLOB_DAT = 6 274 JMP_SLOT = 7 275 RELATIVE = 8 276 GOTOFF = 9 277 GOTPC = 10 278 279 TLS_TPOFF = 14 280 TLS_IE = 15 281 TLS_GOTIE = 16 282 TLS_LE = 17 283 TLS_GD = 18 284 TLS_LDM = 19 285 R16 = 20 286 PC16 = 21 287 R8 = 22 288 PC8 = 23 289 TLS_GD_32 = 24 290 TLS_GD_PUSH = 25 291 TLS_GD_CALL = 26 292 TLS_GD_POP = 27 293 TLS_LDM_32 = 28 294 TLS_LDM_PUSH = 29 295 TLS_LDM_CALL = 30 296 TLS_LDM_POP = 31 297 TLS_LDO_32 = 32 298 TLS_IE_32 = 33 299 TLS_LE_32 = 34 300 TLS_DTPMOD32 = 35 301 TLS_DTPOFF32 = 36 302 TLS_TPOFF32 = 37 303 NUM = 38 304 305 306class PF(Enum): 307 308 READ = 4 309 WRITE = 2 310 EXEC = 1 311 312 def shortString(self, perm): 313 toReturn = '' 314 toReturn += 'R' if perm & int(self.READ) > 0 else ' ' 315 toReturn += 'W' if perm & int(self.WRITE) > 0 else ' ' 316 toReturn += 'E' if perm & int(self.EXEC) > 0 else ' ' 317 318 return toReturn 319 320class DT(Enum): 321 NULL = 0 322 NEEDED = 1 323 PLTRELSZ = 2 324 PLTGOT = 3 325 HASH = 4 326 STRTAB = 5 327 SYMTAB = 6 328 RELA = 7 329 RELASZ = 8 330 RELAENT = 9 331 STRSZ = 10 332 SYMENT = 11 333 INIT = 12 334 FINI = 13 335 SONAME = 14 336 RPATH = 15 337 SYMBOLIC = 16 338 REL = 17 339 RELSZ = 18 340 RELENT = 19 341 PLTREL = 20 342 DEBUG = 21 343 TEXTREL = 22 344 JMPREL = 23 345 BIND_NOW = 24 346 INIT_ARRAY = 25 347 FINI_ARRAY = 26 348 INIT_ARRAYSZ = 27 349 FINI_ARRAYSZ = 28 350 RUNPATH = 29 351 FLAGS = 30 352 ENCODING = 31 353 PREINIT_ARRAY = 32 354 PREINIT_ARRAYSZ = 33 355 MAXPOSTAGS = 34 356 LOOS = 0x6000000d 357 #SUNW_AUXILIARY = 0x6000000d 358 SUNW_RTLDINF = 0x6000000e 359 #SUNW_FILTER = 0x6000000e 360 SUNW_CAP = 0x60000010 361 SUNW_SYMTAB = 0x60000011 362 SUNW_SYMSZ = 0x60000012 363 SUNW_ENCODING = 0x60000013 364 #SUNW_SORTENT = 0x60000013 365 SUNW_SYMSORT = 0x60000014 366 SUNW_SYMSORTSZ = 0x60000015 367 SUNW_TLSSORT = 0x60000016 368 SUNW_TLSSORTSZ = 0x60000017 369 SUNW_CAPINFO = 0x60000018 370 SUNW_STRPAD = 0x60000019 371 SUNW_CAPCHAIN = 0x6000001a 372 SUNW_LDMACH = 0x6000001b 373 SUNW_CAPCHAINENT = 0x6000001d 374 SUNW_CAPCHAINSZ = 0x6000001f 375 HIOS = 0x6ffff000 376 VALRNGLO = 0x6ffffd00 377 CHECKSUM = 0x6ffffdf8 378 PLTPADSZ = 0x6ffffdf9 379 MOVEENT = 0x6ffffdfa 380 MOVESZ = 0x6ffffdfb 381 POSFLAG_1 = 0x6ffffdfd 382 SYMINSZ = 0x6ffffdfe 383 SYMINENT = 0x6ffffdff 384 #VALRNGHI = 0x6ffffdff 385 ADDRRNGLO = 0x6ffffe00 386 GNU_HASH = 0x6ffffef5 387 TLSDESC_PLT = 0x6ffffef6 388 TLSDESC_GOT = 0x6ffffef7 389 GNU_CONFLICT = 0x6ffffef8 390 GNU_LIBLIST = 0x6ffffef9 391 CONFIG = 0x6ffffefa 392 DEPAUDIT = 0x6ffffefb 393 AUDIT = 0x6ffffefc 394 PLTPAD = 0x6ffffefd 395 MOVETAB = 0x6ffffefe 396 SYMINFO = 0x6ffffeff 397 #ADDRRNGHI = 0x6ffffeff 398 VERSYM = 0x6ffffff0 399 RELACOUNT = 0x6ffffff9 400 RELCOUNT = 0x6ffffffa 401 FLAGS_1 = 0x6ffffffb 402 VERDEF = 0x6ffffffc 403 VERDEFNUM = 0x6ffffffd 404 VERNEED = 0x6ffffffe 405 VERNEEDNUM = 0x6fffffff 406 LOPROC = 0x70000000 407 SPARC_REGISTER = 0x70000001 408 AUXILIARY = 0x7ffffffd 409 USED = 0x7ffffffe 410 #FILTER = 0x7fffffff 411 HIPROC = 0x7fffffff 412 413########################### LSB 32 BIT Structures ########################### 414 415LSB_32_R_SYM = lambda i: i >> 8 416LSB_32_R_TYPE = lambda i: i & 0xff 417 418 419class LSB_32_EHDR(LittleEndianStructure): 420 _fields_ = [('e_ident', c_ubyte * 16), 421 ('e_type', c_ushort), 422 ('e_machine', c_ushort), 423 ('e_version', c_uint), 424 ('e_entry', c_uint), 425 ('e_phoff', c_uint), 426 ('e_shoff', c_uint), 427 ('e_flags', c_uint), 428 ('e_ehsize', c_ushort), 429 ('e_phentsize', c_ushort), 430 ('e_phnum', c_ushort), 431 ('e_shentsize', c_ushort), 432 ('e_shnum', c_ushort), 433 ('e_shstrndx', c_ushort)] 434 435 436class LSB_32_SHDR(LittleEndianStructure): 437 _fields_ = [('sh_name', c_uint), 438 ('sh_type', c_uint), 439 ('sh_flags', c_uint), 440 ('sh_addr', c_uint), 441 ('sh_offset', c_uint), 442 ('sh_size', c_uint), 443 ('sh_link', c_uint), 444 ('sh_info', c_uint), 445 ('sh_addralign', c_uint), 446 ('sh_entsize', c_uint) 447 ] 448 449 450class LSB_32_SYM(LittleEndianStructure): 451 _fields_ = [('st_name', c_uint), 452 ('st_value', c_uint), 453 ('st_size', c_uint), 454 ('st_info', c_ubyte), 455 ('st_other', c_ubyte), 456 ('st_shndx', c_ushort) 457 ] 458 459 460class LSB_32_REL(LittleEndianStructure): 461 _fields_ = [('r_offset', c_uint), 462 ('r_info', c_uint)] 463 464 465class LSB_32_RELA(LittleEndianStructure): 466 _fields_ = [('r_offset', c_uint), 467 ('r_info', c_uint), 468 ('r_addend', c_int) 469 ] 470 471 472class LSB_32_PHDR(LittleEndianStructure): 473 _fields_ = [('p_type', c_uint), 474 ('p_offset', c_uint), 475 ('p_vaddr', c_uint), 476 ('p_paddr', c_uint), 477 ('p_filesz', c_uint), 478 ('p_memsz', c_uint), 479 ('p_flags', c_uint), 480 ('p_align', c_uint) 481 ] 482 483class LSB_32_DYN(LittleEndianStructure): 484 _fields_ = [('d_tag', c_uint), 485 ('d_un', c_uint) 486 ] 487 488class LSB_32(): 489 PHDR = LSB_32_PHDR 490 EHDR = LSB_32_EHDR 491 SHDR = LSB_32_SHDR 492 REL = LSB_32_REL 493 RELA = LSB_32_RELA 494 SYM = LSB_32_SYM 495 DYN = LSB_32_DYN 496 R_SYM = staticmethod(LSB_32_R_SYM) 497 R_TYPE = staticmethod(LSB_32_R_TYPE) 498 499########################### MSB 32 BIT Structures ########################### 500 501MSB_32_R_SYM = lambda i: i >> 8 502MSB_32_R_TYPE = lambda i: i & 0xff 503 504 505class MSB_32_EHDR(BigEndianStructure): 506 _fields_ = [('e_ident', c_ubyte * 16), 507 ('e_type', c_ushort), 508 ('e_machine', c_ushort), 509 ('e_version', c_uint), 510 ('e_entry', c_uint), 511 ('e_phoff', c_uint), 512 ('e_shoff', c_uint), 513 ('e_flags', c_uint), 514 ('e_ehsize', c_ushort), 515 ('e_phentsize', c_ushort), 516 ('e_phnum', c_ushort), 517 ('e_shentsize', c_ushort), 518 ('e_shnum', c_ushort), 519 ('e_shstrndx', c_ushort)] 520 521 522class MSB_32_SHDR(BigEndianStructure): 523 _fields_ = [('sh_name', c_uint), 524 ('sh_type', c_uint), 525 ('sh_flags', c_uint), 526 ('sh_addr', c_uint), 527 ('sh_offset', c_uint), 528 ('sh_size', c_uint), 529 ('sh_link', c_uint), 530 ('sh_info', c_uint), 531 ('sh_addralign', c_uint), 532 ('sh_entsize', c_uint) 533 ] 534 535 536class MSB_32_SYM(BigEndianStructure): 537 _fields_ = [('st_name', c_uint), 538 ('st_value', c_uint), 539 ('st_size', c_uint), 540 ('st_info', c_ubyte), 541 ('st_other', c_ubyte), 542 ('st_shndx', c_ushort) 543 ] 544 545 546class MSB_32_REL(BigEndianStructure): 547 _fields_ = [('r_offset', c_uint), 548 ('r_info', c_uint)] 549 550 551class MSB_32_RELA(BigEndianStructure): 552 _fields_ = [('r_offset', c_uint), 553 ('r_info', c_uint), 554 ('r_addend', c_int) 555 ] 556 557 558class MSB_32_PHDR(BigEndianStructure): 559 _fields_ = [('p_type', c_uint), 560 ('p_offset', c_uint), 561 ('p_vaddr', c_uint), 562 ('p_paddr', c_uint), 563 ('p_filesz', c_uint), 564 ('p_memsz', c_uint), 565 ('p_flags', c_uint), 566 ('p_align', c_uint) 567 ] 568 569class MSB_32_DYN(BigEndianStructure): 570 _fields_ = [('d_tag', c_uint), 571 ('d_un', c_uint) 572 ] 573 574class MSB_32(): 575 PHDR = MSB_32_PHDR 576 EHDR = MSB_32_EHDR 577 SHDR = MSB_32_SHDR 578 REL = MSB_32_REL 579 RELA = MSB_32_RELA 580 SYM = MSB_32_SYM 581 DYN = MSB_32_DYN 582 R_SYM = staticmethod(MSB_32_R_SYM) 583 R_TYPE = staticmethod(MSB_32_R_TYPE) 584 585########################### 64 BIT Types ########################### 586 587Elf64_Addr = c_ulonglong 588Elf64_Off = c_ulonglong 589Elf64_Half = c_ushort 590Elf64_Word = c_uint 591Elf64_Sword = c_int 592Elf64_Xword = c_ulonglong 593Elf64_Sxword = c_longlong 594uchar = c_ubyte 595 596########################### LSB 64 BIT Structures ########################### 597 598LSB_64_R_SYM = lambda i: i >> 32 599LSB_64_R_TYPE = lambda i: i & 0xffffffff 600 601 602class LSB_64_EHDR(LittleEndianStructure): 603 _fields_ = [('e_ident', uchar * 16), 604 ('e_type', Elf64_Half), 605 ('e_machine', Elf64_Half), 606 ('e_version', Elf64_Word), 607 ('e_entry', Elf64_Addr), 608 ('e_phoff', Elf64_Off), 609 ('e_shoff', Elf64_Off), 610 ('e_flags', Elf64_Word), 611 ('e_ehsize', Elf64_Half), 612 ('e_phentsize', Elf64_Half), 613 ('e_phnum', Elf64_Half), 614 ('e_shentsize', Elf64_Half), 615 ('e_shnum', Elf64_Half), 616 ('e_shstrndx', Elf64_Half) 617 ] 618 619 620class LSB_64_SHDR(LittleEndianStructure): 621 _fields_ = [('sh_name', Elf64_Word), 622 ('sh_type', Elf64_Word), 623 ('sh_flags', Elf64_Xword), 624 ('sh_addr', Elf64_Addr), 625 ('sh_offset', Elf64_Off), 626 ('sh_size', Elf64_Xword), 627 ('sh_link', Elf64_Word), 628 ('sh_info', Elf64_Word), 629 ('sh_addralign', Elf64_Xword), 630 ('sh_entsize', Elf64_Xword) 631 ] 632 633 634class LSB_64_SYM(LittleEndianStructure): 635 _fields_ = [('st_name', Elf64_Word), 636 ('st_info', uchar), 637 ('st_other', uchar), 638 ('st_shndx', Elf64_Half), 639 ('st_value', Elf64_Addr), 640 ('st_size', Elf64_Xword) 641 ] 642 643 644class LSB_64_REL(LittleEndianStructure): 645 _fields_ = [('r_offset', Elf64_Addr), 646 ('r_info', Elf64_Xword)] 647 648 649class LSB_64_RELA(LittleEndianStructure): 650 _fields_ = [('r_offset', Elf64_Addr), 651 ('r_info', Elf64_Xword), 652 ('r_addend', Elf64_Sxword) 653 ] 654 655 656class LSB_64_PHDR(LittleEndianStructure): 657 _fields_ = [('p_type', Elf64_Word), 658 ('p_flags', Elf64_Word), 659 ('p_offset', Elf64_Off), 660 ('p_vaddr', Elf64_Addr), 661 ('p_paddr', Elf64_Addr), 662 ('p_filesz', Elf64_Xword), 663 ('p_memsz', Elf64_Xword), 664 ('p_align', Elf64_Xword) 665 ] 666 667class LSB_64_DYN(LittleEndianStructure): 668 _fields_ = [('d_tag', Elf64_Xword), 669 ('d_un', Elf64_Xword) 670 ] 671 672class LSB_64(): 673 PHDR = LSB_64_PHDR 674 EHDR = LSB_64_EHDR 675 SHDR = LSB_64_SHDR 676 REL = LSB_64_REL 677 RELA = LSB_64_RELA 678 SYM = LSB_64_SYM 679 DYN = LSB_64_DYN 680 R_SYM = staticmethod(LSB_64_R_SYM) 681 R_TYPE = staticmethod(LSB_64_R_TYPE) 682 683########################### MSB 64 BIT Structures ########################### 684 685MSB_64_R_SYM = lambda i: i >> 32 686MSB_64_R_TYPE = lambda i: i & 0xffffffff 687 688 689class MSB_64_EHDR(BigEndianStructure): 690 _fields_ = [('e_ident', uchar * 16), 691 ('e_type', Elf64_Half), 692 ('e_machine', Elf64_Half), 693 ('e_version', Elf64_Word), 694 ('e_entry', Elf64_Addr), 695 ('e_phoff', Elf64_Off), 696 ('e_shoff', Elf64_Off), 697 ('e_flags', Elf64_Word), 698 ('e_ehsize', Elf64_Half), 699 ('e_phentsize', Elf64_Half), 700 ('e_phnum', Elf64_Half), 701 ('e_shentsize', Elf64_Half), 702 ('e_shnum', Elf64_Half), 703 ('e_shstrndx', Elf64_Half) 704 ] 705 706 707class MSB_64_SHDR(BigEndianStructure): 708 _fields_ = [('sh_name', Elf64_Word), 709 ('sh_type', Elf64_Word), 710 ('sh_flags', Elf64_Xword), 711 ('sh_addr', Elf64_Addr), 712 ('sh_offset', Elf64_Off), 713 ('sh_size', Elf64_Xword), 714 ('sh_link', Elf64_Word), 715 ('sh_info', Elf64_Word), 716 ('sh_addralign', Elf64_Xword), 717 ('sh_entsize', Elf64_Xword) 718 ] 719 720 721class MSB_64_SYM(BigEndianStructure): 722 _fields_ = [('st_name', Elf64_Word), 723 ('st_info', uchar), 724 ('st_other', uchar), 725 ('st_shndx', Elf64_Half), 726 ('st_value', Elf64_Addr), 727 ('st_size', Elf64_Xword) 728 ] 729 730 731class MSB_64_REL(BigEndianStructure): 732 _fields_ = [('r_offset', Elf64_Addr), 733 ('r_info', Elf64_Xword)] 734 735 736class MSB_64_RELA(BigEndianStructure): 737 _fields_ = [('r_offset', Elf64_Addr), 738 ('r_info', Elf64_Xword), 739 ('r_addend', Elf64_Sxword) 740 ] 741 742 743class MSB_64_PHDR(BigEndianStructure): 744 _fields_ = [('p_type', Elf64_Word), 745 ('p_flags', Elf64_Word), 746 ('p_offset', Elf64_Off), 747 ('p_vaddr', Elf64_Addr), 748 ('p_paddr', Elf64_Addr), 749 ('p_filesz', Elf64_Xword), 750 ('p_memsz', Elf64_Xword), 751 ('p_align', Elf64_Xword) 752 ] 753 754class MSB_64_DYN(BigEndianStructure): 755 _fields_ = [('d_tag', Elf64_Xword), 756 ('d_un', Elf64_Xword) 757 ] 758 759class MSB_64(): 760 PHDR = MSB_64_PHDR 761 EHDR = MSB_64_EHDR 762 SHDR = MSB_64_SHDR 763 REL = MSB_64_REL 764 RELA = MSB_64_RELA 765 SYM = MSB_64_SYM 766 DYN = MSB_64_DYN 767 R_SYM = staticmethod(MSB_64_R_SYM) 768 R_TYPE = staticmethod(MSB_64_R_TYPE) 769 770################################ ELF File Implementation ######################################### 771 772class EhdrData(Container): 773 """ 774 header = SectionHeader 775 """ 776 777class ShdrData(Container): 778 779 """ 780 header = SectionHeader 781 name = string (section name) 782 bytes = bytearray (section bytes) 783 raw = c_ubyte_array 784 785 .dynamic 786 content = List of DYN entries 787 788 .rel & .rela 789 relocations = list of REL or RELA 790 791 .dynsym & .symtab 792 symbols = list of SYM entries 793 """ 794 795 796class PhdrData(Container): 797 798 """ 799 type = Programm Header Type 800 header = ProgrammHeader 801 bytes = bytearray (section bytes) 802 raw = c_ubyte_array 803 vaddr = virtual address (int) 804 offset = offset 805 """ 806 807 808class SymbolData(Container): 809 810 """ 811 header = Symbol 812 name = string 813 type = int 814 bind = bind 815 """ 816 817 818class RelocationData(Container): 819 820 """ 821 header = RelocationStruct 822 symbol = SymbolData 823 type = type of relocation 824 """ 825 826class DynamicData(Container): 827 """ 828 header = DYN 829 tag = value of class DT 830 831 """ 832 833##################### ELF Class ############################## 834 835class ELF(Binary): 836 837 def __init__(self, fileName, fileContent=None): 838 super(ELF, self).__init__(fileName, fileContent) 839 840 self.__classes = self._getSuitableClasses(self._bytes) 841 if not self.__classes: 842 raise BinaryError('Bad architecture') 843 844 self.__elfHeader = self._parseElfHeader(self._bytes) 845 self.__segments = self._parseSegments(self._bytes, self.elfHeader) 846 self.__sections = self._parseSections(self._bytes, self.elfHeader) 847 self._parseSymbols(self.sections) 848 self._parseDynamic(self.sections) 849 self._parseRelocations(self.sections) 850 851 @property 852 def _classes(self): 853 return self.__classes 854 855 856 @property 857 def elfHeader(self): 858 return self.__elfHeader 859 860 861 @property 862 def sections(self): 863 return list(self.__sections) 864 865 @property 866 def segments(self): 867 return list(self.__segments) 868 869 @property 870 def programHeaders(self): 871 return list(self.__segments) 872 873 @property 874 def entryPoint(self): 875 return self.elfHeader.header.e_entry 876 877 @property 878 def imageBase(self): 879 return self.segments[0].header.p_vaddr - self.segments[0].header.p_offset if len(self.segments) > 0 else 0 880 881 def _getSuitableClasses(self, data): 882 """Returns the class which holds the suitable classes for the loaded file""" 883 classes = None 884 if data[EI.CLASS] == ELFCLASS.BITS_32: 885 if data[EI.DATA] == ELFDATA.LSB: 886 classes = LSB_32 887 elif data[EI.DATA] == ELFDATA.MSB: 888 classes = MSB_32 889 890 elif data[EI.CLASS] == ELFCLASS.BITS_64: 891 if data[EI.DATA] == ELFDATA.LSB: 892 classes = LSB_64 893 elif data[EI.DATA] == ELFDATA.MSB: 894 classes = MSB_64 895 896 return classes 897 898 def _parseElfHeader(self, data): 899 """Returns the elf header""" 900 ehdr = self.__classes.EHDR.from_buffer(data) 901 return EhdrData(header=ehdr) 902 903 def _parseSegments(self, data, elfHeader): 904 """Return a list of segments""" 905 offset = elfHeader.header.e_phoff 906 segments = [] 907 for i in range(elfHeader.header.e_phnum): 908 phdr = self.__classes.PHDR.from_buffer(data, offset) 909 segment_bytes = (c_ubyte * phdr.p_filesz).from_buffer(data, phdr.p_offset) 910 911 phdrData = PhdrData(header=phdr, raw=segment_bytes, bytes=bytearray(segment_bytes), type=PT[phdr.p_type], vaddr=phdr.p_vaddr, offset=phdr.p_offset) 912 segments.append(phdrData) 913 914 offset += elfHeader.header.e_phentsize 915 916 return segments 917 918 def _parseSections(self, data, elfHeader): 919 """Returns a list of sections""" 920 offset = elfHeader.header.e_shoff 921 shdrs = [] 922 for i in range(elfHeader.header.e_shnum): 923 shdr = self.__classes.SHDR.from_buffer(data, offset) 924 section_bytes = None 925 ba_section_bytes = None 926 if shdr.sh_type != SHT.NOBITS: 927 section_bytes = (c_ubyte * shdr.sh_size).from_buffer(data, shdr.sh_offset) 928 ba_section_bytes = bytearray(section_bytes) 929 shdrs.append(ShdrData(name=None,header=shdr, raw=section_bytes, bytes=ba_section_bytes)) 930 offset += elfHeader.header.e_shentsize 931 932 if elfHeader.header.e_shstrndx != SHN.UNDEF: 933 strtab = shdrs[elfHeader.header.e_shstrndx] 934 strtab_offset = strtab.header.sh_offset 935 936 for section in shdrs: 937 section.name = get_str(strtab.raw, section.header.sh_name) 938 939 return shdrs 940 941 def _parseSymbols(self, sections): 942 """Sets a list of symbols in each DYNSYM and SYMTAB section""" 943 for section in sections: 944 strtab = sections[section.header.sh_link] 945 if section.header.sh_type in (int(SHT.DYNSYM), int(SHT.SYMTAB)): 946 section.symbols = self.__parseSymbolEntriesForSection(section, strtab) 947 948 949 def __parseSymbolEntriesForSection(self, section, strtab): 950 entries = [] 951 offset = 0 952 bytes_p = cast(pointer(section.raw), c_void_p) 953 sym_size = sizeof(self.__classes.SYM) 954 955 for i in range(int(section.header.sh_size / sym_size)): 956 entry = self.__classes.SYM.from_buffer(section.raw, offset) 957 name = get_str(strtab.raw, entry.st_name) 958 sym_data = SymbolData(header=entry, name=name, type=entry.st_info & 0xf, bind=entry.st_info >> 4) 959 entries.append(sym_data) 960 961 offset += sym_size 962 963 return entries 964 965 def _parseRelocations(self, sections): 966 """Parses the relocations and add those to the section""" 967 for section in sections: 968 if section.header.sh_link != SHN.UNDEF and section.header.sh_type in (SHT.REL, SHT.RELA): 969 symbols = sections[section.header.sh_link].symbols 970 relocations = self.__parseRelocationEntries(section, symbols) 971 section.relocations = relocations 972 973 def __parseRelocationEntries(self, section, symbols): 974 struct = self.__classes.REL if section.header.sh_type == SHT.REL else self.__classes.RELA 975 struct_size = sizeof(struct) 976 offset = 0 977 entries = [] 978 979 for i in range(int(section.header.sh_size / struct_size)): 980 entry = struct.from_buffer(section.raw, offset) 981 sym = symbols[self.__classes.R_SYM(entry.r_info)] 982 reloc_entry = RelocationData(header=entry, symbol=sym, type=self.__classes.R_TYPE(entry.r_info)) 983 entries.append(reloc_entry) 984 offset += sizeof(struct) 985 986 return entries 987 988 def _parseDynamic(self, sections): 989 990 dyn_size = sizeof(self._classes.DYN) 991 992 for section in sections: 993 offset = 0 994 dyns = [] 995 if section.header.sh_type == SHT.DYNAMIC: 996 for i in range(int(len(section.bytes) / dyn_size)): 997 dyn = self._classes.DYN.from_buffer(section.raw, offset) 998 dyns.append(DynamicData(header=dyn, tag=DT[dyn.d_tag])) 999 if dyn.d_tag == DT.NULL: 1000 break 1001 offset += dyn_size 1002 section.content = dyns 1003 self._parseDynamicTags(dyns, sections) 1004 1005 def _parseDynamicTags(self, dyns, sections): 1006 1007 for dyn in dyns: 1008 if dyn.header.d_tag == DT.NEEDED: 1009 self.__parseDynamicTagNeeded(dyn, dyns, sections) 1010 1011 1012 def __parseDynamicTagNeeded(self, dyn, dyns, sections): 1013 dyn_strtab = None 1014 for d in dyns: 1015 if d.header.d_tag == DT.STRTAB: 1016 dyn_strtab = d 1017 1018 if not dyn_strtab: 1019 return 1020 1021 for section in sections: 1022 if section.header.sh_addr == dyn_strtab.header.d_un: 1023 dyn.val = get_str(section.raw, dyn.header.d_un) 1024 break 1025 1026 @classmethod 1027 def isSupportedContent(cls, fileContent): 1028 """Returns if the files are valid for this filetype""" 1029 return bytearray(fileContent)[:4] == b'\x7fELF' 1030