예제 #1
0
    def get_apk_info(self):
        apk = APK(self.apk_file)
        app_icon_file = apk.get_app_icon()
        app_icon_data = apk.get_file(app_icon_file)

        size = (256, 256)

        buffered = BytesIO()
        im = Image.open(BytesIO(app_icon_data))
        im = im.resize(size, Image.ANTIALIAS)
        im.save(buffered, "PNG")

        app_icon_b64 = "data:image/png;base64," + base64.b64encode(
            buffered.getvalue()).decode('utf-8')

        self.package_name = apk.get_package()
        self.app_name = apk.get_app_name()

        self.report_saver.package_name = self.package_name
        self.report_saver.app_name = self.app_name
        self.report_saver.version = apk.get_androidversion_code()
        self.report_saver.app_icon = app_icon_b64

        permission_parser = PermissionParser(mode='groups')
        permission_values = permission_parser.transform(
            apk.get_permissions()).flatten().tolist()
        permission_labels = permission_parser.labels()
        self.report_saver.permissions_actual = {
            permission_labels[i]: bool(v)
            for i, v in enumerate(permission_values)
        }
    def testAdaptiveIcon(self):
        # See https://developer.android.com/guide/practices/ui_guidelines/icon_design_adaptive.html
        from androguard.core.bytecodes.apk import APK
        from androguard.core.bytecodes.axml import AXMLPrinter

        a = APK("examples/tests/com.android.example.text.styling.apk")

        self.assertEqual(a.get_app_icon(), "res/mipmap-anydpi-v26/ic_launcher.xml")
        x = AXMLPrinter(a.get_file(a.get_app_icon())).get_xml().decode("UTF-8")
        self.assertIn("adaptive-icon", x)

        # * ldpi (low) ~120dpi
        # * mdpi (medium) ~160dpi
        # * hdpi (high) ~240dpi
        # * xhdpi (extra-high) ~320dpi
        # * xxhdpi (extra-extra-high) ~480dpi
        # * xxxhdpi (extra-extra-extra-high) ~640dpi
        self.assertIsNone(a.get_app_icon(max_dpi=120))  # No LDPI icon
        self.assertIn("mdpi", a.get_app_icon(max_dpi=160))
        self.assertIn("hdpi", a.get_app_icon(max_dpi=240))
        self.assertIn("xhdpi", a.get_app_icon(max_dpi=320))
        self.assertIn("xxhdpi", a.get_app_icon(max_dpi=480))
        self.assertIn("xxxhdpi", a.get_app_icon(max_dpi=640))

        self.assertIn(".png", a.get_app_icon(max_dpi=65533))
        self.assertIn(".xml", a.get_app_icon(max_dpi=65534))
예제 #3
0
    def testAdaptiveIcon(self):
        # See https://developer.android.com/guide/practices/ui_guidelines/icon_design_adaptive.html
        from androguard.core.bytecodes.apk import APK
        from androguard.core.bytecodes.axml import AXMLPrinter

        a = APK("examples/tests/com.android.example.text.styling.apk")

        self.assertEqual(a.get_app_icon(), "res/mipmap-anydpi-v26/ic_launcher.xml")
        x = AXMLPrinter(a.get_file(a.get_app_icon())).get_xml().decode("UTF-8")
        self.assertIn("adaptive-icon", x)

        # * ldpi (low) ~120dpi
        # * mdpi (medium) ~160dpi
        # * hdpi (high) ~240dpi
        # * xhdpi (extra-high) ~320dpi
        # * xxhdpi (extra-extra-high) ~480dpi
        # * xxxhdpi (extra-extra-extra-high) ~640dpi
        self.assertIsNone(a.get_app_icon(max_dpi=120))  # No LDPI icon
        self.assertIn("mdpi", a.get_app_icon(max_dpi=160))
        self.assertIn("hdpi", a.get_app_icon(max_dpi=240))
        self.assertIn("xhdpi", a.get_app_icon(max_dpi=320))
        self.assertIn("xxhdpi", a.get_app_icon(max_dpi=480))
        self.assertIn("xxxhdpi", a.get_app_icon(max_dpi=640))

        self.assertIn(".png", a.get_app_icon(max_dpi=65533))
        self.assertIn(".xml", a.get_app_icon(max_dpi=65534))
예제 #4
0
 def retrieve_content_from_apk(self):
     a = APK(self.filename)
     package_name = a.get_package()
     resources = a.get_android_resources()  # .get_strings_resources()
     self.client_id = resources.get_string(package_name,
                                           "PSA_API_CLIENT_ID_PROD")[1]
     self.client_secret = resources.get_string(
         package_name, "PSA_API_CLIENT_SECRET_PROD")[1]
     self.host_brandid_prod = resources.get_string(package_name,
                                                   "HOST_BRANDID_PROD")[1]
     self.culture = self.__get_cultures_code(
         a.get_file("res/raw/cultures.json"), self.country_code)
     ## Get Customer id
     self.site_code = BRAND[package_name][
         "brand_code"] + "_" + self.country_code + "_ESP"
     pfx_cert = a.get_file("assets/MWPMYMA1.pfx")
     save_key_to_pem(pfx_cert, b"y5Y2my5B")
예제 #5
0
def find_hidden_dex(apk: APK) -> Optional[DalvikVMFormat]:
    files = apk.get_files()
    hidden_dex_names = [
        x for x in files if re.match(r"assets/[a-zA-Z0-9]+", x)
    ]
    if len(hidden_dex_names) == 1:
        hidden_dex_name = hidden_dex_names[0]
        data = apk.get_file(hidden_dex_name)
        return decrypt_dex(data)

    return None
예제 #6
0
파일: main.py 프로젝트: ninoseki/funky_hao
def find_hidden_dex(apk: APK):
    files = apk.get_files()
    hidden_dex_names = [
        x for x in files if re.match(r"assets/[a-z0-9]+/[a-z0-9]+", x)
    ]
    if len(hidden_dex_names) == 1:
        hidden_dex_name = hidden_dex_names[0]
        data = apk.get_file(hidden_dex_name)
        dex = decrypt_dex(data)
        if dex is not None:
            return dex
        return decrypt_dex_b(data)

    return None
예제 #7
0
    def get_apk_info(self):
        apk = APK(self.apk_file)
        app_icon_file = apk.get_app_icon()
        app_icon_data = apk.get_file(app_icon_file)

        size = (256, 256)

        buffered = BytesIO()
        im = Image.open(BytesIO(app_icon_data))
        im = im.resize(size, Image.ANTIALIAS)
        im.save(buffered, "PNG")

        app_icon_b64 = "data:image/png;base64," + base64.b64encode(
            buffered.getvalue()).decode('utf-8')

        self.package_name = apk.get_package()
        self.app_name = apk.get_app_name()

        self.report_saver.package_name = self.package_name
        self.report_saver.app_name = self.app_name
        self.report_saver.version = apk.get_androidversion_code()
        self.report_saver.app_icon = app_icon_b64
예제 #8
0
script_dir = dir_path = os.path.dirname(os.path.realpath(__file__))
if sys.version_info < (3, 6):
    raise RuntimeError("This application requires Python 3.6+")

if not argv[1].endswith(".apk"):
    print("No apk given")
    sys.exit(1)
print("APK loading...")
a = APK(argv[1])
package_name = a.get_package()
resources = a.get_android_resources()  # .get_strings_resources()
client_id = resources.get_string(package_name, "PSA_API_CLIENT_ID_PROD")[1]
client_secret = resources.get_string(package_name,
                                     "PSA_API_CLIENT_SECRET_PROD")[1]
HOST_BRANDID_PROD = resources.get_string(package_name, "HOST_BRANDID_PROD")[1]
pfx_cert = a.get_file("assets/MWPMYMA1.pfx")
REMOTE_REFRESH_TOKEN = None
print("APK loaded !")

client_email = input(f"{BRAND[package_name]['app_name']} email: ")
client_password = getpass(f"{BRAND[package_name]['app_name']} password: "******"What is your country code ? (ex: FR, GB, DE, ES...)\n")

## Get Customer id
site_code = BRAND[package_name]["brand_code"] + "_" + country_code + "_ESP"
try:
    res = requests.post(HOST_BRANDID_PROD + "/GetAccessToken",
                        headers={
                            "Connection": "Keep-Alive",
                            "Content-Type": "application/json",
예제 #9
0
class XAPK:
    def __init__(self, folder):
        self.folder = Path(folder)
        for x in self.folder.glob('*.apk'):
            self.apk_src = Path(x)
            break
        for x in self.folder.glob('*.obb'):
            self.obb_src = Path(x)
            break
        self.apk = APK(self.apk_src)
        self.manifest = self.make_manifest()
        self.icon = self.apk.get_file(self.apk.get_app_icon())

    def make_manifest(self):
        apk_size = self.apk_src.stat().st_size
        if self.obb_src:
            obb_size = self.obb_src.stat().st_size
        else:
            obb_size = 0
        total_size = apk_size + obb_size
        filename = self.apk.get_filename()

        manifest = {}
        manifest['xapk_version'] = 1
        manifest['package_name'] = self.apk.get_package()
        manifest['name'] = self.apk.get_app_name()
        # manifest['locales_name'] = {} # TODO
        manifest['version_code'] = self.apk.get_androidversion_code()
        manifest['version_name'] = self.apk.get_androidversion_name()
        manifest['min_sdk_version'] = self.apk.get_min_sdk_version()
        manifest['target_sdk_version'] = self.apk.get_target_sdk_version()
        manifest['permissions'] = self.apk.get_declared_permissions()
        manifest['total_size'] = total_size
        manifest['expansions'] = []

        if obb_size:
            main_obb = {}
            main_obb[
                'file'] = 'Android/obb/{package_name}/main.{version_code}.{package_name}.obb'.format(
                    **manifest)
            main_obb['install_location'] = 'EXTERNAL_STORAGE'
            main_obb[
                'install_path'] = 'Android/obb/{package_name}/main.{version_code}.{package_name}.obb'.format(
                    **manifest)
            manifest['expansions'].push(main_obb)

        return manifest

    def save(self):
        self.name = '{package_name}_v{version_name}.xapk'.format(
            **self.manifest)
        zip_path = self.folder.joinpath(self.name)

        zip_dir = tempfile.mkdtemp()
        try:
            print('copying apk to temp directory...')
            apk_name = '{package_name}.apk'.format(**self.manifest)
            apk_src = self.apk_src.resolve()
            apk_dest = PurePath(zip_dir).joinpath(apk_name)
            shutil.copy2(apk_src, apk_dest)
            print('apk: OK')

            if self.manifest.get('expansions'):
                print('copying obb to temp directory...')
                obb_name = self.manifest['expansions'][0]['install_path']
                obb_src = self.obb_src.resolve()
                obb_dest = PurePath(zip_dir).joinpath(obb_name)
                os.makedirs(Path(obb_dest).parent, exist_ok=True)
                shutil.copy2(obb_src, obb_dest)
                print('obb: OK')
            else:
                print('no obb found')

            print('creating icon in temp directory...')
            icon = self.icon
            icon_dest = PurePath(zip_dir).joinpath('icon.png')
            with open(icon_dest, 'wb') as iconfile:
                iconfile.write(icon)
            print('icon: OK')

            print('creating manifest in temp directory...')
            manifest_dest = PurePath(zip_dir).joinpath('manifest.json')
            with open(manifest_dest, 'w') as manifestfile:
                s = json.dumps(self.manifest, separators=(':', ','))
                manifestfile.write(s)
            print('manifest: OK')

            print('creating xapk archive...')
            with zipfile.ZipFile(zip_path,
                                 'w',
                                 compression=zipfile.ZIP_DEFLATED) as zfd:
                for root, dirs, files in os.walk(zip_dir):
                    for f in files:
                        filename = os.path.join(root, f)
                        zfd.write(filename, os.path.relpath(filename, zip_dir))
            print('xapk: OK')
        finally:
            print('cleaning up temp directory...')
            shutil.rmtree(zip_dir)
            print('cleanup: OK')
예제 #10
0
class ApkFileSearch(object):
    def __init__(self,
                 apk_file,
                 search_strings,
                 file_types,
                 case_insensitive=False,
                 save_matched_files_dir=None):
        self.apk = APK(apk_file)
        self.search_strings = search_strings
        self.file_types = file_types

        self.save_matched_files_dir = None
        if save_matched_files_dir:
            self.save_matched_files_dir = os.path.join(
                save_matched_files_dir,
                os.path.splitext(os.path.basename(apk_file))[0])
            os.makedirs(self.save_matched_files_dir)

        flags = 0
        if case_insensitive:
            flags = re.IGNORECASE
        self.patterns = [
            re.compile(search_string, flags=flags)
            for search_string in search_strings
        ]

    def search(self):
        """iterate through files in the APK and apply search_strings over files that are of type file_types
            if no search strings specified, consider all files a match
            if no file_types specified, apply search strings to all files
            if no search strings and no file types, then return all files
        """
        apk_files = self.apk.get_files_types()
        search_results = []
        for file_path, file_type in apk_files.iteritems():
            file_ext = os.path.splitext(os.path.basename(file_path))[1]

            #if file type filter on, and this file is not that type, then skip
            if self.file_types and not any(
                    interested_type in file_type.lower()
                    or interested_type in file_ext
                    for interested_type in self.file_types):
                continue

            search_result = None
            file_data = self.apk.get_file(file_path)

            if self.search_strings:
                for pattern in self.patterns:
                    match = pattern.search(file_data)
                    if match:
                        search_result = {
                            'file_path': file_path,
                            'file_type': file_type,
                            'search_string': pattern.pattern
                        }
                        search_results.append(search_result)
            else:
                search_result = {
                    'file_path': file_path,
                    'file_type': file_type,
                    'search_string': None
                }
                search_results.append(search_result)

            #write individual files
            if search_result and self.save_matched_files_dir:
                #save original structure to avoid duplicate filename collisions
                save_file_path = os.path.join(self.save_matched_files_dir,
                                              file_path)
                if not os.path.exists(os.path.dirname(save_file_path)):
                    os.makedirs(os.path.dirname(save_file_path))

                with open(save_file_path, 'wb') as f:
                    f.write(file_data)

                if 'Android binary XML' in file_type:
                    with open(save_file_path, 'r+') as axml_f:
                        decoded_axml = AXMLPrinter(axml_f.read()).buff
                        axml_f.seek(0)
                        axml_f.write(decoded_axml)
                        axml_f.truncate()

        return search_results
예제 #11
0
    help=
    "Add <path> elements containing the mbn path, as extracted from modem.conf files",
)
parser.add_argument(
    "--output",
    type=Path,
    default=Path(__file__).parent / 'res/xml/service_provider_sim_configs.xml',
    help="Write resulting ",
)
args = parser.parse_args()

oem_modem_config_dir = args.oem_dir / "modem-config"
apk_path = args.oem_dir / args.overlay
apk = APK(apk_path.as_posix())
print(f"Opened {apk}")
file = apk.get_file("res/xml/service_providers.xml")

from xml.etree import ElementTree as ET
"""
NOTE:
Use get_xml_obj to get an immutable representation of the tree
Use get_xml to get a formatted string representation
Use get_buff to get a oneline representation without formatting tokens

ET keeps the formatting internally, and spits this out in `.write()`.
Inserted elements are not formatted properly.
"""
et = ET.fromstring(AXMLPrinter(file).get_xml())
assert et.tag == "service_provider_sim_configs"

mbn_paths = set()