def get_dos_locations(x: np.ndarray) -> tuple[list[list[int]], list[list[int]]]:
        """
        We identify the regions in the DOS header which we can perturb adversarially.

        There are a series of "magic numbers" in this method which relate to the structure of the PE file.
        1) mz_offset = 2: the first two bytes of a PE are fixed as MZ.
        2) 0x3C: offset to the pointer to the PE header. The pointer is 4 bytes long.
        3) 0x40: end of the pointer to the PE header.

        :return batch_of_starts: A list of start locations we can perturb.
                                 This will always have the same value of 2 and 64.
        :return batch_of_sizes: Size of the perturbations we can carry out.
        :return batch_of_starts: Start locations which we can perturb.
        """
        batch_of_starts = []
        batch_of_sizes = []
        mz_offset = 2

        for i in range(len(x)):
            size = []
            start = []

            pointer_to_pe_header = x[i, int(0x3C) : int(0x40)].astype(np.uint8)

            # combine 4 unint8 bytes into unit32
            pointer_to_pe_header = (
                pointer_to_pe_header[3] << 24
                | pointer_to_pe_header[2] << 16
                | pointer_to_pe_header[1] << 8
                | pointer_to_pe_header[0]
            )

            size.append(int(0x3C) - mz_offset)
            start.append(mz_offset)

            size.append(int(pointer_to_pe_header) - int(0x40) - 1)
            start.append(int(0x40))

            batch_of_starts.append(start)
            batch_of_sizes.append(size)

        return batch_of_starts, batch_of_sizes

        We identify the regions in the DOS header which we can perturb adversarially.

        There are a series of "magic numbers" in this method which relate to the structure of the PE file.
        1) mz_offset = 2: the first two bytes of a PE are fixed as MZ.
        2) 0x3C: offset to the pointer to the PE header. The pointer is 4 bytes long.
        3) 0x40: end of the pointer to the PE header.

        :return batch_of_starts: A list of start locations we can perturb.
                                 This will always have the same value of 2 and 64.
        :return batch_of_sizes: Size of the perturbations we can carry out.
        :return batch_of_starts: Start locations which we can perturb.
        
art/attacks/evasion/pe_malware_attack.py