def logo(): """ Output our amazing logo :return: None """ print( bold( lightyellow( """ ________ __ \\_____ \\ __ _______ _______| | __ / / \\ \\| | \\__ \\_ __ \\ |/ / / \\_/. \\ | // __ \\| | \\/ < \\_____\\ \\_/____/(____ /__| |__|_ \\ \\__> \\/ \\/ v{} """ ), ).format(__version__) + bold( lightblue( """ An Obfuscation-Neglect Android Malware Scoring System """ ), ), )
def show_label_report(self, rule_path, all_labels, table_version): """ Show the report based on label, last column represents max confidence for that label :param rule_path: the path where may be present the file label_desc.csv. :param all_labels: dictionary containing label:<array of confidence values associated to that label> :return: None """ label_desc = {} # clear table to manage max/detail version self.quark_analysis.label_report_table.clear() if os.path.isfile(os.path.join(rule_path, "label_desc.csv")): # associate to each label a description col_list = ["label", "description"] # csv file on form <label,description> # put this file in the folder of rules (it must not be a json file since it could create conflict with management of rules) df = pd.read_csv( os.path.join(rule_path, "label_desc.csv"), usecols=col_list ) label_desc = dict(zip(df["label"], df["description"])) for label_name in all_labels: confidences = np.array(all_labels[label_name]) if table_version == "max": self.quark_analysis.label_report_table.field_names = [ "Label", "Description", "Number of rules", "MAX Confidence %", ] self.quark_analysis.label_report_table.add_row( [ green(label_name), yellow(label_desc.get(label_name, "-")), (len(confidences)), red(np.max(confidences)), ] ) else: self.quark_analysis.label_report_table.field_names = [ "Label", "Description", "Number of rules", "MAX Confidence %", "AVG Confidence", "Std Deviation", "# of Rules with Confidence >= 80%", ] self.quark_analysis.label_report_table.add_row( [ green(label_name), yellow(label_desc.get(label_name, "-")), (len(confidences)), red(np.max(confidences)), magenta(round(np.mean(confidences), 2)), lightblue(round(np.std(confidences), 2)), lightyellow(np.count_nonzero(confidences >= 80)), ] )
def logo(): print( bold( lightyellow(""" ________ __ \_____ \ __ _______ _______| | __ / / \ \| | \__ \\_ __ \ |/ / / \_/. \ | // __ \| | \/ < \_____\ \_/____/(____ /__| |__|_ \\ \__> \/ \/ v{} """)).format("20.01") + bold( lightblue(""" An Obfuscation-Neglect Android Malware Scoring System """)))
def first_stage_rule_generate(self, apis_pool): """ Extract all api usage in apk current apk then generate method combination. """ # Check if apk parsable if not self.check_apk_parsable(): self.set_progress_status(4) return # Check apk progress if not self.check_progress(): return api_generator = ApiGenerator(self.apk.apis) origin_apis = list(api_generator.generate()) # Setup progress bar origin_apis_num = len(origin_apis) outter_desc = f"Core No.{self.pbar}" outter_loop = tqdm(apis_pool, desc=outter_desc, position=self.pbar, leave=False) for api1 in apis_pool: outter_loop.update(1) # Tag the method if not self.db.check_analysis_progress(api1.id, self.apk.id): tqdm.write( "{}, {}->{} has done in apk progress move forward".format( colors.lightblue(api1.id), api1.class_name, api1.method_name)) continue # Skip current api if it is not exist if self.apk.apk_analysis.apkinfo.find_method( api1.class_name, api1.method_name, api1.descriptor) is None: tqdm.write( "{}, {}->{} does not exist in apk move forward".format( api1.id, api1.class_name, api1.method_name)) continue matched_list = [] id_list = [] for num, api2 in enumerate(origin_apis, start=1): inner_desc = f"{num}/{origin_apis_num}" outter_loop.set_postfix(inner_loop=inner_desc, refresh=True) api = api2 # Skip same api if api2.id == api1.id: continue _comb = { "crime": "", "x1_permission": [], "x2n3n4_comb": [{ "class": api1.class_name, "method": api1.method_name, "descriptor": api1.descriptor }, { "class": api2.class_name, "method": api2.method_name, "descriptor": api2.descriptor }], "yscore": 1 } comb = GenRuleObject(_comb) try: result = self.apk.apk_analysis.run(comb) except KeyboardInterrupt: self.set_progress_status(2) raise except Exception as e: tqdm.write( "{} and {} combination has some error when analyzing, ERROR MESSAGE: {}" .format(api1.id, api2.id, e)) continue if not comb.check_item[4]: continue # tqdm.write("{} and {} matched check!".format( # colors.green(api1.id), colors.green(api2.id))) matched_list.append({"m1": api1.id, "m2": api2.id}) id_list.append(api1.id + api2.id) # Insert matched combination to database and update progress if not self.db.update_analysis_progress(api1.id, self.apk.id): tqdm.write(f"Error occured while update progress: {api1.id}") if not self.db.save_matched_comb(self.apk.id, matched_list, id_list): tqdm.write("some Error occure") # Second stage rule generate # self.sec_stage_rule_generate(matched_list) # Apk completed analyzing outter_loop.clear() outter_loop.close() self.set_progress_status(1) return