示例#1
0
    def extract_data(self, app: Bundle, result_path: str) -> bool:
        # Metadata is stored in a dictionary, which is later serialised to the disk.
        dependencies_metadata = dict()

        if not isinstance(app, Application):
            self.log_error("Supplied app {} is not an application".format(
                app.filepath))
            return False

        app_base = os.path.realpath(app.filepath) + "/"

        executable = app.executable()

        app_dependencies = executable.application_libraries(
        ) if executable else []
        for dependency in app_dependencies:
            dependency_bundle = Bundle.from_binary(dependency)
            # Relative path component from the underlying app to the dependency.
            dependency_rel = fs.path_remove_prefix(dependency, app_base)

            dependency_infos = None

            if dependency_bundle:
                # Use Info.plist from bundle
                dependency_infos = dependency_bundle.info_dictionary()
            else:
                # Try to instead use embedded information
                if lief.is_macho(dependency):
                    dependency_infos = common.extract_embedded_info(
                        lief_extensions.macho_parse_quick(dependency))

            if dependency_infos:
                # Record entry along with further information
                dependencies_metadata[
                    dependency_rel] = DependenciesExtractor._extract_dependency_infos(
                        dependency_infos)
            else:
                # Just record the path to the dependency
                dependencies_metadata[dependency_rel] = {}

        # Store the information to the filesystem
        with open(os.path.join(result_path, "dependencies.json"),
                  "w") as outfile:
            json.dump(dependencies_metadata, outfile, indent=4)

        return True
示例#2
0
    def test_bundle_from_binary(self):
        # For single-file utility, this function should return None, because the file is not
        # part of any bundle
        self.assertIsNone(Bundle.from_binary("/bin/ls"))
        self.assertIsNone(Bundle.from_binary("/bin/ln"))

        # For binaries that are part of a bundle but not the main executable in such a bundle,
        # the function is also supposed to return None

        # Note: iTunes is used here, because it comes pre-installed on macOS
        # and it has the most complicated dependencies of any installed app, thus
        # it can be used for many different purposes
        self.assertIsNone(Bundle.from_binary("/Applications/iTunes.app/Contents/MacOS/iTunesASUHelper"))

        # For non-existent binaries, the function should throw a ValueError
        with self.assertRaises(ValueError):
            # This binary surely does not exist
            Bundle.from_binary("/bin/useful_test03837246")

        # If the main executable is supplied, the corresponding bundle should be found
        self.assertEqual(
            Bundle.from_binary(
                "/Applications/iTunes.app/Contents/MacOS/iTunes"
            ).filepath,
            "/Applications/iTunes.app")

        # This should also work for other types of bundles
        self.assertEqual(
            Bundle.from_binary(
                "/Applications/iTunes.app/Contents/Frameworks/iPodUpdater.framework/Versions/A/iPodUpdater"
            ).filepath,
            "/Applications/iTunes.app/Contents/Frameworks/iPodUpdater.framework"
        )
        self.assertEqual(
            Bundle.from_binary(
                "/Applications/iTunes.app/Contents/PlugIns/iTunesStorageExtension.appex/Contents/MacOS/iTunesStorageExtension"
            ).filepath,
            "/Applications/iTunes.app/Contents/PlugIns/iTunesStorageExtension.appex"
        )