def parse_location(self): """Parse files in specified location""" for root, dirs, files in os.walk(self.location): for f in files: if f.endswith(self.suffix): # TODO: What about Windows paths? file_path = root + "/" + f # Set current path self.current_path = file_path # Parse file log.debug("Parsing file:\t %s" % f) self.parse_file(file_path)
def is_class_method(self, line): """Check if line contains a method definition Args: line (str): Text line to be checked Returns: bool: True if line contains method information, otherwise False """ match = re.search("\.method\s+(?P<method>.*)$", line) if match: log.debug("\t\tFound method: %s" % match.group('method')) return match.group('method') else: return None
def is_class(self, line): """Check if line contains a class definition Args: line (str): Text line to be checked Returns: bool: True if line contains class information, otherwise False """ match = re.search("\.class\s+(?P<class>.*);", line) if match: log.debug("Found class: %s" % match.group('class')) return match.group('class') else: return None
def is_class_parent(self, line): """Check if line contains a class parent definition Args: line (str): Text line to be checked Returns: bool: True if line contains class parent information, otherwise False """ match = re.search("\.super\s+(?P<parent>.*);", line) if match: log.debug("\t\tFound parent class: %s" % match.group('parent')) return match.group('parent') else: return None
def is_method_call(self, line): """Check [MaÔif the line contains a method call (invoke-*) Args: line (str): Text line to be checked Returns: bool: True if line contains call information, otherwise False """ match = re.search("invoke-\w+(?P<invoke>.*)", line) if match: log.debug("\t\t Found invoke: %s" % match.group('invoke')) return match.group('invoke') else: return None
def is_class_property(self, line): """Check if line contains a field definition Args: line (str): Text line to be checked Returns: bool: True if line contains class property information, otherwise False """ match = re.search("\.field\s+(?P<property>.*);", line) if match: log.debug("\t\tFound property: %s" % match.group('property')) return match.group('property') else: return None
def add_class(self, class_obj): """Add new class Args: class_obj (dict): Class object to insert """ log.debug(class_obj) new_class = SmaliClass(class_name=class_obj['name'], class_type=class_obj['type'], class_package=class_obj['package'], depth=class_obj['depth'], path=class_obj['path']) # Add new class self.classes[class_obj['name']] = new_class self.db.merge(new_class)
def is_const_string(self, line): """Check if line contains a const-string Args: line (str): Text line to be checked Returns: bool: True if line contains const-string information, otherwise False """ match = re.search("const-string\s+(?P<const>.*)", line) if match: log.debug("\t\tFound const-string: %s" % match.group('const')) return match.group('const') else: return None
def is_annotation(self, line): """Check if line contains an annotation definition Args: line (str): Text line to be checked Returns: bool: True if line contains annotation information, otherwise False """ match = re.search("\.annotation\s+(?P<type>[a-z]+)\s+(?P<class>.*)$", line) if match: log.debug("\t\tFound annotation: %s" % match.group('class')) return match.group('class') else: log.debug("\t\tNot annotation: %s" % line) return None
def add_class(self, class_obj): """Add new class Args: class_obj (dict): Class object to insert """ log.debug(class_obj) new_class = SmaliClass( class_name=class_obj['name'], class_type=class_obj['type'], class_package=class_obj['package'], depth=class_obj['depth'], path=class_obj['path'] ) # Add new class self.classes[class_obj['name']] = new_class self.db.merge(new_class)
def extract_class(self, data): """Extract class information Args: data (str): Data would be sth like: public static Lcom/a/b/c Returns: dict: Returns a class object, otherwise None """ class_info = data.split(" ") log.debug("class_info: %s" % class_info[-1].split('/')[:-1]) c = { # Last element is the class name 'name': class_info[-1], # Package name 'package': ".".join(class_info[-1].split('/')[:-1]), # Class deepth 'depth': len(class_info[-1].split("/")), # All elements refer to the type of class 'type': " ".join(class_info[:-1]), # Current file path 'path': self.current_path, # Properties 'properties': [], # Const strings 'const-strings': [], # Methods 'methods': [], # Annotations 'annotations': [], } return c
def extract_class(self, data): """Extract class information Args: data (str): Data would be sth like: public static Lcom/a/b/c Returns: dict: Returns a class object, otherwise None """ class_info = data.split(" ") log.debug("class_info: %s" % class_info[-1].split('/')[:-1]) c = { # Last element is the class name 'name': class_info[-1], # Package name 'package': ".".join(class_info[-1].split('/')[:-1]), # Class deepth 'depth': len(class_info[-1].split("/")), # All elements refer to the type of class 'type': " ".join(class_info[:-1]), # Current file path 'path': self.current_path, # Properties 'properties': [], # Const strings 'const-strings': [], # Methods 'methods': [] } return c
def search_call(self, args={}): result = None query = self.db.query(SmaliCall) # - Apply filters ---------------------------------------------------- # from class if "from_class" in args: if args["from_class"]: log.debug("from_class = %s" % args["from_class"]) query = query.filter(SmaliCall.from_class.contains(args["from_class"])) # from method if "from_method" in args: if args["from_method"]: log.debug("from_method = %s" % args["from_method"]) query = query.filter(SmaliCall.from_method.contains(args["from_method"])) # to class if "to_class" in args: if args["to_class"]: log.debug("to_class = %s" % args["to_class"]) query = query.filter(SmaliCall.dst_class.contains(args["to_class"])) # to method if "to_method" in args: if args["to_method"]: log.debug("to_method = %s" % args["to_method"]) query = query.filter(SmaliCall.dst_method.contains(args["to_method"])) # local arguments if "local_args" in args: if args["local_args"]: log.debug("local_args = %s" % args["local_args"]) query = query.filter(SmaliCall.local_args.contains(args["local_args"])) # destination arguments if "dest_args" in args: if args["dest_args"]: log.debug("dest_args = %s" % args["dest_args"]) query = query.filter(SmaliCall.dest_args.contains(args["dest_args"])) # - Make query and return results ------------------------------------ result = query.all() # Return results return result
def search_call(self, args={}): result = None query = self.db.query(SmaliCall) # - Apply filters ---------------------------------------------------- # from class if 'from_class' in args: if args['from_class']: log.debug("from_class = %s" % args['from_class']) query = query.filter( SmaliCall.from_class.contains(args['from_class'])) # from method if 'from_method' in args: if args['from_method']: log.debug("from_method = %s" % args['from_method']) query = query.filter( SmaliCall.from_method.contains(args['from_method'])) # to class if 'to_class' in args: if args['to_class']: log.debug("to_class = %s" % args['to_class']) query = query.filter( SmaliCall.dst_class.contains(args['to_class'])) # to method if 'to_method' in args: if args['to_method']: log.debug("to_method = %s" % args['to_method']) query = query.filter( SmaliCall.dst_method.contains(args['to_method'])) # local arguments if 'local_args' in args: if args['local_args']: log.debug("local_args = %s" % args['local_args']) query = query.filter( SmaliCall.local_args.contains(args['local_args'])) # destination arguments if 'dest_args' in args: if args['dest_args']: log.debug("dest_args = %s" % args['dest_args']) query = query.filter( SmaliCall.dest_args.contains(args['dest_args'])) # - Make query and return results ------------------------------------ result = query.all() # Return results return result