Exemplo n.º 1
0
class AXMLParser :

    def __init__(self, raw_buff) :
        self.reset()

        self.buff = bytecode.BuffHandle( raw_buff )

        self.buff.read(4)
        self.buff.read(4)

        self.sb = StringBlock( self.buff )

        self.m_resourceIDs = []
        self.m_prefixuri = {}
        self.m_uriprefix = {}
        self.m_prefixuriL = []

    def reset(self) :
        self.m_event = -1
        self.m_lineNumber = -1
        self.m_name = -1
        self.m_namespaceUri = -1
        self.m_attributes = []
        self.m_idAttribute = -1
        self.m_classAttribute = -1
        self.m_styleAttribute = -1

    def next(self) :
        self.doNext()
        return self.m_event

    def doNext(self) :
        if self.m_event == StringBlock.END_DOCUMENT :
            return

        event = self.m_event

        self.reset()
        while 1 :
            chunkType = -1

            # Fake END_DOCUMENT event.
            if event == StringBlock.END_TAG :
                pass

            # START_DOCUMENT
            if event == StringBlock.START_DOCUMENT :
                chunkType = StringBlock.CHUNK_XML_START_TAG
            else :
                if self.buff.end() == True :
                    self.m_event = StringBlock.END_DOCUMENT
                    break
                chunkType = SV( '<L', self.buff.read( 4 ) ).get_value()


            if chunkType == StringBlock.CHUNK_RESOURCEIDS :
                chunkSize = SV( '<L', self.buff.read( 4 ) ).get_value()
                # FIXME
                if chunkSize < 8 or chunkSize%4 != 0 :
                    raise("ooo")

                for i in range(0, chunkSize/4-2) :
                    self.m_resourceIDs.append( SV( '<L', self.buff.read( 4 ) ) )

                continue

            # FIXME
            if chunkType < StringBlock.CHUNK_XML_FIRST or chunkType > StringBlock.CHUNK_XML_LAST :
                raise("ooo")

            # Fake START_DOCUMENT event.
            if chunkType == StringBlock.CHUNK_XML_START_TAG and event == -1 :
                self.m_event = StringBlock.START_DOCUMENT
                break

            self.buff.read( 4 ) #/*chunkSize*/
            lineNumber = SV( '<L', self.buff.read( 4 ) ).get_value()
            self.buff.read( 4 ) #0xFFFFFFFF

            if chunkType == StringBlock.CHUNK_XML_START_NAMESPACE or chunkType == StringBlock.CHUNK_XML_END_NAMESPACE :
                if chunkType == StringBlock.CHUNK_XML_START_NAMESPACE :
                    prefix = SV( '<L', self.buff.read( 4 ) ).get_value()
                    uri = SV( '<L', self.buff.read( 4 ) ).get_value()

                    self.m_prefixuri[ prefix ] = uri
                    self.m_uriprefix[ uri ] = prefix
                    self.m_prefixuriL.append( (prefix, uri) )
                else :
                    self.buff.read( 4 )
                    self.buff.read( 4 )
                    (prefix, uri) = self.m_prefixuriL.pop()
                    #del self.m_prefixuri[ prefix ]
                    #del self.m_uriprefix[ uri ]

                continue


            self.m_lineNumber = lineNumber

            if chunkType == StringBlock.CHUNK_XML_START_TAG :
                self.m_namespaceUri = SV( '<L', self.buff.read( 4 ) ).get_value()
                self.m_name = SV( '<L', self.buff.read( 4 ) ).get_value()

                # FIXME
                self.buff.read( 4 ) #flags
                
                attributeCount = SV( '<L', self.buff.read( 4 ) ).get_value()
                self.m_idAttribute = (attributeCount>>16) - 1
                attributeCount = attributeCount & 0xFFFF
                self.m_classAttribute = SV( '<L', self.buff.read( 4 ) ).get_value()
                self.m_styleAttribute = (self.m_classAttribute>>16) - 1

                self.m_classAttribute = (self.m_classAttribute & 0xFFFF) - 1

                for i in range(0, attributeCount*StringBlock.ATTRIBUTE_LENGTH) :
                    self.m_attributes.append( SV( '<L', self.buff.read( 4 ) ).get_value() )

                for i in range(StringBlock.ATTRIBUTE_IX_VALUE_TYPE, len(self.m_attributes), StringBlock.ATTRIBUTE_LENGTH) :
                    self.m_attributes[i] = (self.m_attributes[i]>>24)

                self.m_event = StringBlock.START_TAG
                break

            if chunkType == StringBlock.CHUNK_XML_END_TAG :
                self.m_namespaceUri = SV( '<L', self.buff.read( 4 ) ).get_value()
                self.m_name = SV( '<L', self.buff.read( 4 ) ).get_value()
                self.m_event = StringBlock.END_TAG
                break

            if chunkType == StringBlock.CHUNK_XML_TEXT :
                self.m_name = SV( '<L', self.buff.read( 4 ) ).get_value()
                
                # FIXME
                self.buff.read( 4 ) #?
                self.buff.read( 4 ) #?

                self.m_event = StringBlock.TEXT
                break

    def getPrefixByUri(self, uri) :
        try :
            return self.m_uriprefix[ uri ]
        except KeyError :
            return -1

    def getPrefix(self) :
        try :
            return self.sb.getRaw(self.m_prefixuri[ self.m_namespaceUri ])
        except KeyError :
            return ""

    def getName(self) :
        if self.m_name == -1 or (self.m_event != StringBlock.START_TAG and self.m_event != StringBlock.END_TAG) :
            return ""

        return self.sb.getRaw(self.m_name)

    def getText(self) :
        if self.m_name == -1 or self.m_event != StringBlock.TEXT :
            return ""

        return self.sb.getRaw(self.m_name)

    def getNamespacePrefix(self, pos) :
        prefix = self.m_prefixuriL[ pos ][0]
        return self.sb.getRaw( prefix )

    def getNamespaceUri(self, pos) :
        uri = self.m_prefixuriL[ pos ][1]
        return self.sb.getRaw( uri )

    def getNamespaceCount(self, pos) :
        pass

    def getAttributeOffset(self, index) :
        # FIXME
        if self.m_event != StringBlock.START_TAG :
            raise("Current event is not START_TAG.")

        offset = index * 5
        # FIXME
        if offset >= len(self.m_attributes) :
            raise("Invalid attribute index")

        return offset

    def getAttributeCount(self) :
        if self.m_event != StringBlock.START_TAG :
            return -1

        return len(self.m_attributes) / StringBlock.ATTRIBUTE_LENGTH

    def getAttributePrefix(self, index) :
        offset = self.getAttributeOffset(index)
        uri = self.m_attributes[offset+StringBlock.ATTRIBUTE_IX_NAMESPACE_URI]

        prefix = self.getPrefixByUri( uri )
        if prefix == -1 :
            return ""

        return self.sb.getRaw( prefix )

    def getAttributeName(self, index) :
        offset = self.getAttributeOffset(index)
        name = self.m_attributes[offset+StringBlock.ATTRIBUTE_IX_NAME]

        if name == -1 :
            return ""

        return self.sb.getRaw( name )

    def getAttributeValueType(self, index) :
        offset = self.getAttributeOffset(index)
        return self.m_attributes[offset+StringBlock.ATTRIBUTE_IX_VALUE_TYPE]

    def getAttributeValueData(self, index) :
        offset = self.getAttributeOffset(index)
        return self.m_attributes[offset+StringBlock.ATTRIBUTE_IX_VALUE_DATA]

    def getAttributeValue(self, index) :
        offset = self.getAttributeOffset(index)
        valueType = self.m_attributes[offset+StringBlock.ATTRIBUTE_IX_VALUE_TYPE]
        if valueType == tc.TYPE_STRING :
            valueString = self.m_attributes[offset+StringBlock.ATTRIBUTE_IX_VALUE_STRING]
            return self.sb.getRaw( valueString )
        # WIP
        return ""
Exemplo n.º 2
0
class AXMLParser:
    def __init__(self, raw_buff):
        self.reset()

        self.buff = bytecode.BuffHandle(raw_buff)

        self.buff.read(4)
        self.buff.read(4)

        self.sb = StringBlock(self.buff)

        self.m_resourceIDs = []
        self.m_prefixuri = {}
        self.m_uriprefix = {}
        self.m_prefixuriL = []

    def reset(self):
        self.m_event = -1
        self.m_lineNumber = -1
        self.m_name = -1
        self.m_namespaceUri = -1
        self.m_attributes = []
        self.m_idAttribute = -1
        self.m_classAttribute = -1
        self.m_styleAttribute = -1

    def next(self):
        self.doNext()
        return self.m_event

    def doNext(self):
        if self.m_event == tc.END_DOCUMENT:
            return

        event = self.m_event

        self.reset()

        while 1:
            chunkType = -1

            # Fake END_DOCUMENT event.
            if event == tc.END_TAG:
                pass

            # START_DOCUMENT
            if event == tc.START_DOCUMENT:
                chunkType = tc.CHUNK_XML_START_TAG
            else:
                if self.buff.end() == True:
                    self.m_event = tc.END_DOCUMENT
                    break
                chunkType = SV('<L', self.buff.read(4)).get_value()

            if chunkType == tc.CHUNK_RESOURCEIDS:
                chunkSize = SV('<L', self.buff.read(4)).get_value()
                # FIXME
                if chunkSize < 8 or chunkSize % 4 != 0:
                    raise ("ooo")

                for i in range(0, chunkSize / 4 - 2):
                    self.m_resourceIDs.append(SV('<L', self.buff.read(4)))

                continue

            # FIXME
            if chunkType < tc.CHUNK_XML_FIRST or chunkType > tc.CHUNK_XML_LAST:
                raise ("ooo")

            # Fake START_DOCUMENT event.
            if chunkType == tc.CHUNK_XML_START_TAG and event == -1:
                self.m_event = tc.START_DOCUMENT
                break

            self.buff.read(4)  #/*chunkSize*/
            lineNumber = SV('<L', self.buff.read(4)).get_value()
            self.buff.read(4)  #0xFFFFFFFF

            if chunkType == tc.CHUNK_XML_START_NAMESPACE or chunkType == tc.CHUNK_XML_END_NAMESPACE:
                if chunkType == tc.CHUNK_XML_START_NAMESPACE:
                    prefix = SV('<L', self.buff.read(4)).get_value()
                    uri = SV('<L', self.buff.read(4)).get_value()

                    self.m_prefixuri[prefix] = uri
                    self.m_uriprefix[uri] = prefix
                    self.m_prefixuriL.append((prefix, uri))
                else:
                    self.buff.read(4)
                    self.buff.read(4)
                    (prefix, uri) = self.m_prefixuriL.pop()
                    #del self.m_prefixuri[ prefix ]
                    #del self.m_uriprefix[ uri ]

                continue

            self.m_lineNumber = lineNumber

            if chunkType == tc.CHUNK_XML_START_TAG:
                self.m_namespaceUri = SV('<L', self.buff.read(4)).get_value()
                self.m_name = SV('<L', self.buff.read(4)).get_value()

                # FIXME
                self.buff.read(4)  #flags

                attributeCount = SV('<L', self.buff.read(4)).get_value()
                self.m_idAttribute = (attributeCount >> 16) - 1
                attributeCount = attributeCount & 0xFFFF
                self.m_classAttribute = SV('<L', self.buff.read(4)).get_value()
                self.m_styleAttribute = (self.m_classAttribute >> 16) - 1

                self.m_classAttribute = (self.m_classAttribute & 0xFFFF) - 1

                for i in range(0, attributeCount * tc.ATTRIBUTE_LENGTH):
                    self.m_attributes.append(
                        SV('<L', self.buff.read(4)).get_value())

                for i in range(tc.ATTRIBUTE_IX_VALUE_TYPE,
                               len(self.m_attributes), tc.ATTRIBUTE_LENGTH):
                    self.m_attributes[i] = (self.m_attributes[i] >> 24)

                self.m_event = tc.START_TAG
                break

            if chunkType == tc.CHUNK_XML_END_TAG:
                self.m_namespaceUri = SV('<L', self.buff.read(4)).get_value()
                self.m_name = SV('<L', self.buff.read(4)).get_value()
                self.m_event = tc.END_TAG
                break

            if chunkType == tc.CHUNK_XML_TEXT:
                self.m_name = SV('<L', self.buff.read(4)).get_value()

                # FIXME
                self.buff.read(4)  #?
                self.buff.read(4)  #?

                self.m_event = tc.TEXT
                break

    def getPrefixByUri(self, uri):
        try:
            return self.m_uriprefix[uri]
        except KeyError:
            return -1

    def getPrefix(self):
        try:
            return self.sb.getRaw(self.m_prefixuri[self.m_namespaceUri])
        except KeyError:
            return ""

    def getName(self):
        if self.m_name == -1 or (self.m_event != tc.START_TAG
                                 and self.m_event != tc.END_TAG):
            return ""

        return self.sb.getRaw(self.m_name)

    def getText(self):
        if self.m_name == -1 or self.m_event != tc.TEXT:
            return ""

        return self.sb.getRaw(self.m_name)

    def getNamespacePrefix(self, pos):
        prefix = self.m_prefixuriL[pos][0]
        return self.sb.getRaw(prefix)

    def getNamespaceUri(self, pos):
        uri = self.m_prefixuriL[pos][1]
        return self.sb.getRaw(uri)

    def getNamespaceCount(self, pos):
        pass

    def getAttributeOffset(self, index):
        # FIXME
        if self.m_event != tc.START_TAG:
            raise ("Current event is not START_TAG.")

        offset = index * 5
        # FIXME
        if offset >= len(self.m_attributes):
            raise ("Invalid attribute index")

        return offset

    def getAttributeCount(self):
        if self.m_event != tc.START_TAG:
            return -1

        return len(self.m_attributes) / tc.ATTRIBUTE_LENGTH

    def getAttributePrefix(self, index):
        offset = self.getAttributeOffset(index)
        uri = self.m_attributes[offset + tc.ATTRIBUTE_IX_NAMESPACE_URI]

        prefix = self.getPrefixByUri(uri)
        if prefix == -1:
            return ""

        return self.sb.getRaw(prefix)

    def getAttributeName(self, index):
        offset = self.getAttributeOffset(index)
        name = self.m_attributes[offset + tc.ATTRIBUTE_IX_NAME]

        if name == -1:
            return ""

        return self.sb.getRaw(name)

    def getAttributeValueType(self, index):
        offset = self.getAttributeOffset(index)
        return self.m_attributes[offset + tc.ATTRIBUTE_IX_VALUE_TYPE]

    def getAttributeValueData(self, index):
        offset = self.getAttributeOffset(index)
        return self.m_attributes[offset + tc.ATTRIBUTE_IX_VALUE_DATA]

    def getAttributeValue(self, index):
        offset = self.getAttributeOffset(index)
        valueType = self.m_attributes[offset + tc.ATTRIBUTE_IX_VALUE_TYPE]
        if valueType == tc.TYPE_STRING:
            valueString = self.m_attributes[offset +
                                            tc.ATTRIBUTE_IX_VALUE_STRING]
            return self.sb.getRaw(valueString)
        # WIP
        return ""
Exemplo n.º 3
0
class AXMLParser:

    def __init__(self, raw_buff):
        self.reset()
        self.valid_axml = True
        self.axml_tampered = False
        self.packerwarning = False
        self.buff = bytecode.BuffHandle(raw_buff)

        axml_file, = unpack('<L', self.buff.read(4))
        if axml_file != CHUNK_AXML_FILE:
            if axml_file >> 16 == 0x0008:
                self.axml_tampered = True
                print "AXML file has an unusual header", format(self.buff)
            else:
                self.valid_axml = False
                print "Not a valid AXML file. Header 0x{:08x}".format(self.buff)
                return

        self.filesize, = unpack('<L', self.buff.read(4))
        header = ARSCHeader(self.buff)
        if header.type == 0x0001:
            print  "Expected String Pool header, got %x" % header.type

        self.sb = StringBlock(self.buff, header)

        self.m_resourceIDs = []
        self.m_prefixuri = {}
        self.m_uriprefix = {}
        self.m_prefixuriL = []

    def reset(self):
        self.m_event = -1
        self.m_lineNumber = -1
        self.m_name = -1
        self.m_namespaceUri = -1
        self.m_attributes = []
        self.m_idAttribute = -1
        self.m_classAttribute = -1
        self.m_styleAttribute = -1

    def next(self):
        self.doNext()
        return self.m_event

    def doNext(self):
        if self.m_event == tc.END_DOCUMENT:
            return

        event = self.m_event

        self.reset()

        while 1:
            chunkType = -1

            # Fake END_DOCUMENT event.
            if event == tc.END_TAG:
                pass

            # START_DOCUMENT
            if event == tc.START_DOCUMENT:
                chunkType = tc.CHUNK_XML_START_TAG
            else:
                if self.buff.end() == True:
                    self.m_event = tc.END_DOCUMENT
                    break
                chunkType = SV('<L', self.buff.read(4)).get_value()

            if chunkType == tc.CHUNK_RESOURCEIDS:
                chunkSize = SV('<L', self.buff.read(4)).get_value()
                # FIXME
                if chunkSize < 8 or chunkSize%4 != 0:
                    raise("ooo")

                for i in range(0, int(chunkSize/4-2)):
                    self.m_resourceIDs.append(SV('<L', self.buff.read(4)))

                continue

            # FIXME
            if chunkType < tc.CHUNK_XML_FIRST or chunkType > tc.CHUNK_XML_LAST:
                raise("ooo")

            # Fake START_DOCUMENT event.
            if chunkType == tc.CHUNK_XML_START_TAG and event == -1:
                self.m_event = tc.START_DOCUMENT
                break

            self.buff.read(4) #/*chunkSize*/
            lineNumber = SV('<L', self.buff.read(4)).get_value()
            self.buff.read(4) #0xFFFFFFFF

            if chunkType == tc.CHUNK_XML_START_NAMESPACE or chunkType == tc.CHUNK_XML_END_NAMESPACE:
                if chunkType == tc.CHUNK_XML_START_NAMESPACE:
                    prefix = SV('<L', self.buff.read(4)).get_value()
                    uri = SV('<L', self.buff.read(4)).get_value()

                    self.m_prefixuri[ prefix ] = uri
                    self.m_uriprefix[ uri ] = prefix
                    self.m_prefixuriL.append((prefix, uri))
                else:
                    self.buff.read(4)
                    self.buff.read(4)
                    (prefix, uri) = self.m_prefixuriL.pop()
                    #del self.m_prefixuri[ prefix ]
                    #del self.m_uriprefix[ uri ]

                continue

            self.m_lineNumber = lineNumber

            if chunkType == tc.CHUNK_XML_START_TAG:
                self.m_namespaceUri = SV('<L', self.buff.read(4)).get_value()
                self.m_name = SV('<L', self.buff.read(4)).get_value()

                # FIXME
                self.buff.read(4) #flags

                attributeCount = SV('<L', self.buff.read(4)).get_value()
                self.m_idAttribute = (attributeCount>>16) - 1
                attributeCount = attributeCount & 0xFFFF
                self.m_classAttribute = SV('<L', self.buff.read(4)).get_value()
                self.m_styleAttribute = (self.m_classAttribute>>16) - 1

                self.m_classAttribute = (self.m_classAttribute & 0xFFFF) - 1

                for i in range(0, attributeCount * tc.ATTRIBUTE_LENGTH):
                    self.m_attributes.append(SV('<L', self.buff.read(4)).get_value())

                for i in range(tc.ATTRIBUTE_IX_VALUE_TYPE, len(self.m_attributes), tc.ATTRIBUTE_LENGTH):
                    self.m_attributes[i] = (self.m_attributes[i]>>24)

                self.m_event = tc.START_TAG
                break

            if chunkType == tc.CHUNK_XML_END_TAG:
                self.m_namespaceUri = SV('<L', self.buff.read(4)).get_value()
                self.m_name = SV('<L', self.buff.read(4)).get_value()
                self.m_event = tc.END_TAG
                break

            if chunkType == tc.CHUNK_XML_TEXT:
                self.m_name = SV('<L', self.buff.read(4)).get_value()

                # FIXME
                self.buff.read(4) #?
                self.buff.read(4) #?

                self.m_event = tc.TEXT
                break

    def getPrefixByUri(self, uri):
        try:
            return self.m_uriprefix[ uri ]
        except KeyError:
            return -1

    def getPrefix(self):
        try:
            return self.sb.getRaw(self.m_prefixuri[ self.m_namespaceUri ])
        except KeyError:
            return ""

    def getName(self):
        if self.m_name == -1 or (self.m_event != tc.START_TAG and self.m_event != tc.END_TAG):
            return ""

        return self.sb.getRaw(self.m_name)

    def getText(self):
        if self.m_name == -1 or self.m_event != tc.TEXT:
            return ""

        return self.sb.getRaw(self.m_name)

    def getNamespacePrefix(self, pos):
        prefix = self.m_prefixuriL[ pos ][0]
        return self.sb.getRaw(prefix)

    def getNamespaceUri(self, pos):
        uri = self.m_prefixuriL[ pos ][1]
        return self.sb.getRaw(uri)

    def getNamespaceCount(self, pos):
        pass

    def getAttributeOffset(self, index):
        # FIXME
        if self.m_event != tc.START_TAG:
            raise("Current event is not START_TAG.")

        offset = index * 5
        # FIXME
        if offset >= len(self.m_attributes):
            raise("Invalid attribute index")

        return offset

    def getAttributeCount(self):
        if self.m_event != tc.START_TAG:
            return -1

        return int(len(self.m_attributes) / tc.ATTRIBUTE_LENGTH)

    def getAttributePrefix(self, index):
        offset = self.getAttributeOffset(index)
        uri = self.m_attributes[offset + tc.ATTRIBUTE_IX_NAMESPACE_URI]

        prefix = self.getPrefixByUri(uri)
        if prefix == -1:
            return ""

        return self.sb.getRaw(prefix)

    def getAttributeName(self, index):
        offset = self.getAttributeOffset(index)
        name = self.m_attributes[offset + tc.ATTRIBUTE_IX_NAME]

        if name == -1:
            return ""

        return self.sb.getRaw(name)

    def getAttributeValueType(self, index):
        offset = self.getAttributeOffset(index)
        return self.m_attributes[offset + tc.ATTRIBUTE_IX_VALUE_TYPE]

    def getAttributeValueData(self, index):
        offset = self.getAttributeOffset(index)
        return self.m_attributes[offset + tc.ATTRIBUTE_IX_VALUE_DATA]

    def getAttributeValue(self, index):
        offset = self.getAttributeOffset(index)
        valueType = self.m_attributes[offset + tc.ATTRIBUTE_IX_VALUE_TYPE]
        if valueType == tc.TYPE_STRING:
            valueString = self.m_attributes[offset + tc.ATTRIBUTE_IX_VALUE_STRING]
            return self.sb.getRaw(valueString)
        # WIP
        return ""