def test_remove_dup_list(): assert tools.remove_dup_list([]) == [] assert tools.remove_dup_list([1, 2, 3, 4, 3, 4, 2]) == [1, 2, 3, 4] assert len(tools.remove_dup_list([1, 2, 3, 4, 3, 4, 2])) == 4 assert set(tools.remove_dup_list(["hello", "test", "test"])) == set(["hello", "test"]) assert len(tools.remove_dup_list(["hello", "test", "test"])) == 2 assert tools.remove_dup_list([2.0, 30, 4.0, 2.0]) == [2.0, 4.0, 30] assert len(tools.remove_dup_list([2.0, 30, 4.0, 2.0])) == 3 assert tools.remove_dup_list([1, 2, 3]) == [1, 2, 3]
def upperfunc(self, class_name, method_name): """ Return the upper level method from given class name and method name. :param class_name: :param method_name: :return: list """ result = [] method_set = self.find_method(class_name, method_name) if method_set is not None: for md in method_set: for _, call, _ in md.get_xref_from(): # Get class name and method name: # call.class_name, call.name result.append((call.class_name, call.name)) return tools.remove_dup_list(result) else: return None
def upperfunc(self, class_name, method_name): """ Return the upper level method from given class name and method name. :param class_name: the class name of the Android API :param method_name: the method name of the Android API :return: a list of all upper functions """ upperfunc_result = [] method_set = self.find_method(class_name, method_name) if method_set is not None: for method in method_set: for _, call, _ in method.get_xref_from(): # Get class name and method name: # call.class_name, call.name upperfunc_result.append((call.class_name, call.name)) return tools.remove_dup_list(upperfunc_result) return None
def test_remove_dup_list_with_invalid_arg(): with pytest.raises(TypeError): remove_dup_list(123)
def test_remove_dup_list_with_floats(): assert remove_dup_list([2.0, 30, 4.0, 2.0]) == [2.0, 4.0, 30]
def test_remove_dup_list_with_strings(): assert set(remove_dup_list(["hello", "test", "test"])) == { "hello", "test", }
def test_remove_dup_list_with_numbers(): assert remove_dup_list([1, 2, 3, 4, 3, 4, 2]) == [1, 2, 3, 4]
def test_remove_dup_list_with_empty_list(): assert remove_dup_list([]) == []
def _get_methods_classified(self, dexindex): rz = self._get_rz(dexindex) method_json_list = rz.cmdj("isj") method_dict = defaultdict(list) for json_obj in method_json_list: if json_obj.get("type") not in ["FUNC", "METH"]: continue # -- Descriptor -- full_method_name = json_obj["name"] raw_argument_str = next( re.finditer("\\(.*\\).*", full_method_name), None) if raw_argument_str is None: continue raw_argument_str = raw_argument_str.group(0) if raw_argument_str.endswith(")"): # Convert Java lauguage type to JVM type signature # Parse the arguments raw_argument_str = raw_argument_str[1:-1] arguments = [ self._convert_type_to_type_signature(arg) for arg in raw_argument_str.split(", ") ] # Parse the return type return_type = next( re.finditer("[A-Za-zL][A-Za-z0-9L/\\;[\\]$.]+ ", full_method_name), None, ) if return_type is None: print(f"Unresolved method signature: {full_method_name}") continue return_type = return_type.group(0).strip() # Convert raw_argument_str = ( "(" + " ".join(arguments) + ")" + self._convert_type_to_type_signature(return_type)) descriptor = descriptor_to_androguard_format(raw_argument_str) # -- Method name -- method_name = json_obj["realname"] # -- Is imported -- is_imported = json_obj["is_imported"] # -- Class name -- # Test if the class name is truncated escaped_method_name = self._escape_str_in_rizin_manner(method_name) if escaped_method_name.endswith("_"): escaped_method_name = escaped_method_name[:-1] flag_name = json_obj["flagname"] # sym.imp.clone doesn't belong to a class if flag_name == "sym.imp.clone": method = MethodObject( class_name="", name="clone", descriptor="()Ljava/lang/Object;", cache=RizinCache(json_obj["vaddr"], dexindex, is_imported), ) method_dict[""].append(method) continue if escaped_method_name not in flag_name: logging.warning( f"The class name may be truncated: {json_obj['flagname']}") # Drop the method name match = None for match in re.finditer("_+[A-Za-z]+", flag_name): pass if match is None: logging.warning( f"Skip the damaged flag: {json_obj['flagname']}") continue match = match.group(0) flag_name = flag_name[:flag_name.rfind(match)] # Drop the prefixes sym. and imp. while flag_name.startswith("sym.") or flag_name.startswith("imp."): flag_name = flag_name[4:] class_name = self._convert_type_to_type_signature(flag_name) # Append the method method = MethodObject( class_name=class_name, name=method_name, descriptor=descriptor, cache=RizinCache(json_obj["vaddr"], dexindex, is_imported), ) method_dict[class_name].append(method) # Remove duplicates for class_name, method_list in method_dict.items(): method_dict[class_name] = remove_dup_list(method_list) return method_dict