def __save_source_file(self, src_file: str, prefix: str, ending: str, bbatt: BBAttackInstance) -> str: if Config.savemorelogfiles: b = bbatt.get_source_log_file_target(src_file=src_file, prefix=prefix, ending=ending) return " ".join(["cp", src_file, b, "\n"]) else: return "\n"
def __helper_for_attackinstance( self, tempattackinstance: BBAttackInstance, prefix: str, currenttransformer: evasion.Transformers.TransformerBase, seed: int): loadnewfeatures, error_code, transf_call = tempattackinstance.do_transformation_only( prefix=prefix, currenttransformer=currenttransformer, seed=seed) if error_code is not None: tempattackinstance.logger.logger.debug( "`{}`, T-id:{}, failed with: {}\n".format( transf_call, prefix, error_code)) remainingtransformations = 0 if error_code == "124" else None return transf_call, loadnewfeatures, None, None, remainingtransformations
def run_attack(self) -> typing.Tuple[bool, str]: try: # Init Attack Instance, this creates all the basic stuff including the output file. attackinstance = BBAttackInstance(sourceauthor = self.sauthor, attackdirauth=self.attackdirauth, targetauthor = self.tauthor, bbattackhandler=self) assert attackinstance.originaloutputhash is not None return True, "" except Exception as e: err_msg: str = "***HillClimbing: Unexpected ERROR *** {} with {}".format( self.sauthor.author, str(e)) print(err_msg, file=sys.stderr) traceback.print_tb(e.__traceback__) return False, str(err_msg)
def expand_node_single(self, attackinstance: BBAttackInstance, prefix: str, transformer_id, transformer_seed, newattackdir: str, log_directory: str): outertempattackinstance = attackinstance.clone(attackdirauth=newattackdir, newlogdir=log_directory) currenttransformerobj: TransformerBase = outertempattackinstance.transformerhandler. \ get_specified_transformation_per_uniqueid(uniqueid=transformer_id) queue_outer = [] ua.run_hill_simulation(args=(outertempattackinstance, prefix, currenttransformerobj, transformer_seed, queue_outer)) nextransformerindex, currenttransformer, besttransfcall, \ successtransf, scoreprednew, classprednew = queue_outer[0] if successtransf is not True: outertempattackinstance.cleandir(currentbaselevel=self.attackdirauth) raise ExpandNodeException("Chosen Transformation for next outer iteration not succesfull:" + str(besttransfcall) + "\n") result_string = " {}:`{}` successfull with {} ({}) [Before:{}({})]".\ format(prefix, besttransfcall, round(scoreprednew, 4), classprednew, round(outertempattackinstance.original_predscore, 4), self.tauthor.true_class) return outertempattackinstance, currenttransformerobj, result_string
def run_attack(self) -> AttackResult: try: # A. Init Attack Instance attackinstance = BBAttackInstance(sourceauthor = self.sauthor, attackdirauth=self.attackdirauth, targetauthor = self.tauthor, bbattackhandler=self) self.attackresult.initial_feature_vec = attackinstance.attack_data_merged.getfeaturematrix()[0, :].toarray().reshape(-1) current_root_node: Node = self.tree.root root_state: StateWithAttackInstance = StateWithAttackInstance(transformer=None, attackinstance=attackinstance) current_root_node.state = root_state # B. find next move multiple times for i in range(0, self.max_iterations): attackinstance.logger.logger.debug("\n\nOuter Iteration: {}".format(i)) # B-1 Expand tree to find a suitable next move. If we already succeed with a seq., we break. succesfull_attackinstance = self.mcts_core(attackinstance=attackinstance, outer_iteration_index=i) if succesfull_attackinstance is not None: attackinstance = succesfull_attackinstance break # B-2 Perform a single step move. If we already succeed, we break. attackinstance = self.perform_next_move(attackinstance=attackinstance, outer_iteration_index=i) if self.on_next_move_success(attackinstance=attackinstance) is True: break # B-3 Check for early stop. if self.check_for_early_stop(attackinstance=attackinstance, current_outer_iteration=i) is True: break # C. Finally, collect further information about source file after evasion self.attackresult.final_feature_vec = attackinstance.attack_data_merged.getfeaturematrix()[0, :].toarray().reshape(-1) assert attackinstance.log_chosentransformers.shape[1] == 5 # we expect 5 columns, adapt this value if more.. self.attackresult.log_chosentransformers = attackinstance.log_chosentransformers self.attackresult.extract_changes_linesofcode(pathtooriginalfile=attackinstance.original_source_file, pathtonewfile=attackinstance.source_file) attackinstance.logger.logger.info("-----> {} <----- from {} to {} \n". format(self.attackresult.attackstatus.name, self.sauthor.author, self.tauthor.author)) except Exception as e: err_msg: str = "***MCTS: Unexpected ERROR *** {} -> {} with {}".format( self.sauthor.author, self.tauthor.author, str(e)) print(err_msg, file=sys.stderr) traceback.print_tb(e.__traceback__) self.attackresult.attackstatus = AttackStatus.ERROR self.attackresult.error_message = [str(err_msg), traceback.format_exc()] finally: try: attackinstance.logger.close_logger() except Exception: print("Could not close logger in attackinstance", file=sys.stderr) return self.attackresult
def run_attack(self) -> typing.Tuple[str, bool]: try: # a. Init Attack Instance if self.secure_mode is True: attackinstance = BBAttackInstanceSecure( sourceauthor=self.sauthor, attackdirauth=self.attackdirauth, targetauthor=self.tauthor, bbattackhandler=self) else: attackinstance = BBAttackInstance( sourceauthor=self.sauthor, attackdirauth=self.attackdirauth, targetauthor=self.tauthor, bbattackhandler=self) queue = [] for i in range(0, self.max_iterations): seed = i * 9 + 7 # create log dir for current iteration logdir_iter = os.path.join(attackinstance.log_directory, "test" + str(seed)) os.makedirs(logdir_iter) newtemppath = os.path.join(self.attackdirauth, "temp" + str(seed), self.sauthor.author) tempattackinstance = attackinstance.clone( attackdirauth=newtemppath, newlogdir=logdir_iter) # ** Choose transformer ** currenttransformerobj: evasion.Transformers.TransformerBase = tempattackinstance.transformerhandler.\ get_specified_transformation_per_uniqueid(self.transformer_id) # ** Do transformation ** # -> Check if transformer is callable, may happen with AddTemplateTransformers, # e.g. if they do not have any target includes if currenttransformerobj.check_valid() is True: lasttransfcall, successtransf, scoreprednew, classprednew, remainingtransformers = \ self.__helper_for_attackinstance(tempattackinstance=tempattackinstance, prefix=str(seed), currenttransformer=currenttransformerobj, seed=seed) else: # if no valid transformation is there anymore, it is like a "Code 124: Empty Set"... lasttransfcall, successtransf, scoreprednew, classprednew, remainingtransformers = \ currenttransformerobj.transformer, False, None, None, 0 # ** Eval ** queue.append([ str(seed), currenttransformerobj, lasttransfcall, successtransf, scoreprednew, classprednew, remainingtransformers ]) if not successtransf: tempattackinstance.cleandir( currentbaselevel=attackinstance.attackdirauth) break else: attackinstance = tempattackinstance.clone( attackdirauth=attackinstance.attackdirauth, newlogdir=attackinstance.log_directory) tempattackinstance.cleandir( currentbaselevel=attackinstance.attackdirauth) # print how many successfull transformations were possible at all succ = np.sum( np.array([ successtransf for _, _, _, successtransf, _, _, _ in queue ])) remainingtransformers = queue[-1][6] nooftrials = len(queue) - 1 if remainingtransformers == 0 else len( queue) authstr = self.sauthor.author if self.sauthor.author == self.tauthor.author \ else (self.tauthor.author + "/" + self.sauthor.author) output: str = "{} had: {} / {}; remaining: {}".format( authstr, succ, nooftrials, remainingtransformers) print(output) if remainingtransformers == 0 else print( output, file=sys.stderr) return output, remainingtransformers == 0 except Exception as e: err_msg: str = "***Unexpected ERROR *** {} -> {} with {}".format( self.sauthor.author, self.tauthor.author, str(e)) printable_err_msg = "***Unexpected ERROR *** {} -> {} with {}".format( self.sauthor.author, self.tauthor.author, str(e)[0:(min(30, len(str(e))))]) print(printable_err_msg, file=sys.stderr) return err_msg, False finally: try: attackinstance.logger.close_logger() except Exception: pass