def assert_apk_equal(self, apk: APK, app_name: str, manifest: File, cert: File, dex_files: List[File], other_files: List[File]): self.assertEqual(app_name, apk.get_app_name()) self.assertEqual(manifest, apk.get_manifest()) self.assertEqual(cert, apk.get_cert()) self.assertEqual(dex_files, apk.get_dex_files()) self.assertEqual(other_files, apk.get_other_files())
def execute(self, apk: APK, output_directory: str): self.logger.info("Extracting certificate file...") with ZipFile(apk.get_file_name()) as package: cert = apk.get_cert().get_file_name() self.logger.info("Creating %s/%s...", output_directory, cert) cert_abspath = os.path.join(output_directory, os.path.basename(cert)) with package.open(cert) as cert, open(cert_abspath, "wb") as fp: shutil.copyfileobj(cert, fp)
def execute(self, apk: APK, output_directory: str): self.logger.info("Extracting DEX files...") apk_filename = apk.get_file_name() with ZipFile(apk_filename) as package: for dex_file in apk.get_dex_files(): dex_filename = dex_file.get_file_name() self.logger.info("Creating %s/%s...", output_directory, dex_filename) dex_abspath = os.path.join(output_directory, dex_filename) output_directory = os.path.split(dex_abspath)[0] os.makedirs(output_directory, exist_ok=True) with package.open(dex_filename) as dex, open( dex_abspath, "wb") as fp: shutil.copyfileobj(dex, fp)
def execute(self, apk: APK, input_filename: str, output_directory: str): self.logger.info("Generating JSON report file...") report_filename = GetApkInfoInJson.__REPORT_FILENAME_PREFIX + input_filename + ".json" self.logger.info("Creating %s/%s...", output_directory, report_filename) with open(os.path.join(output_directory, report_filename), "w") as fp: apk_info = json.dumps(apk.dump(), sort_keys=True, ensure_ascii=False, indent=4) fp.write(apk_info)
def test_init(self): for filename in self.apks: # When: apk = self.apks[filename] # Then: self.assertTrue(apk is not None) self.assertTrue(type(apk) is APK) # Test the class raise when a non-existing file is given: with self.assertRaises(ParsingError): APK(join("tests", "data", "aaa_this_is_a_non_existent_file_xxx")) # Test the class raise when a non-existing file is given: with self.assertRaises(APKParsingError): APK(join("tests", "data", "AndroidManifest.xml")) APK(join("tests", "data", "CERT.RSA")) APK(join("tests", "data", "classes.dex"))
def read_target_file(filepath: str, no_string_processing: bool): apk = None try: apk = APK(filepath, no_string_processing) except APKParsingError: logger.error("The target file (i.e. '" + filepath + "') must be an APK package!") except ParsingError: logger.error("The target file (i.e. '" + filepath + "') must be an existing, readable file!") return apk
def read_target_file(filepath: str, no_string_processing: bool): apk = None flash("Reading target apk...") try: apk = APK(filepath, no_string_processing) except APKParsingError: print("The target file (i.e. '%s') must be an APK package!", filepath) except ParsingError: print( "The target file (i.e. '%s') must be an existing, readable file!", filepath) return apk
def read_target_file(filepath: str, no_string_processing: bool) -> Optional[APK]: apk = None logger.debug("Reading %s...", filepath) try: apk = APK(filepath, no_string_processing, logger) except APKParsingError: logger.error("The target file ('%s') must be an APK package!", filepath) except ParsingError: logger.error( "The target file ('%s') must be an existing, readable file!", filepath) return apk
def test_apk_as_dict(self): apk = APK( filename="any-apk-file-name", size=10, md5hash="any-apk-file-md5", sha1hash="any-apk-file-sha1", sha256hash="any-apk-file-sha256", sha512hash="any-apk-file-sha512", app_name="any-app-name", cert=Cert( filename="any-cert-file-name", size=20, md5hash="any-cert-file-md5", sha1hash="any-cert-file-sha1", sha256hash="any-cert-file-sha256", sha512hash="any-cert-file-sha512", serial_number="any-cert-serial-number", validity=CertValidity( valid_from="any-cert-validity-from", valid_to="any-cert-validity-to" ), fingerprint=CertFingerprint( md5="any-cert-fingerprint-md5", sha1="any-cert-fingerprint-sha1", sha256="any-cert-fingerprint-sha256", signature="any-cert-fingerprint-signature", version="any-cert-fingerprint-version" ), owner=CertParticipant( name="any-cert-owner-name", email="any-cert-owner-email", unit="any-cert-owner-unit", organization="any-cert-owner-organization", city="any-cert-owner-city", state="any-cert-owner-state", country="any-cert-owner-country", domain="any-cert-owner-domain" ), issuer=CertParticipant( name="any-cert-issuer-name", email="any-cert-issuer-email", unit="any-cert-issuer-unit", organization="any-cert-issuer-organization", city="any-cert-issuer-city", state="any-cert-issuer-state", country="any-cert-issuer-country", domain="any-cert-issuer-domain" ) ), manifest=AndroidManifest( filename="any-manifest-file-name", size=30, md5hash="any-manifest-file-md5", sha1hash="any-manifest-file-sha1", sha256hash="any-manifest-file-sha256", sha512hash="any-manifest-file-sha512", package_name="any-package-name", version=AppVersion(code=1, name="any-version-name"), sdk=AppSdk(min_version="10", target_version="15", max_version="20"), permissions=[], activities=[], services=[], receivers=[] ), dex_files=[ Dex( filename="any-dex-file-name", size=40, md5hash="any-dex-file-md5", sha1hash="any-dex-file-sha1", sha256hash="any-dex-file-sha256", sha512hash="any-dex-file-sha512", strings=[], urls=[], shell_commands=[], custom_signatures=[] ) ], other_files=[ any_file( filename="any-resource-file-name", size=50, md5="any-resource-file-md5", sha1="any-resource-file-sha1", sha256="any-resource-file-sha256", sha512="any-resource-file-sha512" ) ] ) result = apk.as_dict() self.assertEqual( { "file": "any-apk-file-name", "size": 10, "md5": "any-apk-file-md5", "sha1": "any-apk-file-sha1", "sha256": "any-apk-file-sha256", "sha512": "any-apk-file-sha512", "name": "any-app-name", "cert": { "file": "any-cert-file-name", "size": 20, "md5": "any-cert-file-md5", "sha1": "any-cert-file-sha1", "sha256": "any-cert-file-sha256", "sha512": "any-cert-file-sha512", "serial_number": "any-cert-serial-number", "validity": { "from": "any-cert-validity-from", "until": "any-cert-validity-to" }, "fingerprint": { "md5": "any-cert-fingerprint-md5", "sha1": "any-cert-fingerprint-sha1", "sha256": "any-cert-fingerprint-sha256", "signature": "any-cert-fingerprint-signature", "version": "any-cert-fingerprint-version" }, "owner": { "name": "any-cert-owner-name", "email": "any-cert-owner-email", "unit": "any-cert-owner-unit", "organization": "any-cert-owner-organization", "city": "any-cert-owner-city", "state": "any-cert-owner-state", "country": "any-cert-owner-country", "domain": "any-cert-owner-domain" }, "issuer": { "name": "any-cert-issuer-name", "email": "any-cert-issuer-email", "unit": "any-cert-issuer-unit", "organization": "any-cert-issuer-organization", "city": "any-cert-issuer-city", "state": "any-cert-issuer-state", "country": "any-cert-issuer-country", "domain": "any-cert-issuer-domain" } }, "manifest": { "file": "any-manifest-file-name", "size": 30, "md5": "any-manifest-file-md5", "sha1": "any-manifest-file-sha1", "sha256": "any-manifest-file-sha256", "sha512": "any-manifest-file-sha512", "package": "any-package-name", "version": { "code": 1, "name": "any-version-name" }, "sdk": { "min": "10", "target": "15", "max": "20" }, "permissions": [] }, "dex": [ { "file": "any-dex-file-name", "size": 40, "md5": "any-dex-file-md5", "sha1": "any-dex-file-sha1", "sha256": "any-dex-file-sha256", "sha512": "any-dex-file-sha512", "strings": [], "urls": [], "shell_commands": [] } ], "other": [ { "file": "any-resource-file-name", "size": 50, "md5": "any-resource-file-md5", "sha1": "any-resource-file-sha1", "sha256": "any-resource-file-sha256", "sha512": "any-resource-file-sha512", } ] }, result )
def setUp(self): self.apks = {} for filename in listdir(join("tests", "data")): if filename in self.apks_properties: self.apks[filename] = APK(join("tests", "data", filename))
def dumps_apk_info(apk: APK): apk_info = json.dumps(apk.dump(), sort_keys=True, ensure_ascii=False, indent=4) print(apk_info)
def generate_html_report(apk: APK) -> str: man = apk.get_manifest() cert = apk.get_cert() dex_files = apk.get_dex_files() # Header: report = "<html>" + "\n" report += "\t<table border=\"0\" cellspacing=\"0\" cellpadding=\"2\">" + "\n" # APK file summary: report += "\t\t<tr style='font-size: 120%; font-weight: bold;'>" + "\n" report += "\t\t\t<td colspan=\"2\" style=\"background: #2F2F2F; color: #FFFFFF; text-align: center;\">SUMMARY</td>" + "\n" # noqa report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + apk.get_file_name( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File size:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + str( apk.get_size()) + " Bytes</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File MD5:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + apk.get_md5( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File SHA-1:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + apk.get_sha1( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File SHA-256:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + apk.get_sha256( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File SHA-512:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + apk.get_sha512( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" # App Info: report += "\t\t<tr style='font-size: 120%; font-weight: bold;'>" + "\n" report += "\t\t\t<td colspan=\"2\" style=\"background: #2F2F2F; color: #FFFFFF; text-align: center;\">APP INFO</td>" + "\n" # noqa report += "\t\t</tr>" + "\n" if man is not None: # Package name: report += "\t\t<tr>" + "\n" report += "\t\t\t<td>Package:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + man.get_package_name( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" # App name: report += "\t\t<tr>" + "\n" report += "\t\t\t<td>Name:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + apk.get_app_name( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" if man is not None: # App version: version = man.get_version() report += "\t\t<tr>" + "\n" report += "\t\t\t<td>Version:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + version[ "name"] + " (code: " + str( version["code"]) + ")" + "</td>" + "\n" # noqa report += "\t\t</tr>" + "\n" # App SDK version: sdk = man.get_sdk_version() if "target" in sdk: target = sdk["target"] else: target = "" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>Target SDK:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + target + "</td>" + "\n" report += "\t\t</tr>" + "\n" # App permissions: report += "\t\t<tr>" + "\n" report += "\t\t\t<td style=\"vertical-align: top;\">Permissions (" + str( man.get_number_of_permissions()) + "):</td>" + "\n" # noqa report += "\t\t\t<td style=\"font-weight: bold;\">\n" for permission in man.get_permissions(): if permission == "android.permission.SEND_SMS" or permission == "android.permission.RECEIVE_SMS" or permission == "android.permission.RECEIVE_MMS" or permission == "android.permission.CALL_PHONE" or permission == "android.permission.CALL_PRIVILEGED" or permission == "android.permission.PROCESS_OUTGOING_CALLS" or permission == "android.permission.INSTALL_PACKAGES" or permission == "android.permission.MOUNT_FORMAT_FILESYSTEMS" or permission == "android.permission.MOUNT_UNMOUNT_FILESYSTEMS": # noqa report += "\t\t\t\t<span style=\"color: #FF0000;\">" + permission + "</span><br />\n" else: report += "\t\t\t\t" + permission + "<br />\n" report += "\t\t\t</td>" + "\n" report += "\t\t</tr>" + "\n" # App Activities: report += "\t\t<tr>" + "\n" report += "\t\t\t<td style=\"vertical-align: top;\">Activities (" + str( man.get_number_of_activities()) + "):</td>" + "\n" # noqa report += "\t\t\t<td style=\"font-weight: bold;\">\n" for activity in man.get_activities(): report += "\t\t\t\t" + activity["name"] + "<br />\n" report += "\t\t\t</td>" + "\n" report += "\t\t</tr>" + "\n" # App Services: report += "\t\t<tr>" + "\n" report += "\t\t\t<td style=\"vertical-align: top;\">Services (" + str( man.get_number_of_services()) + "):</td>" + "\n" # noqa report += "\t\t\t<td style=\"font-weight: bold;\">\n" for service in man.get_services(): report += "\t\t\t\t" + service["name"] + "<br />\n" report += "\t\t\t</td>" + "\n" report += "\t\t</tr>" + "\n" # App BroadcastReceivers: report += "\t\t<tr>" + "\n" report += "\t\t\t<td style=\"vertical-align: top;\">BroadcastReceivers (" + str( man.get_number_of_broadcast_receivers( )) + "):</td>" + "\n" # noqa report += "\t\t\t<td style=\"font-weight: bold;\">\n" for receiver in man.get_broadcast_receivers(): report += "\t\t\t\t" + receiver["name"] + "<br />\n" report += "\t\t\t</td>" + "\n" report += "\t\t</tr>" + "\n" # Author Info: report += "\t\t<tr style='font-size: 120%; font-weight: bold;'>" + "\n" report += "\t\t\t<td colspan=\"2\" style=\"background: #2F2F2F; color: #FFFFFF; text-align: center;\">AUTHOR INFO</td>" + "\n" # noqa report += "\t\t</tr>" + "\n" if cert is not None: # Author name: author = cert.get_owner() report += "\t\t<tr>" + "\n" report += "\t\t\t<td>Name:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">\n" if "debug" in author["name"].lower( ) or "unknown" in author["name"].lower(): report += "\t\t\t\t<span style=\"color: #FF0000;\">" + author[ "name"] + "</span><br />\n" else: report += "\t\t\t\t" + author["name"] + "<br />\n" report += "\t\t\t</td>" + "\n" report += "\t\t</tr>" + "\n" # Author email: report += "\t\t<tr>" + "\n" report += "\t\t\t<td>Email:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + author[ "email"] + "</td>" + "\n" report += "\t\t</tr>" + "\n" # Author company unit: report += "\t\t<tr>" + "\n" report += "\t\t\t<td>Company Unit:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + author[ "unit"] + "</td>" + "\n" report += "\t\t</tr>" + "\n" # Author organization: report += "\t\t<tr>" + "\n" report += "\t\t\t<td>Company:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">\n" if "debug" in author["organization"].lower( ) or "unknown" in author["organization"].lower(): report += "\t\t\t\t<span style=\"color: #FF0000;\">" + author[ "organization"] + "</span><br />\n" else: report += "\t\t\t\t" + author["organization"] + "<br />\n" report += "\t\t\t</td>" + "\n" report += "\t\t</tr>" + "\n" # Author location: report += "\t\t<tr>" + "\n" report += "\t\t\t<td>Locality:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + author[ "city"] + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>State:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + author[ "state"] + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>Country:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + author[ "country"] + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>Domain Component:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + author[ "domain"] + "</td>" + "\n" report += "\t\t</tr>" + "\n" # Certificate Info: report += "\t\t<tr style='font-size: 120%; font-weight: bold;'>" + "\n" report += "\t\t\t<td colspan=\"2\" style=\"background: #2F2F2F; color: #FFFFFF; text-align: center;\">CERTIFICATE INFO</td>" + "\n" # noqa report += "\t\t</tr>" + "\n" if cert is not None: report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + cert.get_file_name( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File size:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + str( cert.get_size()) + " Bytes</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File MD5:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + cert.get_md5( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File SHA-1:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + cert.get_sha1( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File SHA-256:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + cert.get_sha256( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File SHA-512:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + cert.get_sha512( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" validity = cert.get_validity() report += "\t\t<tr>" + "\n" report += "\t\t\t<td>Validity:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">From: " + validity[ "from"] + " - Until: " + validity[ "until"] + "</td>" + "\n" # noqa report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>Serial Number:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + cert.get_serial_number( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>Fingerprint MD5:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + cert.get_fingerprint_md5( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>Fingerprint SHA-1:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + cert.get_fingerprint_sha1( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>Fingerprint SHA-256:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + cert.get_fingerprint_sha256( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>Fingerprint Signature:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + cert.get_fingerprint_signature( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>Fingerprint Version:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + cert.get_fingerprint_version( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" # Manifest Info: report += "\t\t<tr style='font-size: 120%; font-weight: bold;'>" + "\n" report += "\t\t\t<td colspan=\"2\" style=\"background: #2F2F2F; color: #FFFFFF; text-align: center;\">ANDROIDMANIFEST.XML INFO</td>" + "\n" # noqa report += "\t\t</tr>" + "\n" if man is not None: report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + man.get_file_name( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File size:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + str( man.get_size()) + " Bytes</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File MD5:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + man.get_md5( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File SHA-1:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + man.get_sha1( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File SHA-256:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + man.get_sha256( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File SHA-512:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + man.get_sha512( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" for dex in dex_files: # dex info: report += "\t\t<tr style='font-size: 120%; font-weight: bold;'>" + "\n" report += "\t\t\t<td colspan=\"2\" style=\"background: #2F2F2F; color: #FFFFFF; text-align: center;\">" + dex.get_file_name( ).upper() + " INFO</td>" + "\n" # noqa report += "\t\t</tr>" + "\n" if dex is not None: report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + dex.get_file_name( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File size:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + str( dex.get_size()) + " Bytes</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File MD5:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + dex.get_md5( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File SHA-1:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + dex.get_sha1( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File SHA-256:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + dex.get_sha256( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" report += "\t\t<tr>" + "\n" report += "\t\t\t<td>File SHA-512:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">" + dex.get_sha512( ) + "</td>" + "\n" report += "\t\t</tr>" + "\n" # URLs: report += "\t\t<tr>" + "\n" report += "\t\t\t<td style=\"vertical-align: top;\">URLs:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">\n" for url in dex.get_urls(): report += "\t\t\t\t" + url + "<br />\n" report += "\t\t\t</td>" + "\n" report += "\t\t</tr>" + "\n" # Shell commands: report += "\t\t<tr>" + "\n" report += "\t\t\t<td style=\"vertical-align: top;\">Shell Commands:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">\n" for command in dex.get_shell_commands(): report += "\t\t\t\t" + command + "<br />\n" report += "\t\t\t</td>" + "\n" report += "\t\t</tr>" + "\n" # Strings: report += "\t\t<tr>" + "\n" report += "\t\t\t<td style=\"vertical-align: top;\">Strings:</td>" + "\n" report += "\t\t\t<td style=\"font-weight: bold;\">\n" for string in dex.get_strings(): report += "\t\t\t\t" + str(string) + "<br />\n" report += "\t\t\t</td>" + "\n" report += "\t\t</tr>" + "\n" # List of files: report += "\t\t<tr style='font-size: 120%; font-weight: bold;'>" + "\n" report += "\t\t\t<td colspan=\"2\" style=\"background: #2F2F2F; color: #FFFFFF; text-align: center;\">OTHER FILES</td>" + "\n" # noqa report += "\t\t</tr>" + "\n" for entry in apk.get_file_list(): report += "\t\t<tr>" + "\n" report += "\t\t\t<td style=\"vertical-align: top; font-weight: bold;\">" + entry.get_file_name( ) + "</td>" + "\n" # noqa report += "\t\t\t<td>\n" report += "\t\t\t\tFile size: " + str( entry.get_size()) + "<br />\n" report += "\t\t\t\tFile MD5: " + entry.get_md5() + "<br />\n" report += "\t\t\t\tFile SHA-1: " + entry.get_sha1() + "<br />\n" report += "\t\t\t\tFile SHA-256: " + entry.get_sha256( ) + "<br />\n" report += "\t\t\t\tFile SHA-512: " + entry.get_sha512( ) + "<br />\n" report += "\t\t\t</td>" + "\n" report += "\t\t</tr>" + "\n" # Footer: report += "\t</table>" + "\n" report += "</html>" + "\n" return report