mirror of
https://github.com/androguard/androguard.git
synced 2024-11-23 13:09:55 +00:00
167 lines
6.5 KiB
Python
167 lines
6.5 KiB
Python
# -*- coding: utf-8 -*-
|
|
import os
|
|
import unittest
|
|
from lxml import etree
|
|
|
|
test_dir = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
from androguard.core import apk, axml
|
|
from operator import itemgetter
|
|
|
|
TEST_APP_NAME = "TestsAndroguardApplication"
|
|
TEST_ICONS = {
|
|
120: "res/drawable-ldpi/icon.png",
|
|
160: "res/drawable-mdpi/icon.png",
|
|
240: "res/drawable-hdpi/icon.png",
|
|
65536: "res/drawable-hdpi/icon.png"
|
|
}
|
|
TEST_CONFIGS = {
|
|
"layout": [axml.ARSCResTableConfig.default_config()],
|
|
"string": [axml.ARSCResTableConfig.default_config()],
|
|
"drawable": [
|
|
axml.ARSCResTableConfig(sdkVersion=4, density=120),
|
|
axml.ARSCResTableConfig(sdkVersion=4, density=160),
|
|
axml.ARSCResTableConfig(sdkVersion=4, density=240)
|
|
]
|
|
}
|
|
|
|
|
|
class ARSCTest(unittest.TestCase):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
with open(os.path.join(test_dir, 'data/APK/TestActivity.apk'), "rb") as fd:
|
|
cls.apk = apk.APK(fd.read(), True)
|
|
|
|
def testARSC(self):
|
|
arsc = self.apk.get_android_resources()
|
|
self.assertTrue(arsc)
|
|
|
|
def testAppName(self):
|
|
app_name = self.apk.get_app_name()
|
|
self.assertEqual(app_name, TEST_APP_NAME, "Couldn't deduce application/activity label")
|
|
|
|
def testAppIcon(self):
|
|
for wanted_density, correct_path in TEST_ICONS.items():
|
|
app_icon_path = self.apk.get_app_icon(wanted_density)
|
|
self.assertEqual(app_icon_path, correct_path,
|
|
"Incorrect icon path for requested density")
|
|
|
|
def testStrings(self):
|
|
arsc = self.apk.get_android_resources()
|
|
|
|
p = arsc.get_packages_names()[0]
|
|
l = "\x00\x00"
|
|
|
|
e = etree.fromstring(arsc.get_string_resources(p, l))
|
|
|
|
self.assertEqual(e.find("string[@name='hello']").text, 'Hello World, TestActivity! kikoololmodif')
|
|
self.assertEqual(e.find("string[@name='app_name']").text, 'TestsAndroguardApplication')
|
|
|
|
def testResourceNames(self):
|
|
"""
|
|
Test if the resource name translation works
|
|
"""
|
|
arsc = self.apk.get_android_resources()
|
|
|
|
self.assertEqual(arsc.get_resource_xml_name(0x7F040001), "@tests.androguard:string/app_name")
|
|
self.assertEqual(arsc.get_resource_xml_name(0x7F020000), "@tests.androguard:drawable/icon")
|
|
|
|
self.assertEqual(arsc.get_resource_xml_name(0x7F040001, 'tests.androguard'), "@string/app_name")
|
|
self.assertEqual(arsc.get_resource_xml_name(0x7F020000, 'tests.androguard'), "@drawable/icon")
|
|
|
|
# Also test non existing resources
|
|
self.assertIsNone(arsc.get_resource_xml_name(0xFFFFFFFF))
|
|
self.assertEqual(arsc.get_id('sdf', 0x7F040001), (None, None, None))
|
|
self.assertEqual(arsc.get_id('tests.androguard', 0xFFFFFFFF), (None, None, None))
|
|
|
|
def testDifferentStringLocales(self):
|
|
"""
|
|
Test if the resolving of different string locales works
|
|
"""
|
|
a = apk.APK(os.path.join(test_dir, 'data/APK/a2dp.Vol_137.apk'))
|
|
|
|
arsc = a.get_android_resources()
|
|
|
|
p = arsc.get_packages_names()[0]
|
|
|
|
self.assertEqual(sorted(["\x00\x00", "da", "de", "el", "fr", "ja", "ru"]),
|
|
sorted(arsc.get_locales(p)))
|
|
|
|
item = "SMSDelayText"
|
|
strings = {"\x00\x00": "Delay for reading text message",
|
|
"da": "Forsinkelse for læsning af tekst besked",
|
|
"de": "Verzögerung vor dem Lesen einer SMS",
|
|
"el": "Χρονοκαθυστέρηση ανάγνωσης μηνυμάτων SMS",
|
|
"fr": "Délai pour lire un SMS",
|
|
"ja": "テキストメッセージ読み上げの遅延",
|
|
"ru": "Задержка зачитывания SMS",
|
|
}
|
|
for k, v in strings.items():
|
|
e = etree.fromstring(arsc.get_string_resources(p, k))
|
|
self.assertEqual(e.find("string[@name='{}']".format(item)).text, v)
|
|
|
|
def testTypeConfigs(self):
|
|
arsc = self.apk.get_android_resources()
|
|
configs = arsc.get_type_configs(None)
|
|
|
|
for res_type, test_configs in list(TEST_CONFIGS.items()):
|
|
config_set = set(test_configs)
|
|
self.assertIn(res_type, configs,
|
|
"resource type %s was not found" % res_type)
|
|
for config in configs[res_type]:
|
|
print(config.get_config_name_friendly())
|
|
self.assertIn(config, config_set,
|
|
"config %r was not expected" % config)
|
|
config_set.remove(config)
|
|
|
|
self.assertEqual(len(config_set), 0,
|
|
"configs were not found: %s" % config_set)
|
|
|
|
unexpected_types = set(TEST_CONFIGS.keys()) - set(configs.keys())
|
|
self.assertEqual(len(unexpected_types), 0,
|
|
"received unexpected resource types: %s" % unexpected_types)
|
|
|
|
def testFallback(self):
|
|
a = apk.APK(os.path.join(test_dir, 'data/APK/com.teleca.jamendo_35.apk'))
|
|
|
|
# Should use the fallback
|
|
self.assertEqual(a.get_app_name(), "Jamendo")
|
|
res_parser = a.get_android_resources()
|
|
|
|
res_id = int(a.get_attribute_value('application', 'label')[1:], 16)
|
|
|
|
# Default Mode, no config
|
|
self.assertEqual(len(res_parser.get_res_configs(res_id)), 2)
|
|
# With default config, but fallback
|
|
self.assertEqual(len(res_parser.get_res_configs(res_id, axml.ARSCResTableConfig.default_config())), 1)
|
|
# With default config but no fallback
|
|
self.assertEqual(
|
|
len(res_parser.get_res_configs(res_id, axml.ARSCResTableConfig.default_config(), fallback=False)), 0)
|
|
|
|
# Also test on resolver:
|
|
self.assertListEqual(list(map(itemgetter(1), res_parser.get_resolved_res_configs(res_id))),
|
|
["Jamendo", "Jamendo"])
|
|
self.assertListEqual(list(
|
|
map(itemgetter(1), res_parser.get_resolved_res_configs(res_id, axml.ARSCResTableConfig.default_config()))),
|
|
["Jamendo"])
|
|
|
|
def testIDParsing(self):
|
|
parser = axml.ARSCParser.parse_id
|
|
|
|
self.assertEqual(parser('@DEADBEEF'), (0xDEADBEEF, None))
|
|
self.assertEqual(parser('@android:DEADBEEF'), (0xDEADBEEF, 'android'))
|
|
self.assertEqual(parser('@foobar:01020304'), (0x01020304, 'foobar'))
|
|
|
|
with self.assertRaises(ValueError):
|
|
parser('@whatisthis')
|
|
with self.assertRaises(ValueError):
|
|
parser('#almost')
|
|
with self.assertRaises(ValueError):
|
|
parser('@android:NONOTHEX')
|
|
with self.assertRaises(ValueError):
|
|
parser('@android:00')
|
|
|
|
|
|
if __name__ == '__main__':
|
|
unittest.main()
|