/// <summary> /// Assembles repeated action detection. If program reads/writes/sends more than min_to_transfer the created/opened object is remebered in output place /// </summary> /// <param name="create_or_open_file">place whith object created/opened</param> /// <param name="zw_read_file_api">place with read behavior. DELETE</param> /// <param name="min_to_transfer">Min number of bytes to transfer for detection</param> /// <returns>Place with unique set of objects from where more than min_to_read bytes were read by program. This procedure DELETES from {place with read behavior}</returns> private Place AccumulatedBytesCheckAssemble(Place create_or_open_object, Place action_api, int min_to_transfer, string accumulator_field_name, string human_readable_prefix) { Place transfer_data_from_object = CPNetBlocks.getPlaceClosedByZwClose(human_readable_prefix + "_transfer_data_from_object", "FileHandle").setPrintLevel(Place.PrintLevel.Low); CPNetBlocks.assembleDiInputStructure( create_or_open_object, Arc.DEFAULT_WEIGHT, Delete.No, action_api, Arc.MIN_WEIGHT, Delete.Yes, transfer_data_from_object, EQUAL(Hook_ZwCreateFile.Color.FileHandle, "FileHandle") ).generating_expression = tuple => { Token result = new Token(tuple[action_api]); result.loadFields(new string[] { "ObjectName" }, string.Empty, tuple[create_or_open_object]); result.prevTuple = tuple; return(result); }; //add read more than limit subnet from the first time CPNetBlocks.assembleDiInputStructure( action_api, Delete.Yes, transfer_data_from_object, Delete.Yes, transfer_data_from_object, (token1, token2) => token1["FileHandle"].Equals(token2["FileHandle"]) && to_int(token2[accumulator_field_name]) < min_to_transfer ).generating_expression = tuple => { Token result = new Token(tuple[transfer_data_from_object]); result[accumulator_field_name] = to_int(tuple[transfer_data_from_object][accumulator_field_name]) + to_int(tuple[action_api][accumulator_field_name]); return(result); }; Place excessive_tranfers = CPNetBlocks.getPlaceClosedByZwClose(human_readable_prefix + "_excessive_transfers", "FileHandle").setPrintLevel(Place.PrintLevel.Low); CPNetBlocks.assembleDiInputStructure( action_api, Arc.MAX_WEIGHT, Delete.Yes, transfer_data_from_object, Arc.DEFAULT_WEIGHT, Delete.No, excessive_tranfers, (token1, token2) => token1["FileHandle"].Equals(token2["FileHandle"]) && to_int(token2[accumulator_field_name]) >= min_to_transfer ).generating_expression = tuple => new Token(tuple[transfer_data_from_object]); Place remember_transfers = new Place(human_readable_prefix + "_remember_transfers").setPrintLevel(Place.PrintLevel.Low); //remember_file_read.addReaction(new Place.Reaction(printCauseToken)); CPNetBlocks.assembleMonoInputStructure( transfer_data_from_object, Arc.MIN_WEIGHT, Delete.No, remember_transfers, (token) => to_int(token[accumulator_field_name]) >= min_to_transfer ).generating_expression = tuple => new Token(tuple[transfer_data_from_object]); Place remember_transfers_unique = new Place(human_readable_prefix + "_remember_transfers_unique"); //remember_file_read_unique.addReaction(new Place.Reaction(printCauseToken)); CPNetBlocks.assembleEliminateDuplicateItems(remember_transfers, remember_transfers_unique, (token1, token2) => CPNetBlocks.strings_equal_ignore_case(token1["ObjectName"], token2["ObjectName"])); return(remember_transfers_unique); }