[docs]classJar(Soot):""" Backend for lifting JARs to Soot. """is_default=True# let CLE automatically use this backend
[docs]def__init__(self,jar_path,binary_stream,entry_point=None,entry_point_params=("java.lang.String[]",),jni_libs=None,jni_libs_ld_path=None,**kwargs,):""" :param jar_path: Path to JAR. The following parameters are optional :param entry_point: Fully qualified name of method that should be used as the entry point. If not specified, we try to parse it from the manifest. :param additional_jars: Additional JARs. :param additional_jar_roots: Additional JAR roots. :param jni_libs: Name(s) of JNI libs to load (if any). :param jni_libs_ld_path: Path(s) where to find libs defined by param jni_libs. Note: Directory of the JAR is added by default. """log.debug("Loading JAR from %s ...",jar_path)ifnotentry_point:# try to parse main class from manifestself.manifest=self.get_manifest(jar_path)main_class=self.manifest.get("Main-Class",None)ifmain_class:entry_point=main_class+"."+"main"# the actual lifting is done by the Soot superclasssuper().__init__(jar_path,binary_stream,input_format="jar",entry_point=entry_point,entry_point_params=entry_point_params,jni_libs=jni_libs,jni_libs_ld_path=jni_libs_ld_path,**kwargs,)
[docs]@staticmethoddefis_compatible(stream):# check if stream is an archiveifnotSoot.is_zip_archive(stream):returnFalse# get filelistwithZipFile(stream)asjar:filelist=jar.namelist()# check for manifest and if a least one java class# file is availableif"META-INF/MANIFEST.MF"notinfilelist:returnFalseclass_files=[fforfinfilelistiff.endswith(".class")]iflen(class_files)==0:returnFalsereturnTrue
[docs]defget_manifest(self,binary_path=None):""" Load the MANIFEST.MF file :return: A dict of meta info :rtype: dict """path=binary_pathifbinary_pathelseself.binarywithZipFile(path)asjar:manifest=jar.open("META-INF/MANIFEST.MF","r")data={}forlineinmanifest.readlines():ifb":"inline:key,value=line.split(b":")data[key.strip().decode("utf-8")]=value.strip().decode("utf-8")returndata