def check_parameter(self, parent_function, first_method_list, second_method_list): """ Check the usage of the same parameter between two method. :param parent_function: function that call the first function and second functions at the same time. :param first_method_list: function which calls before the second method. :param second_method_list: function which calls after the first method. :return: True or False """ state = False for first_call_method in first_method_list: for second_call_method in second_method_list: pyeval = PyEval() # Check if there is an operation of the same register for bytecode_obj in self.apkinfo.get_method_bytecode( parent_function): # ['new-instance', 'v4', Lcom/google/progress/SMSHelper;] instruction = [bytecode_obj.mnemonic] if bytecode_obj.registers is not None: instruction.extend(bytecode_obj.registers) if bytecode_obj.parameter is not None: instruction.append(bytecode_obj.parameter) # for the case of MUTF8String instruction = [str(x) for x in instruction] if instruction[0] in pyeval.eval.keys(): pyeval.eval[instruction[0]](instruction) for table in pyeval.show_table(): for val_obj in table: for c_func in val_obj.called_by_func: first_method_pattern = f"{first_call_method.class_name}->{first_call_method.name}{first_call_method.descriptor}" second_method_pattern = f"{second_call_method.class_name}->{second_call_method.name}{second_call_method.descriptor}" if first_method_pattern in c_func and second_method_pattern in c_func: state = True # Build for the call graph if state: call_graph_analysis = { "parent": parent_function, "first_call": first_call_method, "second_call": second_call_method, "apkinfo": self.apkinfo, "first_api": self.quark_analysis.first_api, "second_api": self.quark_analysis.second_api, "crime": self.quark_analysis.crime_description, } self.quark_analysis.call_graph_analysis_list.append( call_graph_analysis) return state
def hasHandleRegister(first_method, second_method): """ Check the usage of the same parameter between two method. :param first_method: function which calls before the second method. :param second_method: function which calls after the first method. :return: True or False """ state = False result = set() if hasOrder(first_method, second_method): for mutual_parent in hasOrder(first_method, second_method): first_wrapper = [] second_wrapper = [] find_previous_method(first_method, mutual_parent, first_wrapper) find_previous_method(second_method, mutual_parent, second_wrapper) for first_call_method in first_wrapper: for second_call_method in second_wrapper: pyeval = PyEval() # Check if there is an operation of the same register for bytecode_obj in get_method_bytecode(mutual_parent): # ['new-instance', 'v4', Lcom/google/progress/SMSHelper;] instruction = [bytecode_obj.mnemonic] if bytecode_obj.registers is not None: instruction.extend(bytecode_obj.registers) if bytecode_obj.parameter is not None: instruction.append(bytecode_obj.parameter) # for the case of MUTF8String instruction = [str(x) for x in instruction] if instruction[0] in pyeval.eval.keys(): pyeval.eval[instruction[0]](instruction) for table in pyeval.show_table(): for val_obj in table: for c_func in val_obj.called_by_func: first_method_pattern = f"{first_call_method.class_name}->{first_call_method.name}{first_call_method.descriptor}" second_method_pattern = f"{second_call_method.class_name}->{second_call_method.name}{second_call_method.descriptor}" if (first_method_pattern in c_func and second_method_pattern in c_func): state = True result.add(mutual_parent) if state: return result return None
def check_parameter( self, common_method, first_method_name, second_method_name, ): """ check the usage of the same parameter between two method. :param common_method: function that call the first function and second functions at the same time. :param first_method_name: function which calls before the second method. :param second_method_name: function which calls after the first method. :return: True or False """ pyeval = PyEval() # Check if there is an operation of the same register state = False common_class_name, common_method_name = common_method for bytecode_obj in self.apkinfo.get_method_bytecode( common_class_name, common_method_name, ): # ['new-instance', 'v4', Lcom/google/progress/SMSHelper;] instruction = [bytecode_obj.mnemonic] if bytecode_obj.registers is not None: instruction.extend(bytecode_obj.registers) if bytecode_obj.parameter is not None: instruction.append(bytecode_obj.parameter) # for the case of MUTF8String instruction = [str(x) for x in instruction] if instruction[0] in pyeval.eval.keys(): pyeval.eval[instruction[0]](instruction) for table in pyeval.show_table(): for val_obj in table: matchers = [first_method_name, second_method_name] matching = [ s for s in val_obj.called_by_func if all(xs in s for xs in matchers) ] if matching: state = True break return state
def pyeval(): pyeval = PyEval() # mock_hash_table = [...[], [v4_mock_variable_obj], [], [], [v9_mock_variable_obj]....] v4_mock_variable_obj = VarabileObject("v4", "Lcom/google/progress/SMSHelper;", None) v9_mock_variable_obj = VarabileObject("v9", "some_string", "java.io.file.close()") pyeval.table_obj.insert(4, v4_mock_variable_obj) pyeval.table_obj.insert(9, v9_mock_variable_obj) yield pyeval del pyeval