def __init__(self, path_to_source, build_directory=None): """ :param path_to_source: Path to directory, APK, or a .java file :param build_directory: directory to unpack and decompile APK to. If directory does not exist it will be created, defaults to same directory as APK/qark """ if not os.path.exists(path_to_source): raise ValueError("Invalid path, path must be to an APK, directory, or a Java file") self.path_to_source = path_to_source self.build_directory = os.path.join(build_directory, "qark") if build_directory else os.path.join(os.path.dirname(os.path.abspath(path_to_source)), "qark") # validate we are running on an APK, Directory, or Java source code if os.path.isfile(self.path_to_source) and os.path.splitext(self.path_to_source.lower())[1] not in (".java", ".apk"): raise ValueError("Invalid path, path must be to an APK, directory, or a Java file") if os.path.isdir(path_to_source) or is_java_file(path_to_source): self.source_code = True self.manifest_path = None log.debug("Decompiler got directory to run on, assuming Java source code") return self.source_code = False self.apk_name = os.path.splitext(os.path.basename(path_to_source))[0] # name of APK without the .apk extension self.dex_path = self._unpack_apk() self.jar_path = self._run_dex2jar() self.manifest_path = self.run_apktool() self.decompilers = DECOMPILERS
def _gather_files(self): """Walks the `path_to_source` and updates the `self.files` set with new files.""" if is_java_file(self.path_to_source): self.files.add(self.path_to_source) log.debug("Added single java file to scanner") return log.debug("Adding files to scanner...") try: for (dir_path, _, file_names) in walk(self.path_to_source): for file_name in file_names: fullPath = path.join(dir_path, file_name) notIgnored = True for j in IGNORE_FILES: if fullPath.lower().find(j.lower()) > -1: notIgnored = False log.debug("ignore: " + fullPath) break if notIgnored: st = stat(fullPath) if st.st_size > 0.2 * 1024 * 1024: if is_binary_string( open(fullPath, 'rb').read(1024)): notIgnored = False log.debug("ignore binary: " + fullPath) if notIgnored: self.files.add(fullPath) except AttributeError: log.debug("Decompiler does not have a build directory")
def update(self, file_path, call_run=False): if not self.parseable: return if self.java_ast is None and is_java_file(file_path): # Make sure the file contents have been set super(JavaASTPlugin, self).update(file_path, call_run=False) if self.file_contents: try: JavaASTPlugin.java_ast = javalang.parse.parse( self.file_contents) except (javalang.parser.JavaSyntaxError, IndexError): log.debug("Unable to parse AST for file %s", self.file_path) JavaASTPlugin.java_ast = None JavaASTPlugin.parseable = False return except: log.debug("LexerError from tokenizer.py has raised!") log.debug("Unable to parse file %s", self.file_path) JavaASTPlugin.java_ast = None JavaASTPlugin.parseable = False return if call_run and self.java_ast is not None: self.run()
def java_files_from_files(files): """ Returns a generator of everything in `files` that ends with the `.java` extension. :param list files: :return: generator of file paths """ return (file_path for file_path in files if is_java_file(file_path))
def _gather_files(self): """Walks the `path_to_source` and updates the `self.files` set with new files.""" if is_java_file(self.path_to_source): self.files.add(self.path_to_source) log.debug("Added single java file to scanner") return log.debug("Adding files to scanner...") try: for (dir_path, _, file_names) in walk(self.path_to_source): for file_name in file_names: self.files.add(path.join(dir_path, file_name)) except AttributeError: log.debug("Decompiler does not have a build directory")
def run(self): if not is_java_file(self.file_path): return for line_number, line in enumerate(self.file_contents.split('\n')): http_url_match = re.search(HTTP_URL_REGEX, line) if http_url_match: self.issues.append( Issue(category=self.category, severity=self.severity, name=self.name, description=self.description.format( http_url=http_url_match.group(0)), file_object=self.file_path, line_number=(line_number, 0)))