AxmlParserPY icon indicating copy to clipboard operation
AxmlParserPY copied to clipboard

('getApkPackageInfo Error. ', ValueError('chr() arg not in range(256)',))

Open ohyeah521 opened this issue 8 years ago • 6 comments

when i run this command

ap = apk.APK(filename)

it show error like this. ('getApkPackageInfo Error. ', ValueError('chr() arg not in range(256)',))

i found the problems.

in this file. stringblock.py

def getRaw(self, idx):
    print("YYYYYYYYYYYYYYYYYYYYYYYYYYYY getRaw %s \n" % idx)
    if idx < 0 or self.m_stringOffsets == [] or idx >= len(self.m_stringOffsets):
        return None

    offset = self.m_stringOffsets[ idx ].get_value()
    length = self.getShort(self.m_strings, offset)

    data = ""
    print "length = ", length
    while length > 0:
        offset += 2
        # Unicode character
        print "self.getShort = ", self.getShort(self.m_strings, offset)
        data += chr(self.getShort(self.m_strings, offset))

        # FIXME
        if data[-1] == "&":
            data = data[:-1]

        length -= 1

    return data

can not resolve unicode.

ohyeah521 avatar Dec 29 '16 04:12 ohyeah521

We're using this at XDA and found this issue in APKs being uploaded using Android Studio 3.0 and all the new updated build tools.

corcoran avatar Jun 08 '17 14:06 corcoran

@antitree if you would have a fix for us it would be great.

yakov116 avatar Jun 08 '17 14:06 yakov116

Working on a fix with XDA. Issue is caused by StringBlock not accounting for different alignments when packaged in UTF8 mode.

Until a fix is released, does anyone have a suggestion for how to force packing in utf16 mode (as was the default before)?

Working:

>>> struct.unpack('<L', b[24:28])[0]
0

Not working:

>>> struct.unpack('<L', a[24:28])[0]
256

antdking avatar Jun 15 '17 06:06 antdking

    def getRaw(self, idx):

        if idx < 0 or self.m_stringOffsets == [] or idx >= len(self.m_stringOffsets):
            return None

        offset = self.m_stringOffsets[ idx ].get_value()
        length = self.getByte(self.m_strings, offset)
        offset += 1
        isansi = self.getByte(self.m_strings, offset)

        data = ""

        while length > 0:
            if isansi==0:
                # Unicode character
                offset += 2
                data += unichr(self.getShort(self.m_strings, offset))
            else:

                #multibyte
                offset += 1
                data += unichr(self.getByte(self.m_strings, offset))
                

            # FIXME
            if data[-1] == "&":
                data = data[:-1]

            length -= 1
        return data
        
    def getByte(self, array, offset):
        value = array[offset / 4].get_value()
        offset%=4
        if offset == 0:
            return value & 0xFF
        if offset == 1:
            return (value>>8) & 0xFF
        if offset == 2:
            return (value>>16) & 0xFF
        if offset == 3:
            return (value>>24) & 0xFF

http://blog.csdn.net/lzf_china/article/details/8069056

gonjay avatar Jun 23 '17 06:06 gonjay

I would recommend checking out androguard if you want a more actively developed APK parser in python.

https://github.com/androguard/androguard

corcoran avatar Jun 30 '17 04:06 corcoran

I finally with this method.

If you use python2 need to change file ``axmlparserpy/stringblock.py +L89`

Origin

data += chr(self.getShort(self.m_strings, offset))

To

data += unichr(self.getShort(self.m_strings, offset))

codeskyblue avatar Jul 20 '17 12:07 codeskyblue