原地址:https://github.com/guanchao/elfParser
作者是用python2写的,现在给出我修改后的python3版本。(测试发现有bug,以后自己写个,0.0)
1 #!/usr/bin/env python 2 # coding:utf-8 3 4 import sys 5 import binascii 6 7 ''' 8 # 节区类型定义 9 /* sh_type */ 10 #define SHT_NULL 0 11 #define SHT_PROGBITS 1 12 #define SHT_SYMTAB 2 13 #define SHT_STRTAB 3 14 #define SHT_RELA 4 15 #define SHT_HASH 5 16 #define SHT_DYNAMIC 6 17 #define SHT_NOTE 7 18 #define SHT_NOBITS 8 19 #define SHT_REL 9 20 #define SHT_SHLIB 10 21 #define SHT_DYNSYM 11 22 #define SHT_NUM 12 23 #define SHT_LOPROC 0x70000000 24 #define SHT_HIPROC 0x7fffffff 25 #define SHT_LOUSER 0x80000000 26 #define SHT_HIUSER 0xffffffff 27 #define SHT_MIPS_LIST 0x70000000 28 #define SHT_MIPS_CONFLICT 0x70000002 29 #define SHT_MIPS_GPTAB 0x70000003 30 #define SHT_MIPS_UCODE 0x70000004 31 ''' 32 SH_TYPE_MAP_LIST = {0: 'SHT_NULL', 33 1: 'SHT_PROGBITS', 34 2: 'SHT_SYMTAB', 35 3: 'SHT_STRTAB', 36 4: 'SHT_RELA', 37 5: 'SHT_HASH', 38 6: 'SHT_DYNAMIC', 39 7: 'SHT_NOTE', 40 8: 'SHT_NOBITS', 41 9: 'SHT_REL', 42 10: 'SHT_SHLIB', 43 11: 'SHT_DYNSYM', 44 # 0x60000000:'SHT_LOOS', 45 # 0x6fffffff:'SHT_HIOS', 46 0x70000000: 'SHT_LOPROC', 47 0x7FFFFFFF: 'SHT_HIPROC', 48 0x80000000: 'SHT_LOUSER', 49 0x8FFFFFFF: 'SHT_HIUSER', 50 0x70000000: 'SHT_MIPS_LIST', 51 0x70000002: 'SHT_MIPS_CONFLICT', 52 0x70000003: 'SHT_MIPS_GPTAB', 53 0x70000004: 'SHT_MIPS_UCODE', 54 } 55 56 PT_TYPE_MAP_LIST = { 57 0: 'NULL', 58 1: 'LOAD', 59 2: 'DYNAMIC', 60 3: 'INTERP', 61 4: 'NOTE', 62 5: 'SHLIB', 63 6: 'PHDR', 64 7: 'TLS', 65 0x70000000: 'LOPROC', 66 0x70000001: 'HIPROC', 67 0x6474E551: 'GNU_STACK', 68 0x6474E552: 'GNU_RELRO', 69 } 70 71 ''' 72 Elf32_Dyn.d_tag 73 ''' 74 DYNAMIC_TYPE = { 75 0: 'NULL', 76 1: 'NEEDED', 77 2: 'PLTRELSZ', 78 3: 'PLTGOT', 79 4: 'HASH', 80 5: 'STRTAB', 81 6: 'SYMTAB', 82 7: 'RELA', 83 8: 'RELASZ', 84 9: 'RELAENT', 85 10: 'STRSZ', 86 11: 'SYMENT', 87 12: 'INIT', 88 13: 'FINIT', 89 14: 'SONAME', 90 15: 'RPATH', 91 16: 'SYMBOLIC', 92 17: 'REL', 93 18: 'RELSZ', 94 19: 'RELENT', 95 20: 'PLTREL', 96 21: 'DEBUG', 97 22: 'TEXTREL', 98 23: 'JMPREL', 99 26: 'FINIT_ARRAY', 100 28: 'FINIT_ARRAYSZ', 101 25: 'INIT_ARRAY', 102 27: 'INIT_ARRAYSZ', 103 30: 'FLAGS', 104 0x6FFFFFFA: 'RELCOUNT', 105 0x6FFFFFFB: 'FLAGS_1', 106 0x70000000: 'LOPROC', 107 0x7fffffff: 'HIPROC', 108 0x70000001: 'MIPS_RLD_VERSION', 109 0x70000002: 'MIPS_TIME_STAMP', 110 0x70000003: 'MIPS_ICHECKSUM', 111 0x70000004: 'MIPS_IVERSION', 112 0x70000005: 'MIPS_FLAGS', 113 0x70000006: 'MIPS_BASE_ADDRESS', 114 0x70000008: 'MIPS_CONFLICT', 115 0x70000009: 'MIPS_LIBLIST', 116 0x7000000a: 'MIPS_LOCAL_GOTNO', 117 0x7000000b: 'MIPS_CONFLICTNO', 118 0x70000010: 'MIPS_LIBLISTNO', 119 0x70000011: 'MIPS_SYMTABNO', 120 0x70000012: 'MIPS_UNREFEXTNO', 121 0x70000013: 'MIPS_GOTSYM', 122 0x70000014: 'MIPS_HIPAGENO', 123 0x70000016: 'MIPS_RLD_MAP', 124 125 } 126 ''' 127 typedef struct elf32_hdr{ 128 unsigned char e_ident[EI_NIDENT]; 129 Elf32_Half e_type; 130 Elf32_Half e_machine; 131 Elf32_Word e_version; 132 Elf32_Addr e_entry; /* Entry point */ 133 Elf32_Off e_phoff; 134 Elf32_Off e_shoff; 135 Elf32_Word e_flags; 136 Elf32_Half e_ehsize; 137 Elf32_Half e_phentsize; 138 Elf32_Half e_phnum; 139 Elf32_Half e_shentsize; 140 Elf32_Half e_shnum; 141 Elf32_Half e_shstrndx; 142 } Elf32_Ehdr; 143 ''' 144 145 146 class Elf32_Ehdr(object): 147 """docstring for Elf32_Ehdr""" 148 149 def __init__(self): 150 super(Elf32_Ehdr, self).__init__() 151 self.e_ident = None 152 self.e_type = None 153 self.e_machine = None 154 self.e_version = None 155 self.e_entry = None 156 self.e_phoff = None 157 self.e_shoff = None 158 self.e_flags = None 159 self.e_ehsize = None 160 self.e_phentsize = None 161 self.e_phnum = None 162 self.e_shentsize = None 163 self.e_shnum = None 164 self.e_shstrndx = None 165 166 167 class e_ident(object): 168 """docstring for e_ident""" 169 170 def __init__(self): 171 super(e_ident, self).__init__() 172 self.file_identification = None 173 self.ei_class = None 174 self.ei_data = None 175 self.ei_version = None 176 self.ei_osabi = None 177 self.ei_abiversion = None 178 self.ei_pad = None 179 self.ei_nident = None 180 181 def __str__(self): 182 return 'e_ident=[file_identification=%s, ei_class=%d, ei_data=%d, ei_version=%d, ei_osabi=%d, ei_abiversion=%d, ei_pad=%s, ei_nident=%d]' % ( 183 self.file_identification, self.ei_class, self.ei_data, self.ei_version, self.ei_osabi, self.ei_abiversion, 184 self.ei_pad, self.ei_nident) 185 186 187 class Elf32_Shdr(object): 188 """docstring for Elf32_Shdr""" 189 190 def __init__(self): 191 super(Elf32_Shdr, self).__init__() 192 ''' 193 typedef struct Elf32_Shdr { 194 Elf32_Word sh_name; 195 Elf32_Word sh_type; 196 Elf32_Word sh_flags; 197 Elf32_Addr sh_addr; 198 Elf32_Off sh_offset; 199 Elf32_Word sh_size; 200 Elf32_Word sh_link; 201 Elf32_Word sh_info; 202 Elf32_Word sh_addralign; 203 Elf32_Word sh_entsize; 204 } Elf32_Shdr; 205 ''' 206 self.sh_name = None 207 self.sh_type = None 208 self.sh_flags = None 209 self.sh_addr = None 210 self.sh_offset = None 211 self.size = None 212 self.sh_link = None 213 self.sh_addralign = None 214 self.sh_entsize = None 215 216 self.section_name = None 217 218 def __str__(self): 219 return 'Elf32_Shdr=[sh_name=%s, sh_type=%d, sh_flags=%d, sh_addr=%s, sh_sh_offset=%s, sh_size=%d, sh_link=%d, sh_info=%d, sh_addralign=%d, sh_entsize=%d]' % \ 220 (hex(self.sh_name), self.sh_type, self.sh_flags, hex(self.sh_addr), hex(self.sh_offset), self.sh_size, 221 self.sh_link, self.sh_info, self.sh_addralign, self.sh_entsize) 222 223 224 class Elf32_Sym(object): 225 """docstring for Elf32_Sym""" 226 227 def __init__(self): 228 super(Elf32_Sym, self).__init__() 229 ''' 230 typedef struct elf32_sym{ 231 Elf32_Word st_name; 232 Elf32_Addr st_value; 233 Elf32_Word st_size; 234 unsigned char st_info; 235 unsigned char st_other; 236 Elf32_Half st_shndx; 237 } Elf32_Sym; 238 ''' 239 self.st_name = None 240 self.st_value = None 241 self.st_size = None 242 self.st_info = None 243 self.st_other = None 244 self.st_shndx = None 245 246 self.symbol_name = None 247 248 def __str__(self): 249 return 'Elf32_Dyn=[st_name=%s, st_value=%d, st_size=%d, st_info=%d, st_other=%d, st_shndx=%d] #%s' % \ 250 (self.st_name, self.st_value, self.st_size, self.st_info, self.st_other, self.st_shndx, self.symbol_name) 251 252 253 class Elf32_Phdr(object): 254 """docstring for Elf32_Phdr""" 255 256 def __init__(self): 257 super(Elf32_Phdr, self).__init__() 258 ''' 259 /* 32-bit ELF base types. */ 260 typedef uint32_t Elf32_Addr; 261 typedef uint16_t Elf32_Half; 262 typedef uint32_t Elf32_Off; 263 typedef int32_t Elf32_Sword; 264 typedef uint32_t Elf32_Word; 265 ''' 266 self.p_type = None # Elf32_Word 267 self.p_offset = None # Elf32_Off 268 self.p_vaddr = None # Elf32_Addr 269 self.p_paddr = None # Elf32_Addr 270 self.p_filesz = None # Elf32_word 271 self.p_memsz = None # Elf32_Word 272 self.p_flags = None # Elf32_Word 273 self.p_align = None # Elf32_Word 274 275 276 class Elf32_Dyn(object): 277 """docstring for Elf32_dyn""" 278 279 def __init__(self): 280 super(Elf32_Dyn, self).__init__() 281 ''' 282 typedef struct dynamic{ 283 Elf32_Sword d_tag; 284 union{ 285 Elf32_Sword d_val; 286 Elf32_Addr d_ptr; 287 } d_un; 288 } Elf32_Dyn; 289 ''' 290 self.d_tag = None 291 self.d_un = None 292 293 def __str__(self): 294 return 'Elf32_Dyn=[d_tag=%d, d_un=%d]' % \ 295 (self.d_tag, self.d_un) 296 297 298 class ELF(object): 299 """docstring for ELF""" 300 301 def __init__(self, filepath): 302 super(ELF, self).__init__() 303 self.filepath = filepath 304 self.elf32_Ehdr = Elf32_Ehdr() 305 306 # section header table 307 self.sectionHeaderTable = [] 308 309 # section name table 310 self.sectionNameTable = None 311 312 # program header table 313 self.programHeaderTable = [] 314 315 # dynamic symbol table 316 self.symbolTable = [] # .dynsym 317 self.dynstrTable = None # .dynstr 318 319 # dynamic link table 320 self.dynamicLinkTable = [] # .dynamic 321 322 self.initELFHeader() 323 self.initSectionHeader() 324 self.initProgramHeader() 325 self.initSymbolTalbe() 326 self.initDynamicLinkTable() 327 328 def initELFHeader(self): 329 f = open(self.filepath, "rb") 330 self.f = f 331 # unsigned char e_ident[EI_NIDENT]; 332 f.seek(0, 0) 333 self.elf32_Ehdr.e_ident = e_ident() 334 self.elf32_Ehdr.e_ident.file_identification = f.read(4) 335 self.elf32_Ehdr.e_ident.ei_class = int.from_bytes(f.read(1), 'little') 336 self.elf32_Ehdr.e_ident.ei_data = int.from_bytes(f.read(1), 'little') 337 self.elf32_Ehdr.e_ident.ei_version = int.from_bytes(f.read(1), 'little') 338 self.elf32_Ehdr.e_ident.ei_osabi = int.from_bytes(f.read(1), 'little') 339 self.elf32_Ehdr.e_ident.ei_abiversion = int.from_bytes(f.read(1), 'little') 340 self.elf32_Ehdr.e_ident.ei_pad = binascii.b2a_hex(f.read(6)) 341 self.elf32_Ehdr.e_ident.ei_nident = int.from_bytes(f.read(1), 'little') 342 343 # Elf32_Half e_type; 344 f.seek(16, 0) 345 self.elf32_Ehdr.e_type = int.from_bytes(f.read(2), 'little') 346 347 # Elf32_Half e_machine; 348 f.seek(18, 0) 349 self.elf32_Ehdr.e_machine = int.from_bytes(f.read(2), 'little') 350 351 # Elf32_Word e_version; 352 f.seek(20, 0) 353 self.elf32_Ehdr.e_version = int.from_bytes(f.read(4), 'little') 354 355 # Elf32_Addr e_entry; 356 f.seek(24, 0) 357 self.elf32_Ehdr.e_entry = int.from_bytes(f.read(4), 'little') 358 359 # Elf32_Off e_phoff; 360 f.seek(28, 0) 361 self.elf32_Ehdr.e_phoff = int.from_bytes(f.read(4), 'little') 362 363 # Elf32_Off e_shoff; 364 f.seek(32, 0) 365 self.elf32_Ehdr.e_shoff = int.from_bytes(f.read(4), 'little') 366 367 # Elf32_Word e_flags; 368 f.seek(36, 0) 369 self.elf32_Ehdr.e_flags = int.from_bytes(f.read(4), 'little') 370 371 # Elf32_Half e_ehsize; 372 f.seek(40, 0) 373 self.elf32_Ehdr.e_ehsize = int.from_bytes(f.read(2), 'little') 374 375 # Elf32_Half e_phentsize; 376 f.seek(42, 0) 377 self.elf32_Ehdr.e_phentsize = int.from_bytes(f.read(2), 'little') 378 379 # Elf32_Half e_phnum; 380 f.seek(44, 0) 381 self.elf32_Ehdr.e_phnum = int.from_bytes(f.read(2), 'little') 382 383 # Elf32_Half e_shentsize; 384 f.seek(46, 0) 385 self.elf32_Ehdr.e_shentsize = int.from_bytes(f.read(2), 'little') 386 387 # Elf32_Half e_shnum; 388 f.seek(48, 0) 389 self.elf32_Ehdr.e_shnum = int.from_bytes(f.read(2), 'little') 390 391 # Elf32_Half e_shstrndx; 392 f.seek(50, 0) 393 self.elf32_Ehdr.e_shstrndx = int.from_bytes(f.read(2), 'little') 394 395 def initSectionHeader(self): 396 # print(self.elf32_Ehdr.e_shnum) 397 for i in range(self.elf32_Ehdr.e_shnum): 398 self.sectionHeaderTable.append(self.parseSectionHeader(self.elf32_Ehdr.e_shoff + i * self.elf32_Ehdr.e_shentsize)) 399 if self.elf32_Ehdr.e_shnum == 0: 400 return 401 # init section name table 402 self.f.seek(self.sectionHeaderTable[self.elf32_Ehdr.e_shstrndx].sh_offset) 403 size = self.sectionHeaderTable[self.elf32_Ehdr.e_shstrndx].sh_size 404 self.sectionNameTable = self.f.read(size) 405 406 for i in range(self.elf32_Ehdr.e_shnum): 407 idx = self.sectionHeaderTable[i].sh_name 408 name = [] 409 while self.sectionNameTable[idx] != 0: 410 name.append(chr(self.sectionNameTable[idx])) 411 idx += 1 412 # print("".join(name)) 413 self.sectionHeaderTable[i].section_name = "".join(name) 414 415 def parseSectionHeader(self, offset): 416 self.f.seek(offset, 0) 417 elf32_Shdr = Elf32_Shdr() 418 # elf32_Shdr.sh_name = int.from_bytes(self.f.read(4), 16) 419 elf32_Shdr.sh_name = int.from_bytes(self.f.read(4), 'little') 420 elf32_Shdr.sh_type = int.from_bytes(self.f.read(4), 'little') 421 elf32_Shdr.sh_flags = int.from_bytes(self.f.read(4), 'little') 422 elf32_Shdr.sh_addr = int.from_bytes(self.f.read(4), 'little') 423 elf32_Shdr.sh_offset = int.from_bytes(self.f.read(4), 'little') 424 elf32_Shdr.sh_size = int.from_bytes(self.f.read(4), 'little') 425 elf32_Shdr.sh_link = int.from_bytes(self.f.read(4), 'little') 426 elf32_Shdr.sh_info = int.from_bytes(self.f.read(4), 'little') 427 elf32_Shdr.sh_addralign = int.from_bytes(self.f.read(4), 'little') 428 elf32_Shdr.sh_entsize = int.from_bytes(self.f.read(4), 'little') 429 return elf32_Shdr 430 431 def displaySectionHeader(self): 432 print('[+] Section Header Table:') 433 434 print(' # %-32s%-16s%-16s%-16s%-8s%-8s%-8s%-8s%-8s%-8s' % ( 435 'Name', 'Type', 'Addr', 'Offset', 'Size', 'ES', 'Flg', 'Lk', 'Inf', 'Al')) 436 437 for index in range(len(self.sectionHeaderTable)): 438 elf32_Shdr = self.sectionHeaderTable[index] 439 if elf32_Shdr.sh_type in SH_TYPE_MAP_LIST: 440 print(' [%4d] %-32s%-16s%-16s%-16s%-8s%-8d%-8d%-8d%-8d%-8d' % \ 441 (index, 442 self.getSectionName(elf32_Shdr), 443 SH_TYPE_MAP_LIST[elf32_Shdr.sh_type].strip(), 444 hex(elf32_Shdr.sh_addr), 445 hex(elf32_Shdr.sh_offset), 446 hex(elf32_Shdr.sh_size), 447 elf32_Shdr.sh_entsize, 448 elf32_Shdr.sh_flags, 449 elf32_Shdr.sh_link, 450 elf32_Shdr.sh_info, 451 elf32_Shdr.sh_addralign, 452 )) 453 454 else: 455 print(' [%4d] %-32s%-16d%-16s%-16s%-8s%-8d%-8d%-8d%-8d%-8d' % \ 456 (index, 457 self.getSectionName(elf32_Shdr), 458 elf32_Shdr.sh_type, 459 hex(elf32_Shdr.sh_addr), 460 hex(elf32_Shdr.sh_offset), 461 hex(elf32_Shdr.sh_size), 462 elf32_Shdr.sh_entsize, 463 elf32_Shdr.sh_flags, 464 elf32_Shdr.sh_link, 465 elf32_Shdr.sh_info, 466 elf32_Shdr.sh_addralign, 467 )) 468 469 print() 470 471 def getSectionName(self, elf32_Shdr): 472 idx = self.sectionNameTable.find(0, elf32_Shdr.sh_name) 473 return self.sectionNameTable[elf32_Shdr.sh_name:idx] 474 475 def initProgramHeader(self): 476 for i in range(self.elf32_Ehdr.e_phnum): 477 self.programHeaderTable.append( 478 self.parseProgramHeader(self.elf32_Ehdr.e_phoff + i * self.elf32_Ehdr.e_phentsize)) 479 480 def parseProgramHeader(self, offset): 481 ''' 482 typedef struct elf32_phdr{ 483 Elf32_Word p_type; 484 Elf32_Off p_offset; 485 Elf32_Addr p_vaddr; 486 Elf32_Addr p_paddr; 487 Elf32_Word p_filesz; 488 Elf32_Word p_memsz; 489 Elf32_Word p_flags; 490 Elf32_Word p_align; 491 } Elf32_Phdr; 492 ''' 493 self.f.seek(offset, 0) 494 elf32_Phdr = Elf32_Phdr() 495 elf32_Phdr.p_type = int.from_bytes(self.f.read(4), 'little') 496 elf32_Phdr.p_offset = int.from_bytes(self.f.read(4), 'little') 497 elf32_Phdr.p_vaddr = int.from_bytes(self.f.read(4), 'little') 498 elf32_Phdr.p_paddr = int.from_bytes(self.f.read(4), 'little') 499 elf32_Phdr.p_filesz = int.from_bytes(self.f.read(4), 'little') 500 elf32_Phdr.p_memsz = int.from_bytes(self.f.read(4), 'little') 501 elf32_Phdr.p_flags = int.from_bytes(self.f.read(4), 'little') 502 elf32_Phdr.p_align = int.from_bytes(self.f.read(4), 'little') 503 return elf32_Phdr 504 505 def displayProgramHeader(self): 506 print('[+] Program Header Table:') 507 508 print(' # %-16s%-16s%-16s%-16s%-8s%-8s%-8s%-8s' % ( 509 'Type', 'offset', 'VirtAddr', 'PhysAddr', 'FileSiz', 'MemSiz', 'Flg', 'Align')) 510 511 for index in range(len(self.programHeaderTable)): 512 elf32_Phdr = self.programHeaderTable[index] 513 514 if elf32_Phdr.p_type in PT_TYPE_MAP_LIST: 515 print(' [%4d] %-16s%-16s%-16s%-16s%-8s%-8s%-8d%-8s' % ( 516 index, 517 PT_TYPE_MAP_LIST[elf32_Phdr.p_type], 518 hex(elf32_Phdr.p_offset), 519 hex(elf32_Phdr.p_vaddr), 520 hex(elf32_Phdr.p_paddr), 521 hex(elf32_Phdr.p_filesz), 522 hex(elf32_Phdr.p_memsz), 523 elf32_Phdr.p_flags, 524 hex(elf32_Phdr.p_align), 525 )) 526 527 else: 528 print(' [%4d] %-16d%-16s%-16s%-16s%-8s%-8s%-8d%-8s' % ( 529 index, 530 elf32_Phdr.p_type, 531 hex(elf32_Phdr.p_offset), 532 hex(elf32_Phdr.p_vaddr), 533 hex(elf32_Phdr.p_paddr), 534 hex(elf32_Phdr.p_filesz), 535 hex(elf32_Phdr.p_memsz), 536 elf32_Phdr.p_flags, 537 hex(elf32_Phdr.p_align), 538 )) 539 540 print('\n[+] Section to segment mapping:') 541 542 for index in range(len(self.programHeaderTable)): 543 elf32_Phdr = self.programHeaderTable[index] 544 sections = self.getSegmentSections(elf32_Phdr) 545 546 sections_str = '' 547 for elf32_Shdr in sections: 548 idx = self.sectionNameTable.index(0, elf32_Shdr.sh_name) 549 sections_str += self.sectionNameTable[elf32_Shdr.sh_name:idx].decode() + ' ' 550 print(' [%4d] %s' % (index, sections_str)) 551 552 print() 553 554 555 def getSegmentSections(self, elf32_Phdr): 556 start = elf32_Phdr.p_offset 557 end = elf32_Phdr.p_offset + elf32_Phdr.p_filesz 558 559 sections = [] 560 for index in range(len(self.sectionHeaderTable)): 561 elf32_Shdr = self.sectionHeaderTable[index] 562 section_start = elf32_Shdr.sh_offset 563 section_end = elf32_Shdr.sh_offset + elf32_Shdr.sh_size 564 if section_start >= start and section_end <= end: 565 sections.append(elf32_Shdr) 566 567 return sections 568 569 def initSymbolTalbe(self): 570 # init dynsym 571 elf32_Shdr = self.getSectionByName('.dynsym') 572 if elf32_Shdr != None: 573 for i in range(int(elf32_Shdr.sh_size / elf32_Shdr.sh_entsize)): 574 self.symbolTable.append(self.parseSymbolTable(elf32_Shdr.sh_offset + i * elf32_Shdr.sh_entsize)) 575 576 # init dynstr 577 dynstr_elf32_Shdr = self.getSectionByName('.dynstr') 578 self.f.seek(dynstr_elf32_Shdr.sh_offset) 579 580 self.dynstrTable = self.f.read(dynstr_elf32_Shdr.sh_size) 581 582 for i in range(len(self.symbolTable)): 583 idx = self.symbolTable[i].st_name 584 name = [] 585 while self.dynstrTable[idx+1] != 0: 586 name.append(chr(self.dynstrTable[idx])) 587 idx += 1 588 # print("".join(name)) 589 self.symbolTable[i].symbol_name = "".join(name) 590 591 def parseSymbolTable(self, offset): 592 ''' 593 typedef struct elf32_sym{ 594 Elf32_Word st_name; 595 Elf32_Addr st_value; 596 Elf32_Word st_size; 597 unsigned char st_info; 598 unsigned char st_other; 599 Elf32_Half st_shndx; 600 } Elf32_Sym; 601 ''' 602 self.f.seek(offset, 0) 603 elf32_Sym = Elf32_Sym() 604 elf32_Sym.st_name = int.from_bytes(self.f.read(4), 'little') 605 elf32_Sym.st_value = int.from_bytes(self.f.read(4), 'little') 606 elf32_Sym.st_size = int.from_bytes(self.f.read(4), 'little') 607 elf32_Sym.st_info = int.from_bytes(self.f.read(1), 'little') 608 elf32_Sym.st_other = int.from_bytes(self.f.read(1), 'little') 609 elf32_Sym.st_shndx = int.from_bytes(self.f.read(2), 'little') 610 return elf32_Sym 611 612 def displaySymbolTable(self): 613 print('[+] Dynamic Symbol Table:') 614 615 print(' # %-10s%-8s%-8s%-8s%-8s%-8s%-8s' 616 % ('Value', 'Size', 'Type', 'Bind', 'Other', 'Ndx', 'Name')) 617 BIND_TYPE = {0: 'LOCAL', 1: 'GLOBAL', 2: 'WEAK', 13: 'LOPROC', 15: 'HIPROC'} 618 ELF32_ST_TYPE = {0: 'NOTYPE', 1: 'OBJECT', 2: 'FUNC', 3: 'SECTION', 4: 'FILE', 13: 'LOPROC', 15: 'HIPROC'} 619 SHN_TYPE = {0: 'UNDEF', 0xfff1: 'ABS', 0xfff2: 'COMMON', } 620 621 for index in range(len(self.symbolTable)): 622 elf32_Sym = self.symbolTable[index] 623 bind = elf32_Sym.st_info >> 4 624 type = elf32_Sym.st_info & 0xf 625 626 if elf32_Sym.st_shndx == 0 or elf32_Sym.st_shndx == 0xfff1 or elf32_Sym.st_shndx == 0xfff2: 627 shn_type = SHN_TYPE[elf32_Sym.st_shndx] 628 else: 629 shn_type = str(elf32_Sym.st_shndx) 630 print(' [%4d] %-10s%-8d%-8s%-8s%-8d%-8s%-8s' % ( 631 index, 632 hex(elf32_Sym.st_value), 633 elf32_Sym.st_size, 634 ELF32_ST_TYPE[type], 635 BIND_TYPE[bind], 636 elf32_Sym.st_other, 637 shn_type, 638 elf32_Sym.symbol_name 639 )) 640 print() 641 642 def initDynamicLinkTable(self): 643 # init dynamic 644 elf32_Shdr = self.getSectionByName('.dynamic') 645 if elf32_Shdr != None: 646 for i in range(int(elf32_Shdr.sh_size / elf32_Shdr.sh_entsize)): 647 self.dynamicLinkTable.append( 648 self.parseDynamicLinkTable(elf32_Shdr.sh_offset + i * elf32_Shdr.sh_entsize)) 649 650 def parseDynamicLinkTable(self, offset): 651 ''' 652 typedef struct dynamic{ 653 Elf32_Sword d_tag; 654 union{ 655 Elf32_Sword d_val; 656 Elf32_Addr d_ptr; 657 } d_un; 658 } Elf32_Dyn; 659 ''' 660 self.f.seek(offset, 0) 661 elf32_Dyn = Elf32_Dyn() 662 elf32_Dyn.d_tag = int.from_bytes(self.f.read(4), 'little') 663 elf32_Dyn.d_un = int.from_bytes(self.f.read(4), 'little') 664 return elf32_Dyn 665 666 def displayDynamicLinkTable(self): 667 print('[+] Dynamic Link Table:') 668 print(' # %-16s%-16s%-8s' % ('Tag', 'Type', 'Name/Value')) 669 670 for index in range(len(self.dynamicLinkTable)): 671 elf32_Dyn = self.dynamicLinkTable[index] 672 print(' [%4d] %-16s%-16s%-16s' % ( 673 index, 674 hex(elf32_Dyn.d_tag), 675 DYNAMIC_TYPE[elf32_Dyn.d_tag], 676 self.getElf32_Dyn_TypeInfo(elf32_Dyn), 677 678 )) 679 680 def getElf32_Dyn_TypeInfo(self, elf32_Dyn): 681 if elf32_Dyn.d_tag == 1: # DT_NEEDED 682 idx = self.dynstrTable.find(0, elf32_Dyn.d_un) 683 return 'Shared library: [%s]' % self.dynstrTable[elf32_Dyn.d_un: idx] 684 685 elif elf32_Dyn.d_tag == 0xe: # DT_SONAME 686 idx = self.dynstrTable.find(0, elf32_Dyn.d_un) 687 return 'Library soname: [%s]' % self.dynstrTable[elf32_Dyn.d_un: idx] 688 689 return hex(elf32_Dyn.d_un) 690 691 def displayELFHeader(self): 692 print('[+] ELF Header:') 693 print('e_ident:\t%s' % self.elf32_Ehdr.e_ident) 694 print('e_type: \t%s' % self.elf32_Ehdr.e_type) 695 print('e_machine:\t%s' % self.elf32_Ehdr.e_machine) 696 print('e_version:\t%s' % self.elf32_Ehdr.e_version) 697 print('e_entry:\t%s' % self.elf32_Ehdr.e_entry) 698 print('e_phoff:\t%s\t//Program header offset' % hex(self.elf32_Ehdr.e_phoff)) 699 print('e_shoff:\t%s\t//Section header offset' % hex(self.elf32_Ehdr.e_shoff)) 700 print('e_flags:\t%s' % self.elf32_Ehdr.e_flags) 701 print('e_ehsize:\t%s\t//ELF header size' % self.elf32_Ehdr.e_ehsize) 702 print('e_phentsize:\t%s\t//Program header entry size' % self.elf32_Ehdr.e_phentsize) 703 print('e_phnum:\t%s\t//Program header number' % self.elf32_Ehdr.e_phnum) 704 print('e_shentsize:\t%s\t//Section header entry size' % (self.elf32_Ehdr.e_shentsize)) 705 print('e_shnum:\t%s\t//Section header number' % (self.elf32_Ehdr.e_shnum)) 706 print('e_shstrndx:\t%s\t//Section header string index' % (self.elf32_Ehdr.e_shstrndx)) 707 print() 708 709 def disassemble(self): 710 ''' 711 Display assembler contents of executable sections (.text .plt ...) 712 ''' 713 self.__disassembleTEXTSection() 714 self.__disassemblePLTSection() 715 716 def __disassembleTEXTSection(self): 717 elf32_Shdr = self.getSectionByName('.text') 718 if elf32_Shdr == None: 719 return 720 # TODO 721 pass 722 723 def __disassemblePLTSection(self): 724 elf32_Shdr = self.getSectionByName('.plt') 725 if elf32_Shdr == None: 726 return 727 # TODO 728 pass 729 730 def getSectionByName(self, name): 731 for elf32_Shdr in self.sectionHeaderTable: 732 if elf32_Shdr.section_name == name: 733 return elf32_Shdr 734 return None 735 736 737 if __name__ == '__main__': 738 elf = ELF(sys.argv[1]) 739 elf.displayELFHeader() 740 elf.displaySectionHeader() 741 elf.displayProgramHeader() 742 elf.displaySymbolTable() 743 elf.displayDynamicLinkTable() 744 elf.disassemble()