diff --git a/pyaxmlparser/arscparser.py b/pyaxmlparser/arscparser.py index 5ef5772..1097e6d 100644 --- a/pyaxmlparser/arscparser.py +++ b/pyaxmlparser/arscparser.py @@ -125,16 +125,31 @@ def __init__(self, raw_buff): entries = [] for i in range(0, a_res_type.entryCount): - current_package.mResId = current_package.mResId & 0xffff0000 | i - entries.append((unpack('> 8, parent=parent) + elif self.is_complex(): self.item = ARSCComplex(buff, parent) else: # If FLAG_COMPLEX is not set, a Res_value structure will follow - self.key = ARSCResStringPoolRef(buff, self.parent) + self.value = ARSCResValue.fetch(buff, parent) - def get_index(self): - return self.index + def get_key(self): + return self.compact_key if self.is_compact() else self.key def get_value(self): - return self.parent.mKeyStrings.getString(self.index) + return self.parent.mKeyStrings.getString(self.key) - def get_key_data(self): - return self.key.get_data_value() + def get_value_data(self): + return self.value.get_data_value() def is_public(self): return (self.flags & self.FLAG_PUBLIC) != 0 @@ -554,16 +565,19 @@ def is_complex(self): def is_weak(self): return (self.flags & self.FLAG_WEAK) != 0 + def is_compact(self): + return (self.flags & self.FLAG_COMPACT) != 0 + def __repr__(self): return ( "" + "flags='0x{:02x}' key='0x{:x}' holding={}>" ).format( self.start, self.mResId, self.size, self.flags, - self.index, + self.key, self.item if self.is_complex() else self.key) @@ -577,25 +591,35 @@ def __init__(self, buff, parent=None): self.items = [] for i in range(0, self.count): - self.items.append((unpack('".format(self.start, self.id_parent, self.count) - -class ARSCResStringPoolRef(object): - def __init__(self, buff, parent=None): - self.start = buff.get_idx() +class ARSCResValue: + def __init__(self, data, data_type, res0=0, size=8, parent=None): + self.size = size + self.res0 = res0 + self.data = data + self.data_type = data_type self.parent = parent - self.size, = unpack("".format( - self.start, + return "".format( self.size, const.TYPE_TABLE.get(self.data_type, "0x%x" % self.data_type), self.data) diff --git a/pyaxmlparser/core.py b/pyaxmlparser/core.py index f694e76..92dae30 100644 --- a/pyaxmlparser/core.py +++ b/pyaxmlparser/core.py @@ -267,6 +267,7 @@ def __init__(self, filename, raw=False, skip_analysis=False, testzip=False): self.androidversion = {} self.permissions = [] self.uses_permissions = [] + self.uses_permission_sdk_23 = [] self.declared_permissions = {} self.valid_apk = False @@ -358,6 +359,7 @@ def _apk_analysis(self): self.androidversion["Code"] = self.get_attribute_value("manifest", "versionCode") self.androidversion["Name"] = self.get_attribute_value("manifest", "versionName") permission = list(self.get_all_attribute_value("uses-permission", "name")) + permission += list(self.get_all_attribute_value("uses-permission-sdk-23", "name")) self.permissions = list(set(self.permissions + permission)) for uses_permission in self.find_tags("uses-permission"): @@ -366,6 +368,12 @@ def _apk_analysis(self): self._get_permission_maxsdk(uses_permission) ]) + for uses_permission in self.find_tags("uses-permission-sdk-23"): + self.uses_permission_sdk_23.append([ + self.get_value_from_tag(uses_permission, "name"), + self._get_permission_maxsdk(uses_permission) + ]) + # getting details of the declared permissions for d_perm_item in self.find_tags('permission'): d_perm_name = self._get_res_string_value( @@ -439,7 +447,7 @@ def _get_permission_maxsdk(self, item): try: maxSdkVersion = int(self.get_value_from_tag(item, "maxSdkVersion")) except ValueError: - log.warning(self.get_max_sdk_version() + 'is not a valid value for maxSdkVersion') + log.warning(f"{self.get_max_sdk_version()} is not a valid value for <{item.tag}> maxSdkVersion") except TypeError: pass return maxSdkVersion @@ -1206,7 +1214,7 @@ def get_uses_implied_permission_list(self): if (WRITE_EXTERNAL_STORAGE in self.permissions or implied_WRITE_EXTERNAL_STORAGE) \ and READ_EXTERNAL_STORAGE not in self.permissions: maxSdkVersion = None - for name, version in self.uses_permissions: + for name, version in self.uses_permissions + self.uses_permission_sdk_23: if name == WRITE_EXTERNAL_STORAGE: maxSdkVersion = version break diff --git a/pyaxmlparser/stringblock.py b/pyaxmlparser/stringblock.py index 3a008f4..5a89774 100644 --- a/pyaxmlparser/stringblock.py +++ b/pyaxmlparser/stringblock.py @@ -126,7 +126,7 @@ def getString(self, idx): if idx in self._cache: return self._cache[idx] - if idx < 0 or not self.m_stringOffsets or idx > self.stringCount: + if idx < 0 or not self.m_stringOffsets or idx >= self.stringCount: return "" offset = self.m_stringOffsets[idx]