class_docstr: Implementation of the following white-box attacks related to PE malware crafting:
      1) Append based attacks (example paper link: https://arxiv.org/abs/1810.08280)
      2) Section insertion attacks (example paper link: https://arxiv.org/abs/2008.07125)
      3) Slack manipulation attacks (example paper link: https://arxiv.org/abs/1810.08280)
      4) DOS Header Attacks (example paper link: https://arxiv.org/abs/1901.03583)
class_docstr_tok: ["Implementation","of","the","following","white-box","attacks","related","to","PE","malware","crafting",":","1",")","Append","based","attacks","(","example","paper","link",":","https",":","\/\/arxiv.org\/abs\/1810.08280",")","2",")","Section","insertion","attacks","(","example","paper","link",":","https",":","\/\/arxiv.org\/abs\/2008.07125",")","3",")","Slack","manipulation","attacks","(","example","paper","link",":","https",":","\/\/arxiv.org\/abs\/1810.08280",")","4",")","DOS","Header","Attacks","(","example","paper","link",":","https",":","\/\/arxiv.org\/abs\/1901.03583",")"]
docstr: Create a new section in a PE file that the attacker can perturb to create an adversarial example.
  we are using the lief library (https://github.com/lief-project/LIEF) to manipulate the PE file.
  
  :param datapoint: either 1) path to file we want to analyse with lief and get the section information.
                    or 2) list of ints that can be processed by lief.
  
                    If we have already pre-processed the file into a numpy array, we convert it to a form
                    that can be read by lief.
                    eg, if we have it as a numpy array this could be done by:
  
                    datapoint = datapoint[0:size]  # size is the original size of the malware file
                    datapoint = datapoint.astype('uint8')
                    datapoint = datapoint.tolist()
  :param sample_size: Size of the original datapoint. Only if it is an array and the l0 budget is fractional
  :param padding_char: The char to use to pad the file to be of length maxlen
  :param maxlen: Maximum length of the data that the MalConv model can process
  :param bytes_to_assign: (Optional) how many bytes we wish to specify when inserting a new section.
                          If unspecified the whole l0 budget will be used on a single section.
  :param verbose: lief outputs a lot to the console, particularly if we are processing many files.
                  By default suppress printing of messages. Can be toggled on/off by True/False
  :return manipulated_data: Executable with section inserted and turned into a numpy array of
                            the appropriate size
  :return len(manipulated_file): Size of original file
  :return information_on_section.pointerto_raw_data: The start of the inserted section
  :return information_on_section.virtual_size: Size of the inserted section
  :return size_of_slack: Size of slack regions in this executable (including from the section we just inserted)
  :return start_of_slack: Start of slack regions in this executable (including from the section we just inserted)
docstr_tok: ["Create","a","new","section","in","a","PE","file","that","the","attacker","can","perturb","to","create","an","adversarial","example",".","we","are","using","the","lief","library","(","https",":","\/\/github.com\/lief-project\/LIEF",")","to","manipulate","the","PE","file",".",":","param","datapoint",":","either","1",")","path","to","file","we","want","to","analyse","with","lief","and","get","the","section","information",".","or","2",")","list","of","ints","that","can","be","processed","by","lief",".","If","we","have","already","pre-processed","the","file","into","a","numpy","array",",","we","convert","it","to","a","form","that","can","be","read","by","lief",".","eg",",","if","we","have","it","as","a","numpy","array","this","could","be","done","by",":","datapoint","=","datapoint","[","0",":","size","]","#","size","is","the","original","size","of","the","malware","file","datapoint","=","datapoint.astype","(","'uint8","'",")","datapoint","=","datapoint.tolist","(",")",":","param","sample_size",":","Size","of","the","original","datapoint",".","Only","if","it","is","an","array","and","the","l0","budget","is","fractional",":","param","padding_char",":","The","char","to","use","to","pad","the","file","to","be","of","length","maxlen",":","param","maxlen",":","Maximum","length","of","the","data","that","the","MalConv","model","can","process",":","param","bytes_to_assign",":","(","Optional",")","how","many","bytes","we","wish","to","specify","when","inserting","a","new","section",".","If","unspecified","the","whole","l0","budget","will","be","used","on","a","single","section",".",":","param","verbose",":","lief","outputs","a","lot","to","the","console",",","particularly","if","we","are","processing","many","files",".","By","default","suppress","printing","of","messages",".","Can","be","toggled","on\/off","by","True\/False",":","return","manipulated_data",":","Executable","with","section","inserted","and","turned","into","a","numpy","array","of","the","appropriate","size",":","return","len","(","manipulated_file",")",":","Size","of","original","file",":","return","information_on_section.pointerto_raw_data",":","The","start","of","the","inserted","section",":","return","information_on_section.virtual_size",":","Size","of","the","inserted","section",":","return","size_of_slack",":","Size","of","slack","regions","in","this","executable","(","including","from","the","section","we","just","inserted",")",":","return","start_of_slack",":","Start","of","slack","regions","in","this","executable","(","including","from","the","section","we","just","inserted",")"]
code: def insert_section(
      self,
      datapoint: Union[List[int], str],
      sample_size: Optional[int] = None,
      padding_char: int = 256,
      maxlen: int = 2**20,
      bytes_to_assign: Optional[int] = None,
      verbose: bool = False,
  ) -> Union[
      Tuple[np.ndarray, int, int, int, List[int], List[int]],
      Tuple[None, None, None, None, None, None],
  ]:  # pragma: no cover
      """
      Create a new section in a PE file that the attacker can perturb to create an adversarial example.
      we are using the lief library (https://github.com/lief-project/LIEF) to manipulate the PE file.
  
      :param datapoint: either 1) path to file we want to analyse with lief and get the section information.
                        or 2) list of ints that can be processed by lief.
  
                        If we have already pre-processed the file into a numpy array, we convert it to a form
                        that can be read by lief.
                        eg, if we have it as a numpy array this could be done by:
  
                        datapoint = datapoint[0:size]  # size is the original size of the malware file
                        datapoint = datapoint.astype('uint8')
                        datapoint = datapoint.tolist()
      :param sample_size: Size of the original datapoint. Only if it is an array and the l0 budget is fractional
      :param padding_char: The char to use to pad the file to be of length maxlen
      :param maxlen: Maximum length of the data that the MalConv model can process
      :param bytes_to_assign: (Optional) how many bytes we wish to specify when inserting a new section.
                              If unspecified the whole l0 budget will be used on a single section.
      :param verbose: lief outputs a lot to the console, particularly if we are processing many files.
                      By default suppress printing of messages. Can be toggled on/off by True/False
      :return manipulated_data: Executable with section inserted and turned into a numpy array of
                                the appropriate size
      :return len(manipulated_file): Size of original file
      :return information_on_section.pointerto_raw_data: The start of the inserted section
      :return information_on_section.virtual_size: Size of the inserted section
      :return size_of_slack: Size of slack regions in this executable (including from the section we just inserted)
      :return start_of_slack: Start of slack regions in this executable (including from the section we just inserted)
      """
      # pylint: disable=I1101
      import lief  # pylint: disable=C0415
  
      if not verbose:
          lief.logging.disable()
  
      binary = lief.PE.parse(datapoint)
  
      name_in_use = True
      while name_in_use:
          new_section_name = "." + "".join(
              chr(random.randrange(ord("a"), ord("z")))
              for _ in range(5)
          )
          name_in_use = False
  
          # check if the random name is already by chance in use
          for section in binary.sections:
              if new_section_name == section.name:
                  name_in_use = True
  
      new_section = lief.PE.Section(new_section_name)
  
      if bytes_to_assign is None:
          if self.l_0 < 1:  # l0 is a fraction of the filesize
              # if its a filepath we need to get the file size
              if isinstance(datapoint, str):
                  with open(datapoint, "rb") as file:
                      open_file = file.read()
                  sample_size = len(open_file)
              else:
                  if sample_size is None:
                      raise ValueError(
                          "if the data is an array and the l0 budget is fractional "
                          "the sample size must be provided"
                      )
  
              perturbation_size = int(sample_size * self.l_0)
          else:  # or l0 is interpreted as total perturbation size
              perturbation_size = int(self.l_0)
          new_section.content = [
              random.randint(0, 255) for _ in range(perturbation_size)
          ]
      else:
          new_section.content = [
              random.randint(0, 255) for _ in range(bytes_to_assign)
          ]
  
      # we add the new section at the end of the existing sections
      section_end_points = []
      for section in binary.sections:
          section_end_points.append(
              section.virtual_address + section.size
          )
  
      new_section.virtual_address = max(section_end_points)
  
      binary.add_section(
          new_section,
          random.choice(
              [
                  lief.PE.SECTION_TYPES.BSS,
                  lief.PE.SECTION_TYPES.DATA,
                  lief.PE.SECTION_TYPES.EXPORT,
                  lief.PE.SECTION_TYPES.IDATA,
                  lief.PE.SECTION_TYPES.RELOCATION,
                  lief.PE.SECTION_TYPES.RESOURCE,
                  lief.PE.SECTION_TYPES.TEXT,
                  lief.PE.SECTION_TYPES.TLS_,
                  lief.PE.SECTION_TYPES.UNKNOWN,
              ]
          ),
      )
  
      information_on_section = binary.get_section(new_section_name)
  
      size_of_slack = []
      start_of_slack = []
      for section in binary.sections:
          slack = section.sizeof_raw_data - section.virtual_size
          if slack > 0:
              size_of_slack.append(slack)
              start_of_slack.append(
                  section.pointerto_raw_data + section.virtual_size
              )
  
      builder = lief.PE.Builder(binary)
      builder.build()
  
      manipulated_file = np.array(builder.get_build(), dtype=np.uint8)
  
      manipulated_data = (
          np.ones((maxlen,), dtype=np.uint16) * padding_char
      )
  
      # Only process files which are less then the max file size supported
      if len(manipulated_file) < maxlen:
          manipulated_data[: len(manipulated_file)] = manipulated_file[
              :maxlen
          ]
  
          return (
              manipulated_data,
              len(manipulated_file),
              information_on_section.pointerto_raw_data,
              information_on_section.virtual_size,
              size_of_slack,
              start_of_slack,
          )
      return None, None, None, None, None, None
  
imports: import json
  import random
  import logging
  from typing import Optional, Union, Tuple, List, Dict, TYPE_CHECKING
  from tqdm.auto import trange
  import numpy
  from art.estimators.estimator import BaseEstimator, NeuralNetworkMixin
  from art.estimators.classification.classifier import ClassifierMixin
  from art.attacks.attack import EvasionAttack
label_desc: Use image node_id 14 for calling the MalwareGDTensorFlow obj's underlying member method code with example usage: obj.insert_section(datapoint, sample_size, padding_char, maxlen, bytes_to_assign, verbose) and returns: None,  None,  None,  None,  None,  None, manipulated_data,  len,  information_on_section,  information_on_section,  size_of_slack,  start_of_slack