All pastes #368639 Raw Edit

Anonymous

public python v1 · immutable
#368639 ·published 2007-02-23 06:14 UTC
rendered paste body
# Copyright 2006 Falling Leaf Systems, LLC.# Refer to LICENSE in the root directory.                import structfrom fileformat import *PT_NULL = 0     PT_LOAD = 1PT_DYNAMIC = 2  PT_INTERP = 3   PT_NOTE = 4     PT_SHLIB = 5    PT_PHDR = 6     PT_LOOS = 0x60000000PT_HIOS = 0x6fffffffPT_LOPROC = 0x70000000PT_HIPROC = 0x7fffffffPT_GNU_EH_FRAME = 0x6474e550                 ET_NONE = 0     ET_REL = 1ET_EXEC = 2     ET_DYN = 3      ET_CORE = 4ET_LOPROC = 0xff00ET_HIPROC = 0xffff                        EM_NONE = 0EM_M32 = 1      EM_SPARC = 2            EM_386 = 3              EM_68K = 4      EM_88K = 5EM_486 = 6EM_860 = 7                      class ELF(FileFormat):        capabilities = (FILEFORMAT_WRITE, FILEFORMAT_READ)                        def read(self, fp):                """                Read file from given file pointer                                        @param  fp:             File pointer toinput file                @type   fp:             C{file}                @return:           This L{FileFormat} object after reading from the file                @rtype:            L{FileFormat}                """                                assert(fp.read(4) == '\x7FELF')                                e_ident = fp.read(12)                                filetype, machine, version,\                 entry, phoff,shoff,\                flags, ehsize, phentsize,\                 phnum, shentsize, shnum,\                shstrndx                    = struct.unpack('<HHLLLLLHHHHHH', fp.read(36))                                self.entry_point = entry                                fp.seek(shoff+(shentsize*shstrndx)+16)                strndxaddr = struct.unpack('<L', fp.read(4))[0]                fp.seek(shoff+(shentsize*shstrndx)+20)                strndxlen  = struct.unpack('<L', fp.read(4))[0]                                                fp.seek(strndxaddr)                self.strtab = fp.read(strndxlen)                                fp.seek(phoff)                for i in range(phnum):                        self.readPhdr(fp)                for i in range(shnum - 1):                        fp.seek(shoff+(shentsize*i))                        self.readShdr(fp)                # assert(True != True)        def write(self, fp):                """                Write file to given file pointer                @param  fp:             File pointer to output file                @type   fp:             C{file}                """                if self.is_shared:                        filetype = ET_DYN                else:                        filetype = ET_REL # ET_EXEC                machine = EM_386                version = 1                entry = self.entry_point                flags = 0                ehsize = 52 # sizeof(Elf32'Ehdr)                phentsize = 32 # sizeof(Elf32.Phdr)                phnum = len(self.sections)                shentsize = 40 # sizeof(Elf32.Shdr)                shnum = len(self.sections) + 2 + 1 # For symtab                phoff = ehsize                shoff = phoff + (phentsize * phnum)                shstrndx = shnum - 1                fp.write('\x7FELF')                fp.write('\x01\x01\x01' + ('\x00' * 9)) # Rest of e'ident                fp.write(                        struct.pack('<HHLLLLLHHHHHH',                                filetype, machine, version,                                entry, phoff, shoff,                                flags, ehsize, phentsize,                                phnum, shentsize, shnum,                                shstrndx                        )                )                shstr = '\0'                fileoff = shoff + (shentsize * shnum)                for sec in self.sections:                        fp.write(self.writePhdr(sec, fileoff=fileoff))                        fileoff += len(sec.data)                fileoff = shoff + (shentsize * shnum)                fp.write(                        struct.pack('<LLLLLLLLLL',                                0, 0, 0, 0, 0,                                0, 0, 0, 0, 0                        )                )                used_segments = []                for sec in self.sections:                        fp.write(self.writeShdr(sec, fileoff=fileoff, nameoff=len(shstr)))                        fileoff += len(sec.data)                        name = sec.name.lower()                        name = name.replace('.', '')                        name = name.replace('alky', '')                        name = '.alky' + name                        while name in used_segments:                                name += '_'                        used_segments.append(name)                        sec.name = name                        shstr += '%s\0' % name                temp = len(shstr)                shstr += '.symtab\0'                symtab = self.writeSymTab(nameoff=len(shstr))                for sym in self.symbols:                        shstr += sym + '\0'                link = shstrndx                info = len(self.symbols) + 1                fp.write(                        struct.pack('<LLLLLLLLLL',                                temp, 2, 0x7,                                0, fileoff, len(symtab),                                link, info, 0, 16                        )                )                fileoff += len(symtab)                fp.write(                        struct.pack('<LLLLLLLLLL',                                0, 3, 0x7,                                0, fileoff, len(shstr),                                0, 0, 0, 0                        )                )                for sec in self.sections:                        fp.write(sec.data)                fp.write(symtab)                fp.write(shstr)        def writePhdr(self, sec, fileoff):                type = PT_LOAD                return struct.pack('<LLLLLLLL',                        type, fileoff, sec.addr,                        0, len(sec.data), sec.size,                        0x7, 2                )        def readPhdr(self, fp):                type, fileoff, addr,\                unk, data_len, data_size,\                prot, unk2                = struct.unpack('<LLLLLLLL', fp.read(32))                return True        def writeShdr(self, sec, fileoff=0, nameoff=0):                return struct.pack('<LLLLLLLLLL',                        nameoff, 1, 0x7,                        sec.addr, fileoff, len(sec.data),                        0, 0, 2, 0                )        def readShdr(self, fp):                nameoff, unk, prot,\                addr, fileoff, data_len,\                unk2, unk3, unk4, unk5   = struct.unpack('<LLLLLLLLLL', fp.read(40))                if nameoff != 0:                        name = self.strtab[nameoff:].split('\0', 1)[0]                else:                        name = None                if not name:                        return False                fp.seek(fileoff)                data = fp.read(data_len)                sec = Section(name, addr, data, data_len, prot)                self.addSection(sec)                return True        def writeSymTab(self, nameoff):                symtab = []                symtab.append((0, 0, 0, 0, 0))                for sym in self.symbols:                        ordinal, addr = self.symbols[sym]                        typ = (1 << 4) | 2                        i = -1                        for sec in self.sections:                                if addr >= sec.addr and addr < sec.addr + sec.size:                                        section = i                                        break                                i += 1                        if i == -1:                                i = 0xfffe                        symtab.append((nameoff, addr, 0, typ, section))                        nameoff += len(sym) + 1                data = ''                for sym in symtab:                        data += struct.pack('<LLLHH', *sym)                return data