Пример #1
0
 def __init__(self):
     self.logger = Logger("Reader")
     if isinstance(self.FORMAT_SPEC, str):
         self.formats = [FormatParser(self.FORMAT_SPEC, self.DATA_SEPARATOR).parse()]
     elif isinstance(self.FORMAT_SPEC, (list, tuple)):
         self.formats = []
         for format_type, format in self.FORMAT_SPEC:
             self.formats.append((format_type, FormatParser(format, self.DATA_SEPARATOR).parse()))
Пример #2
0
    def __init__(self, filename):
        self.fp = createMemoryMappedFileView(filename)
        self.header = ELFHeader(self)
        self.is64Bit = self.header.is64Bit

        self.programHeaders = []
        self.sectionHeaders = []
        self._sectionHeadersByName = {}
        self._stringCache = {}
        self.symbols = OrderedDict()
        self.logger = Logger("ELF")

        pos = self.header.e_phoff
        if pos:
            for _ in range(self.header.elfNumberOfPHs):
                self.programHeaders.append(ELFProgramHeaderTable(self, pos))
                pos += self.header.elfPHTEntrySize

        pos = self.header.e_shoff
        if pos:
            for _ in range(self.header.elfNumberOfSHs):
                self.sectionHeaders.append(ELFSectionHeaderTable(self, pos))
                pos += self.header.elfSHTEntrySize

        for idx, sectionHeader in enumerate(self.sectionHeaders):
            if sectionHeader.shType in (defs.SHT_SYMTAB, defs.SHT_DYNSYM):
                for _, symbol in sectionHeader.symbols.items():
                    symbol.sectionName = getSpecialSectionName(symbol.st_shndx)
            elif sectionHeader.shType in (defs.SHT_REL, defs.SHT_RELA):
                symtab = sectionHeader.shLink
                sectionToModify = sectionHeader.shInfo
                offset = 0

                if sectionHeader.shType == defs.SHT_REL:
                    format = defs.REL_FMT64 if self.is64Bit else defs.REL_FMT32
                    entrySize = defs.ELF_RELOCATION_SIZE64 if self.is64Bit else defs.ELF_RELOCATION_SIZE32
                    elfRelocation = Attributor(format, defs.Elf_Rel,
                                               self.byteOrderPrefix)
                else:
                    format = defs.RELA_FMT64 if self.is64Bit else defs.RELA_FMT32
                    entrySize = defs.ELF_RELOCATION_A_SIZE64 if self.is64Bit else defs.ELF_RELOCATION_A_SIZE32
                    elfRelocation = Attributor(format, defs.Elf_Rela,
                                               self.byteOrderPrefix)
                img = sectionHeader.image
                for pos in range(len(img) // entrySize):
                    data = img[offset:offset + entrySize]
                    reloc = Relocation(self.is64Bit)
                    elfRelocation.apply(data, reloc)
                    offset += entrySize
            elif sectionHeader == defs.SHT_NOTE:
                pass
        for section in self.sectionHeaders:
            name = self.getString(self.header.elfStringTableIndex,
                                  section.shNameIdx)
            section._name = name
            self._sectionHeadersByName[name] = section
        self.createSectionToSegmentMapping()
        self.buildSymbols()
Пример #3
0
class Writer(object):
    """
    """

    logger = Logger(__name__)

    def dump(self, fp, image, **kws):
        if isinstance(fp, str):
            fp = open(fp, "wb")
        fp.write(self.dumps(image))
        if hasattr(fp, "close"):
            fp.close()

    def dumps(self, image, **kws):
        BLOCK_SIZE = 16
        result = []
        result.append('<?xml version="1.0" encoding="UTF-8"?>')
        result.append(
            '<dump name="SHF dump by objutils" blocks="{:04x}">'.format(
                len(image._sections)))
        if hasattr(image, "sections") and not image.sections:
            return b''
        sections = sorted(image.sections, key=lambda x: x.start_address)
        for idx, section in enumerate(sections):
            result.append('    <block name="Section #{:04x}" address="{:08x}" word_size="01" length="{:08x}" checksum="{}">'.\
                format(idx, section.start_address, section.length, SHA1_DIGEST(section.data)))
            nblocks = len(section.data) // BLOCK_SIZE
            remaining = len(section.data) % BLOCK_SIZE
            offset = 0
            for _ in range(nblocks):
                result.append("        {}".format(" ".join([
                    "{:02x}".format(x)
                    for x in section.data[offset:offset + BLOCK_SIZE]
                ])))
                offset += BLOCK_SIZE
            if remaining:
                result.append("        {}".format(" ".join([
                    "{:02x}".format(x)
                    for x in section.data[offset:offset + remaining]
                ])))
            result.append('    </block>')
        result.append("</dump>")
        return bytes("\n".join(result), encoding="ascii")
Пример #4
0
    def __init__(self, inFile):
        if not hasattr(inFile, 'read'):
            raise TypeError("Need a file-like object.")
        self.logger = Logger("IEEE695")
        self.inFile = inFile
        self.info = Info()
        self.info.ASWs={}
        self.fpos = 0
        self.blockType = []
        self.finished = False
        self.symbols = {}
        self.externalSymbols = {}
        self.sections = {}
        self.nnRecords = {}
        self.contexts = {}
        diRoot = DebugInformation()
        diRoot.parent = None
        diRoot.name = "ROOT"
        self.debugInformation = [diRoot]
        self.diParents = [diRoot]
        self.currentSection = None
        self.currentSectionIndex = None
    ####
        self._nb = 0
        self.dbCollection = bytearray()

        while not self.finished:
            cc = self.readByte(self.fpos)
            if cc == MB:
                self.onModuleBegin()
            elif cc == AD:
                self.onAD()
            elif cc == E2:
                self.onE2()
            elif cc == NX:
                self.onNX()
            elif cc == WX:
                self.onWX()
            elif cc == NN:
                self.onNN()
            elif cc == F1:
                self.onF1()
            elif cc == ST:
                self.onST()
            elif cc == NC:
                self.onNC()
            elif cc == SA:
                self.onSA()
            elif cc == NI:
                self.onNI()
            elif cc == BB:
                self.onBB()
            elif cc == BE:
                self.onBE()
            elif cc == TY:
                self.onTY()
            elif cc == SB:
                self.onSB()
            elif cc == LD:
                self.onLD()
            elif cc == ME:
                self.onME()
            else:
                raise NotImplementedError("0x{0:02X}".format(cc))
Пример #5
0
class Reader(object):

    def __init__(self, inFile):
        if not hasattr(inFile, 'read'):
            raise TypeError("Need a file-like object.")
        self.logger = Logger("IEEE695")
        self.inFile = inFile
        self.info = Info()
        self.info.ASWs={}
        self.fpos = 0
        self.blockType = []
        self.finished = False
        self.symbols = {}
        self.externalSymbols = {}
        self.sections = {}
        self.nnRecords = {}
        self.contexts = {}
        diRoot = DebugInformation()
        diRoot.parent = None
        diRoot.name = "ROOT"
        self.debugInformation = [diRoot]
        self.diParents = [diRoot]
        self.currentSection = None
        self.currentSectionIndex = None
    ####
        self._nb = 0
        self.dbCollection = bytearray()

        while not self.finished:
            cc = self.readByte(self.fpos)
            if cc == MB:
                self.onModuleBegin()
            elif cc == AD:
                self.onAD()
            elif cc == E2:
                self.onE2()
            elif cc == NX:
                self.onNX()
            elif cc == WX:
                self.onWX()
            elif cc == NN:
                self.onNN()
            elif cc == F1:
                self.onF1()
            elif cc == ST:
                self.onST()
            elif cc == NC:
                self.onNC()
            elif cc == SA:
                self.onSA()
            elif cc == NI:
                self.onNI()
            elif cc == BB:
                self.onBB()
            elif cc == BE:
                self.onBE()
            elif cc == TY:
                self.onTY()
            elif cc == SB:
                self.onSB()
            elif cc == LD:
                self.onLD()
            elif cc == ME:
                self.onME()
            else:
                raise NotImplementedError("0x{0:02X}".format(cc))


    def setCurrentSectionIndex(self, index):
        self.currentSectionIndex = index

    def checkSectionIndex(self, index):
        if  self.currentSectionIndex is None:
            print("No current Section Index.")
        elif self.currentSectionIndex != index:
            print
            print("Invalid Section Index.")


    def readByte(self, offset):
        "Read 8bit quantity"
        self.inFile.seek(offset, os.SEEK_SET)
        result = ord(self.inFile.read(1))
        self.fpos = self.inFile.tell()
        return result

    def readWord(self, offset):
        "Read 16bit quantity"
        self.inFile.seek(offset, os.SEEK_SET)
        h = ord(self.inFile.read(1))
        l = ord(self.inFile.read(1))
        self.fpos = self.inFile.tell()
        return h << 8 | l

    def readNumber(self, offset):
        "Read number of abitrary length"
        self.inFile.seek(offset, os.SEEK_SET)
        typecode = self.readByte(offset)
        if typecode <= SMALL_NUMBER:
            # length: [0..127]
            result = typecode
        elif 0x80 <= typecode <= 0x88:
            # length (in bytes) [0..8]
            length = typecode & ~0x80
            data = self.inFile.read(length)
            self.fpos = self.inFile.tell()
            result = reduce(lambda x, y: (x * 256) + ord(y), data, 0)
        return result

    def readString(self, offset):
        typecode = self.readByte(offset)

        if typecode <= SHORT_STRING:
            # length: [0..127]
            length = typecode
        elif typecode == 0xde:
            # length: [0..255]
            length = self.readByte(offset + 1)
        elif typecode == 0xdf:
            # length: [0..65535]
            length = self.readWord(offset + 1)
        else:
            raise TypeError("Invalid typecode [{0:02x}].".format(typecode))
        result = self.inFile.read(length)
        self.fpos = self.inFile.tell()
        return result

    def readCharacter(self, offset):
        result = chr(self.readByte(offset) - 0x80)
        if ord(result) > ord('Z'):
            result = None
        return result

    def checkOptional(self, offset, isString = False):
        "Read and maybe putback"
        cc = self.readByte(offset)
        if cc >= COMMAND_CODE:
            self.inFile.seek(offset, os.SEEK_SET)   # Put back.
            self.fpos = offset
            return None
        if isString == True:
            self.inFile.seek(offset, os.SEEK_SET)   # Put back.
            self.fpos = offset
            return self.readString(offset)
        else:
            if 0xC0 <= cc <= 0xDA:
                result = chr(cc - 0x80)
                if ord(result) > ord('Z'):
                    result = None
            else:
                return self.readNumber(offset)

    def symbolByName(self, name):
        pass

    def symbolByIndex(self, index):
        pass

################################
################################
################################
    def onModuleBegin(self):
        "{$E0}{Id1}{Id2}"
        self.info.processor = self.readString(self.fpos)
        self.info.module = self.readString(self.fpos)

        self.logger.debug("PROCESSOR: '{0!s}' MODULE: '{1!s}'.".format(self.info.processor, self.info.module))

    def onAD(self):
        "$EC}{n1}{n2}[a]"
        self.info.numberOfBits = self.readNumber(self.fpos)
        self.info.numberOfMAUs = self.readNumber(self.fpos)
        self.info.adressWidth = self.info.numberOfBits * self.info.numberOfMAUs
        self.info.byteOrder = self.checkOptional(self.fpos)

    def onE2(self):
        "{$E2}{$D7}{0x}{n}"
        """
        ASR     = 0xD2    # Variable Values.
        """
        discr = self.readByte(self.fpos)
        if discr == ASW:
            addr = self.readByte(self.fpos)
            byteOffset = self.readNumber(self.fpos)
            self.info.ASWs[addr] = (ASWAssignment[addr], byteOffset)
        elif discr == ASS:
            sectionIndex = self.readNumber(self.fpos)
            self.checkSectionIndex(sectionIndex)
            self.sections[sectionIndex].sectionSize = self.readNumber(self.fpos)
            self.logger.debug("Section-Size: 0x{0:04x}".format(self.sections[sectionIndex].sectionSize))
        elif discr == ASA:
            sectionIndex = self.readNumber(self.fpos)
            self.checkSectionIndex(sectionIndex)
            self.sections[sectionIndex].regionSize.append(self.readNumber(self.fpos))
        elif discr == ASB:
            sectionIndex = self.readNumber(self.fpos)
            self.checkSectionIndex(sectionIndex)
            self.sections[sectionIndex].physicalAddress.append(self.readNumber(self.fpos))
        elif discr == ASR:
            sectionIndex = self.readNumber(self.fpos)
            self.checkSectionIndex(sectionIndex)
            self.sections[sectionIndex].sectionOffset.append(self.readNumber(self.fpos))
        elif discr == ASF:
            sectionIndex = self.readNumber(self.fpos)
            self.checkSectionIndex(sectionIndex)
            self.sections[sectionIndex].mauSize = self.readNumber(self.fpos)
            self.logger.debug("MAU-Size: 0x{0:04x}".format(self.sections[sectionIndex].mauSize))
        elif discr == ASL:
            sectionIndex = self.readNumber(self.fpos)
            self.checkSectionIndex(sectionIndex)
            self.sections[sectionIndex].sectionBaseAddr = self.readNumber(self.fpos)
            self.logger.debug("Section-BaseAddr: 0x{0:04x}".format(self.sections[sectionIndex].sectionBaseAddr))
        elif discr == ASM:
            sectionIndex = self.readNumber(self.fpos)
            self.checkSectionIndex(sectionIndex)
            self.sections[sectionIndex].mValue = self.readNumber(self.fpos)
        elif discr == ASI:
            # There may be more than one ASI/ATI record pair for a single
            # name since constants defined in SETs and #defines my be redefined repeatedly.
            symbolIndex = self.readNumber(self.fpos)
            expr = self.readNumber(self.fpos)
            self.symbols[symbolIndex].expr = expr
        elif discr == ASN:
            symbolNameIndex = self.readNumber(self.fpos)
            symbolTypeIndex = self.readNumber(self.fpos)
        elif discr == ASP:
            sectionIndex = self.readNumber(self.fpos)   #? check sec-Index!!?
            newValue = self.readNumber(self.fpos)
        elif discr == ASG:
            delim = self.readByte(self.fpos)
            if delim != 0xBE:
                pass    # todo: FormatError!!!
            executionStartingAddr = self.readNumber(self.fpos)
            self.logger.debug("STARTING-ADDRESS: 0x{0:04X}".format(executionStartingAddr))
            delim = self.readByte(self.fpos)
            if delim != 0xBF:
                pass    # todo: FormatError!!!
            self.info.executionStartingAddr = executionStartingAddr
        else:
            raise NotImplementedError(hex(discr))

    def onNN(self):
        "{$F0}{n1}{Id}"
        symbolType = self.readNumber(self.fpos)
        symbolName = self.readString(self.fpos)

        self.nnRecords[symbolType] = Info()
        self.nnRecords[symbolType].name = symbolName
        self.nnRecords[symbolType].atn = {}

        #self.logger.debug("Symbol-Type: 0x%02x Name: '%s'" % (symbolType, symbolName))

    def onNX(self):
        "{$E9}{n1}{Id}"
        externalReferenceIndex = self.readNumber(self.fpos)
        symbolName = self.readString(self.fpos)
        self.externalSymbols[externalReferenceIndex] = Info()
        self.externalSymbols[externalReferenceIndex].symbolName = symbolName

    def onWX(self):
        "{$F4}{n1}{n2}{n3}"
        externalReferenceIndex = self.readNumber(self.fpos)
        defaultSize = self.readNumber(self.fpos)
        defaultValue = self.readNumber(self.fpos)
        self.externalSymbols[externalReferenceIndex].defaultSize = defaultSize
        self.externalSymbols[externalReferenceIndex].defaultValue = defaultValue

    def onF1(self):
        """
            ATI     = 0xF1C9    # Variable Attribute.
            ATX     = 0xF1D8    # External Reference Relocation Information.
            ATN     = 0xF1CE    # Variable Attributes.
        """
        discr = self.readByte(self.fpos)
        if discr == ATI:
            numberOfElements = 0
            symbolNameIndex = self.readNumber(self.fpos)
            symbolTypeIndex =self.readNumber(self.fpos)
            attrDef =self.readNumber(self.fpos)
            if attrDef == 8:
                pass
            elif attrDef == 16:
                symbolClass = self.readNumber(self.fpos)
                publicLocalIndicator =  self.checkOptional(self.fpos)
                numericValue = self.checkOptional(self.fpos)
                stringValue = self.checkOptional(self.fpos)

                self.symbols[symbolNameIndex].symbolClass = symbolClass
                self.symbols[symbolNameIndex].publicLocalIndicator = publicLocalIndicator
                self.symbols[symbolNameIndex].numericValue = numericValue
                self.symbols[symbolNameIndex].stringValue = stringValue
            elif attrDef == 19:
                pass
            else:
                pass    # todo: FormatError!!!
##            n4 =self.readNumber(self.fpos) # If n2 is non-zero, number of elements in the symbol type specified in n2
            if symbolTypeIndex != 0:
                numberOfElements = self.readNumber(self.fpos)
            self.symbols[symbolNameIndex].symbolTypeIndex = symbolTypeIndex
            self.symbols[symbolNameIndex].numberOfElements = numberOfElements
            self.symbols[symbolNameIndex].attrDef = attrDef
        elif discr == ATX:
            externalReferenceIndex = self.readNumber(self.fpos)
            typeIndex = self.readNumber(self.fpos)
            sectionIndex = self.readNumber(self.fpos)
            shortExternalFlag = self.readNumber(self.fpos)
            self.externalSymbols[externalReferenceIndex].typeIndex = typeIndex
            self.externalSymbols[externalReferenceIndex].sectionIndex = sectionIndex
            self.externalSymbols[externalReferenceIndex].shortExternalFlag = shortExternalFlag
        elif discr == ATN:  # todo: onATN
            symbolNameIndex = self.readNumber(self.fpos)
            symbolTypeIndex =self.readNumber(self.fpos)
            attrDef =self.readNumber(self.fpos)
            if attrDef == 1:
                stackOffset = self.readNumber(self.fpos)
            elif attrDef == 2:
                registerIndex = self.readNumber(self.fpos)
            elif attrDef == 3:
                pass
#            elif attrDef == 4:
#                pass
            elif attrDef == 7:
                lineNumber = self.readNumber(self.fpos)
                columnNumber = self.readNumber(self.fpos)
                res1 = self.checkOptional(self.fpos)
                res2 = self.checkOptional(self.fpos)
            elif attrDef == 8:
                pass
            elif attrDef == 9:
                absoluteProgramCounterOffset = self.readNumber(self.fpos)
                ##if symbolNameIndex == 0:
                ##    registerResourceIndex = self.readByte(self.fpos)
            elif attrDef == 10:
                registerIndex = self.readNumber(self.fpos)
                frameOffset = self.readNumber(self.fpos)
#            elif attrDef == 11:
#                pass
            elif attrDef == 19:
                numberOfElements = self.readNumber(self.fpos)
                localGlobal = self.checkOptional(self.fpos)
            elif attrDef == 37:
                self.info.objectFormatVersionNumber = self.readNumber(self.fpos)
                self.info.objectFormatRevisionLevel  = self.readNumber(self.fpos)
            elif attrDef == 38:
                self.info.objectFormatType=ObjectFormatTypes[self.readNumber(self.fpos)]
            elif attrDef == 39:
                self.info.symbolCaseSensitivity = CaseSensitivity[self.readNumber(self.fpos)]
            elif attrDef == 40:
                self.info.memoryModel = MemoryModel[self.readNumber(self.fpos)]
            elif attrDef == 50:
                year = self.readNumber(self.fpos)
                month = self.readNumber(self.fpos)
                day = self.readNumber(self.fpos)
                hour = self.readNumber(self.fpos)
                minute = self.readNumber(self.fpos)
                second = self.readNumber(self.fpos)
                self.info.creationDate = datetime(year, month, day, hour, minute, second)
            elif attrDef == 51:
                self.info.commandLine = self.readString(self.fpos)
            elif attrDef == 52:
                self.info.executionStatus = self.readNumber(self.fpos)
            elif attrDef == 53:
                self.info.hostEnvironment = self.readNumber(self.fpos)
            elif attrDef == 54:
                tool = self.readNumber(self.fpos)
                version = self.readNumber(self.fpos)
                revision = self.readNumber(self.fpos)
                revisionLevel = self.checkOptional(self.fpos)   # single IEEE-695 letter in the range $C1-$DA
            elif attrDef == 55:
                self.info.comments = self.readString(self.fpos)
            elif attrDef == 64:
                typeIdent = self.readNumber(self.fpos)
                addATN = self.readNumber(self.fpos)
            elif attrDef == 65:
                miscString = self.readString(self.fpos)
            else:
                raise NotImplementedError("Invalid ATN-Attr: 0x{0:02x}".format(attrDef))
                # todo: FormatError
        else:
            raise NotImplementedError(hex(discr))
            # todo: FormatError

    def onST(self):
        "${E6}{n1}{l}[Id][n2][n3][n4]"
        sectionIndex = self.readByte(self.fpos)
        self.setCurrentSectionIndex(sectionIndex)
        f = self.readCharacter(self.fpos)
        if f == 'A':
            s, t = self.readCharacter(self.fpos), self.readCharacter(self.fpos)
            sectionType = f + s + t
        elif f == 'B':
            pass
        elif f == 'C':
            pass
        elif f == 'E':
            pass # todo: 'EA' / 'EZ' !!!
        elif f == 'M':
            pass
        elif f == 'T':
            pass
        #todo: 'ZC' / 'ZM'.
        else:
            raise NotImplementedError("SEG-TYPE: {0!s}".format(f))

        sectionName = self.readString(self.fpos)
        parentSectionIndex = self.checkOptional(self.fpos)

        if f == 'T':
            brotherSectionIndex = self.readNumber(self.fpos)

        if f in ('B', 'T'):
            contextIndex = self.readNumber(self.fpos)

        self.sections[sectionIndex] = Section(sectionType, sectionName, parentSectionIndex)
        self.logger.debug("SECTION [{0!s}:{1!s}]".format(sectionType, sectionName))
        # SA, ASA, ASB, ASF, ASL, ASM, ASR, and ASS records must appear after the ST record they refer to.
        '''
        ASP absolute code
        ASR absolute ROM data
        ASD absolute data

        CP code
        CR ROM data
        CD data

        EAP common absolute code
        EAR common absolute ROM data
        EAD common absolute data

        ZCP  short code
        ZCR  short ROM data
        ZCD  short data
        '''

    def onNC(self):
        "{$FB}{n1}{Id}"
        contextIndex = self.readNumber(self.fpos)
        contextName = self.readString(self.fpos)
        self.contexts[contextIndex] = contextName

    def onSA(self):
        "{$E7}{n1}[n2][n3]"
        sectionIndex = self.readByte(self.fpos)
        self.checkSectionIndex(sectionIndex)
        boundaryAlignmentDivisor = self.checkOptional(self.fpos)
        self.sections[sectionIndex].boundaryAlignment = 2 ** boundaryAlignmentDivisor
        self.sections[sectionIndex].pageSize  = self.checkOptional(self.fpos)

    def onNI(self):
        "{$E8}{n}{Id}"
        nameIndex = self.readNumber(self.fpos)  # must be > 31, 0 - 31 reserved.
        symbolName = self.readString(self.fpos)
        info = Info()
        info.nameIndex = nameIndex
        info.symbolName = symbolName
        self.symbols[nameIndex] = info
        self.logger.debug("SYMBOL: {0!s}".format(symbolName)) # followed by ASI.

    def onBB(self):
        blockType = self.readByte(self.fpos)
        blockSize = self.readNumber(self.fpos)
        info = DebugInformation()
        info.parent = self.diParents[-1]
        info.blockType = blockType
        info.blockSize = blockSize
        if blockSize == 0:
            pass
        if blockType == BB1:
            self.blockType.append(1)
            module_name = self.readString(self.fpos)
            info.module_name = module_name
            info.name = "BB1"
            self.logger.debug("MODULE-NAME: {0!s}".format(module_name))
        elif blockType == BB2:
            self.blockType.append(2)
            zeroLengthName = self.readString(self.fpos)
            info.zeroLengthName = zeroLengthName
            info.name = "BB2"
        elif blockType == BB3:
            self.blockType.append(3)
            module_name = self.readString(self.fpos)
            info.module_name = module_name
            info.name = "BB3"
        elif blockType == BB4:
            self.blockType.append(4)
            functionName = self.readString(self.fpos)
            stackSpaceRequired = self.readNumber(self.fpos)
            typeIndexOfReturnValue = self.readNumber(self.fpos)
            offsetExpr = self.readNumber(self.fpos)
            info.functionName = functionName
            info.stackSpaceRequired = stackSpaceRequired
            info.typeIndexOfReturnValue = typeIndexOfReturnValue
            info.offsetExpr = offsetExpr
            info.name = "BB4"
        elif blockType ==  BB5:
            self.blockType.append(5)
            sourceFilename = self.readString(self.fpos)
            year = self.checkOptional(self.fpos)    # todo: factor-out (namedtuple)!!!
            month = self.checkOptional(self.fpos)
            day = self.checkOptional(self.fpos)
            hour = self.checkOptional(self.fpos)
            minute = self.checkOptional(self.fpos)
            second = self.checkOptional(self.fpos)
            info.sourceFilename = sourceFilename
            info.year = year
            info.month = month
            info.day = day
            info.hour = hour
            info.minute = minute
            info.second = second
            info.name = "BB5"
        elif blockType ==  BB6:
            self.blockType.append(6)
            functionName = self.readString(self.fpos)
            stackRequired = self.readNumber(self.fpos)
            typeIndexForReturnValue = self.readNumber(self.fpos)
            offsetExpr = self.readNumber(self.fpos)
            info.functionName = functionName
            info.stackRequired = stackRequired
            info.typeIndexForReturnValue = typeIndexForReturnValue
            info.offsetExpr = offsetExpr
            info.name = "BB6"
        elif blockType == BB10:
            self.blockType.append(10)
            module_name = self.readString(self.fpos)
            objFileName = self.readString(self.fpos)
            toolType = self.readNumber(self.fpos)
            versionRevision = self.checkOptional(self.fpos, isString = True)
            year = self.checkOptional(self.fpos)
            month = self.checkOptional(self.fpos)
            day = self.checkOptional(self.fpos)
            hour = self.checkOptional(self.fpos)
            minute = self.checkOptional(self.fpos)
            second = self.checkOptional(self.fpos)
            info.module_name = module_name
            info.objFileName = objFileName
            info.toolType = toolType
            info.versionRevision = versionRevision
            info.year = year
            info.month = month
            info.day = day
            info.hour = hour
            info.minute = minute
            info.second = second
            info.name = "BB10"
        elif blockType ==  BB11:
            self.blockType.append(11)
            zeroLengthName = self.readString(self.fpos)
            sectionType = self.readNumber(self.fpos)
            sectionIndex = self.readNumber(self.fpos)
            offsetExpr = self.readNumber(self.fpos)
            dummy = self.readByte(self.fpos)   # $90 - Comma operator!!!
            sectionMapping = self.readNumber(self.fpos)
            info.zeroLengthName = zeroLengthName
            info.sectionType = sectionType
            info.sectionIndex = sectionIndex
            info.offsetExpr = offsetExpr
            info.dummy = dummy
            info.sectionMapping = sectionMapping
            info.name = "BB11"
        elif blockType ==  BB20:
            self.blockType.append(20)
            raise NotImplementedError('BB20')
        parent = self.diParents[-1]
        parent.add(info)
        self.diParents.append(info)
        self.logger.debug(" " * len(self.diParents), "BB{0:d}".format(blockType))

    def onBE(self):
        blockType = self.blockType.pop()
        self.diParents.pop()
        if  blockType in (4, 6):
            functionEndAddr = self.readNumber(self.fpos)
        elif blockType == 11:
            moduleSectionSize = self.checkOptional(self.fpos)

    def onTY(self):
        ""
        typeIndex = self.readNumber(self.fpos)
        if self.readByte(self.fpos) != 0xCE:
            pass    # todo: raise FormatError!!
        localNameIndex = self.readNumber(self.fpos)
        values = []
        while True:
            value = self.checkOptional(self.fpos)
            if value is None:
                break
            else:
                values.append(value)

    def onSB(self):
        "{$E5}{n1}"
        sectionIndex = self.readNumber(self.fpos)
        sec = self.sections[sectionIndex]
        self.logger.debug("Data for section: '{0!s}'. {1:d} bytes of data to follow.".format(
            sec.sectionName, sec.sectionSize
        ))

    def onLD(self):
        "{$ED}{n1}{...}"
        numberOfMAUs = self.readNumber(self.fpos)
        data = self.inFile.read((numberOfMAUs * self.info.numberOfBits) / 8)
        self.logger.debug("reading {0:d} bytes".format(len(data)))


        # SB ASP LD
        self._nb += len(data)
        self.dbCollection.extend(data)

        self.fpos = self.inFile.tell()


    def onME(self):
        "Module End Record Type"
        self.finished = True
        self.logger.debug("{0:d} Data-Bytes.".format(self._nb))
Пример #6
0
 def __init__(self):
     self.logger = Logger("Writer")
Пример #7
0
class Reader(object):
    """
    """

    logger = Logger(__name__)

    def load(self, fp):
        if isinstance(fp, str):
            fp = open(fp, "rb")
        data = fp.read()
        root = ET.fromstring(data)
        sections = []
        for idx, child in enumerate(root):
            tag = child.tag
            attrib = child.attrib
            text = remove_ws(child.text)
            section_data = bytearray.fromhex(text)
            name = attrib.get('name')
            if name is None:
                self.logger.error(
                    "Block #{}: Missing required attribute `name`.".format(
                        idx))
                continue
            address = attrib.get('address')
            if address:
                address = remove_ws(address)
                address = int(address, 16)
            else:
                self.logger.error(
                    "Block #{}: Missing required attribute `address`.".format(
                        idx))
                continue
            length = attrib.get('length')
            if length:
                length = remove_ws(length)
                length = int(length, 16)
            else:
                self.logger.error(
                    "Block #{}: Missing required attribute `length`.".format(
                        idx))
                continue
            word_size = attrib.get('word_size')
            if word_size:
                word_size = remove_ws(word_size)
                word_size = int(word_size, 16)
            else:
                self.logger.error(
                    "Block #{}: Missing required attribute `wordsize`.".format(
                        idx))
                continue
            if len(section_data) != (length * word_size):
                self.logger.error(
                    "Block #{}: Mismatch between (`length` * `word_size`) and actual block length."
                    .format(idx))
                continue
            checksum = attrib.get('checksum')
            if checksum:
                checksum = remove_ws(checksum)
                if SHA1_DIGEST(section_data) != checksum:
                    self.logger.error(
                        "Block #{}: Wrong `checksum`.".format(idx))
                    continue
            else:
                self.logger.error(
                    "Block #{}: Missing required attribute `checksum`.".format(
                        idx))
                continue
            #print(tag, attrib)
            #print(section_data, SHA1_DIGEST(section_data))
            sections.append(Section(address, section_data))
        img = Image(sections)
        if hasattr(fp, "close"):
            fp.close()
        return img

    def loads(self, image):
        if PYTHON_VERSION.major == 3:
            if isinstance(image, str):
                return self.load(create_string_buffer(bytes(image, "ascii")))
            else:
                return self.load(create_string_buffer(image))
        else:
            return self.load(create_string_buffer(image))