mirror of
https://github.com/SickGear/SickGear.git
synced 2024-12-01 08:53:37 +00:00
0d9fbc1ad7
This version of SickBeard uses both TVDB and TVRage to search and gather it's series data from allowing you to now have access to and download shows that you couldn't before because of being locked into only what TheTVDB had to offer. Also this edition is based off the code we used in our XEM editon so it does come with scene numbering support as well as all the other features our XEM edition has to offer. Please before using this with your existing database (sickbeard.db) please make a backup copy of it and delete any other database files such as cache.db and failed.db if present, we HIGHLY recommend starting out with no database files at all to make this a fresh start but the choice is at your own risk! Enjoy!
187 lines
7 KiB
Python
187 lines
7 KiB
Python
"""
|
|
ELF (Unix/BSD executable file format) parser.
|
|
|
|
Author: Victor Stinner
|
|
Creation date: 08 may 2006
|
|
"""
|
|
|
|
from lib.hachoir_parser import Parser
|
|
from lib.hachoir_core.field import (FieldSet, ParserError,
|
|
UInt8, UInt16, UInt32, Enum,
|
|
String, Bytes)
|
|
from lib.hachoir_core.text_handler import textHandler, hexadecimal
|
|
from lib.hachoir_core.endian import LITTLE_ENDIAN, BIG_ENDIAN
|
|
|
|
class ElfHeader(FieldSet):
|
|
static_size = 52*8
|
|
LITTLE_ENDIAN_ID = 1
|
|
BIG_ENDIAN_ID = 2
|
|
MACHINE_NAME = {
|
|
1: u"AT&T WE 32100",
|
|
2: u"SPARC",
|
|
3: u"Intel 80386",
|
|
4: u"Motorola 68000",
|
|
5: u"Motorola 88000",
|
|
7: u"Intel 80860",
|
|
8: u"MIPS RS3000"
|
|
}
|
|
CLASS_NAME = {
|
|
1: u"32 bits",
|
|
2: u"64 bits"
|
|
}
|
|
TYPE_NAME = {
|
|
0: u"No file type",
|
|
1: u"Relocatable file",
|
|
2: u"Executable file",
|
|
3: u"Shared object file",
|
|
4: u"Core file",
|
|
0xFF00: u"Processor-specific (0xFF00)",
|
|
0xFFFF: u"Processor-specific (0xFFFF)"
|
|
}
|
|
ENDIAN_NAME = {
|
|
LITTLE_ENDIAN_ID: "Little endian",
|
|
BIG_ENDIAN_ID: "Big endian",
|
|
}
|
|
|
|
def createFields(self):
|
|
yield Bytes(self, "signature", 4, r'ELF signature ("\x7fELF")')
|
|
yield Enum(UInt8(self, "class", "Class"), self.CLASS_NAME)
|
|
yield Enum(UInt8(self, "endian", "Endian"), self.ENDIAN_NAME)
|
|
yield UInt8(self, "file_version", "File version")
|
|
yield String(self, "pad", 8, "Pad")
|
|
yield UInt8(self, "nb_ident", "Size of ident[]")
|
|
yield Enum(UInt16(self, "type", "File type"), self.TYPE_NAME)
|
|
yield Enum(UInt16(self, "machine", "Machine type"), self.MACHINE_NAME)
|
|
yield UInt32(self, "version", "ELF format version")
|
|
yield UInt32(self, "entry", "Number of entries")
|
|
yield UInt32(self, "phoff", "Program header offset")
|
|
yield UInt32(self, "shoff", "Section header offset")
|
|
yield UInt32(self, "flags", "Flags")
|
|
yield UInt16(self, "ehsize", "Elf header size (this header)")
|
|
yield UInt16(self, "phentsize", "Program header entry size")
|
|
yield UInt16(self, "phnum", "Program header entry count")
|
|
yield UInt16(self, "shentsize", "Section header entry size")
|
|
yield UInt16(self, "shnum", "Section header entre count")
|
|
yield UInt16(self, "shstrndx", "Section header strtab index")
|
|
|
|
def isValid(self):
|
|
if self["signature"].value != "\x7FELF":
|
|
return "Wrong ELF signature"
|
|
if self["class"].value not in self.CLASS_NAME:
|
|
return "Unknown class"
|
|
if self["endian"].value not in self.ENDIAN_NAME:
|
|
return "Unknown endian (%s)" % self["endian"].value
|
|
return ""
|
|
|
|
class SectionHeader32(FieldSet):
|
|
static_size = 40*8
|
|
TYPE_NAME = {
|
|
8: "BSS"
|
|
}
|
|
|
|
def createFields(self):
|
|
yield UInt32(self, "name", "Name")
|
|
yield Enum(UInt32(self, "type", "Type"), self.TYPE_NAME)
|
|
yield UInt32(self, "flags", "Flags")
|
|
yield textHandler(UInt32(self, "VMA", "Virtual memory address"), hexadecimal)
|
|
yield textHandler(UInt32(self, "LMA", "Logical memory address (in file)"), hexadecimal)
|
|
yield textHandler(UInt32(self, "size", "Size"), hexadecimal)
|
|
yield UInt32(self, "link", "Link")
|
|
yield UInt32(self, "info", "Information")
|
|
yield UInt32(self, "addr_align", "Address alignment")
|
|
yield UInt32(self, "entry_size", "Entry size")
|
|
|
|
def createDescription(self):
|
|
return "Section header (name: %s, type: %s)" % \
|
|
(self["name"].value, self["type"].display)
|
|
|
|
class ProgramHeader32(FieldSet):
|
|
TYPE_NAME = {
|
|
3: "Dynamic library"
|
|
}
|
|
static_size = 32*8
|
|
|
|
def createFields(self):
|
|
yield Enum(UInt16(self, "type", "Type"), ProgramHeader32.TYPE_NAME)
|
|
yield UInt16(self, "flags", "Flags")
|
|
yield UInt32(self, "offset", "Offset")
|
|
yield textHandler(UInt32(self, "vaddr", "V. address"), hexadecimal)
|
|
yield textHandler(UInt32(self, "paddr", "P. address"), hexadecimal)
|
|
yield UInt32(self, "file_size", "File size")
|
|
yield UInt32(self, "mem_size", "Memory size")
|
|
yield UInt32(self, "align", "Alignment")
|
|
yield UInt32(self, "xxx", "???")
|
|
|
|
def createDescription(self):
|
|
return "Program Header (%s)" % self["type"].display
|
|
|
|
def sortSection(a, b):
|
|
return int(a["offset"] - b["offset"])
|
|
|
|
#class Sections(FieldSet):
|
|
# def createFields?(self, stream, parent, sections):
|
|
# for section in sections:
|
|
# ofs = section["offset"]
|
|
# size = section["file_size"]
|
|
# if size != 0:
|
|
# sub = stream.createSub(ofs, size)
|
|
# #yield DeflateFilter(self, "section[]", sub, size, Section, "Section"))
|
|
# chunk = self.doRead("section[]", "Section", (Section,), {"stream": sub})
|
|
# else:
|
|
# chunk = self.doRead("section[]", "Section", (FormatChunk, "string[0]"))
|
|
# chunk.description = "ELF section (in file: %s..%s)" % (ofs, ofs+size)
|
|
|
|
class ElfFile(Parser):
|
|
PARSER_TAGS = {
|
|
"id": "elf",
|
|
"category": "program",
|
|
"file_ext": ("so", ""),
|
|
"min_size": ElfHeader.static_size, # At least one program header
|
|
"mime": (
|
|
u"application/x-executable",
|
|
u"application/x-object",
|
|
u"application/x-sharedlib",
|
|
u"application/x-executable-file",
|
|
u"application/x-coredump"),
|
|
"magic": (("\x7FELF", 0),),
|
|
"description": "ELF Unix/BSD program/library"
|
|
}
|
|
endian = LITTLE_ENDIAN
|
|
|
|
def validate(self):
|
|
err = self["header"].isValid()
|
|
if err:
|
|
return err
|
|
return True
|
|
|
|
def createFields(self):
|
|
# Choose the right endian depending on endian specified in header
|
|
if self.stream.readBits(5*8, 8, BIG_ENDIAN) == ElfHeader.BIG_ENDIAN_ID:
|
|
self.endian = BIG_ENDIAN
|
|
else:
|
|
self.endian = LITTLE_ENDIAN
|
|
|
|
# Parse header and program headers
|
|
yield ElfHeader(self, "header", "Header")
|
|
for index in xrange(self["header/phnum"].value):
|
|
yield ProgramHeader32(self, "prg_header[]")
|
|
|
|
if False:
|
|
raise ParserError("TODO: Parse sections...")
|
|
#sections = self.array("prg_header")
|
|
#size = self["header/shoff"].value - self.current_size//8
|
|
#chunk = self.doRead("data", "Data", (DeflateFilter, stream, size, Sections, sections))
|
|
#chunk.description = "Sections (use an evil hack to manage share same data on differents parts)"
|
|
#assert self.current_size//8 == self["header/shoff"].value
|
|
else:
|
|
raw = self.seekByte(self["header/shoff"].value, "raw[]", relative=False)
|
|
if raw:
|
|
yield raw
|
|
|
|
for index in xrange(self["header/shnum"].value):
|
|
yield SectionHeader32(self, "section_header[]")
|
|
|
|
def createDescription(self):
|
|
return "ELF Unix/BSD program/library: %s" % (
|
|
self["header/class"].display)
|
|
|