def __adjust_base_relocation_table(self, header_offset):

        offset_to_base_relocation_table_rva_within_header = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_BASE_RELOCATION_TABLE_RVA
        base_relocation_table_rva = MultiByteHandler.get_dword_given_offset(self.binary_data, offset_to_base_relocation_table_rva_within_header)

        if base_relocation_table_rva == 0x0:
            return

        offset_to_base_relocation_table_size = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_BASE_RELOCATION_TABLE_SIZE
        base_relocation_table_size = MultiByteHandler.get_dword_given_offset(self.binary_data, offset_to_base_relocation_table_size)

        base_relocation_table_raw = Win32BinaryUtils.convert_rva_to_raw(self.binary_data, header_offset, base_relocation_table_rva)
        current_base_relocation_table_raw = base_relocation_table_raw

        while current_base_relocation_table_raw < base_relocation_table_raw + base_relocation_table_size:
            rva_of_block = MultiByteHandler.get_dword_given_offset(self.binary_data, current_base_relocation_table_raw)
            size_of_block = MultiByteHandler.get_dword_given_offset(self.binary_data, current_base_relocation_table_raw + 0x4)
            if not Win32BinaryUtils.rva_is_after_entrypoint_and_requires_change(self.binary_data, header_offset, rva_of_block):
                current_base_relocation_table_raw += size_of_block
                continue

            type_rva_offset = current_base_relocation_table_raw + 0x8 #Type RVA entries start two dwords after the beginning of the block
            number_of_type_rva_entries = (int)((size_of_block - 0x8)/0x2)

            for type_rva_index in range(0, number_of_type_rva_entries):
                type_rva = MultiByteHandler.get_word_given_offset(self.binary_data, type_rva_offset)
                if type_rva != 0x0:
                    MultiByteHandler.set_word_given_offset(self.binary_data, type_rva_offset, type_rva + self.rva_delta)
                type_rva_offset += 0x2

            MultiByteHandler.set_dword_given_offset(self.binary_data, current_base_relocation_table_raw, rva_of_block + self.rva_delta)
            current_base_relocation_table_raw += size_of_block
        # Adjusting RVA on Data Directories header.
        MultiByteHandler.set_dword_given_offset(self.binary_data, offset_to_base_relocation_table_rva_within_header, base_relocation_table_rva + self.rva_delta)
    def __adjust_standard_coff_fields_and_coff_header(self, header_offset,
                                                      size_of_new_section):

        # Set size of code
        size_of_code_offset = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_SIZE_OF_CODE
        current_size_of_code = MultiByteHandler.get_dword_given_offset(
            self.binary_data, size_of_code_offset)
        MultiByteHandler.set_dword_given_offset(
            self.binary_data, size_of_code_offset,
            current_size_of_code + size_of_new_section)

        # Adjust number of sections
        number_of_sections_offset = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_NUMBER_OF_SECTIONS
        number_of_sections = MultiByteHandler.get_word_given_offset(
            self.binary_data, number_of_sections_offset)
        number_of_sections += 1
        MultiByteHandler.set_word_given_offset(self.binary_data,
                                               number_of_sections_offset,
                                               number_of_sections)

        if self.rva_delta != 0:
            # Adjust address of entrypoint
            address_of_entrypoint = MultiByteHandler.get_dword_given_offset(
                self.binary_data, header_offset +
                Win32BinaryOffsetsAndSizes.OFFSET_TO_ENTRYPOINT_RVA)
            address_of_entrypoint += self.rva_delta
            MultiByteHandler.set_dword_given_offset(
                self.binary_data, header_offset +
                Win32BinaryOffsetsAndSizes.OFFSET_TO_ENTRYPOINT_RVA,
                address_of_entrypoint)

            # Adjust BaseOfCode
            base_of_code_rva = MultiByteHandler.get_dword_given_offset(
                self.binary_data, header_offset +
                Win32BinaryOffsetsAndSizes.OFFSET_TO_BASE_OF_CODE_RVA)
            base_of_code_rva += self.rva_delta
            MultiByteHandler.set_dword_given_offset(
                self.binary_data, header_offset +
                Win32BinaryOffsetsAndSizes.OFFSET_TO_BASE_OF_CODE_RVA,
                base_of_code_rva)

            # Adjust BaseOfData
            base_of_data_rva = MultiByteHandler.get_dword_given_offset(
                self.binary_data, header_offset +
                Win32BinaryOffsetsAndSizes.OFFSET_TO_BASE_OF_DATA_RVA)
            base_of_data_rva += self.rva_delta
            MultiByteHandler.set_dword_given_offset(
                self.binary_data, header_offset +
                Win32BinaryOffsetsAndSizes.OFFSET_TO_BASE_OF_DATA_RVA,
                base_of_data_rva)
    def __get_new_header(self, virtual_size, virtual_address, size_of_raw_data,
                         pointer_to_raw_data):
        """
        :param virtual_size:
        :param virtual_address:
        :param size_of_raw_data:
        :param pointer_to_raw_data:
        :return: Returns a new header for the shellcode section.
        """

        new_section_header = [
            0
        ] * Win32BinaryOffsetsAndSizes.SIZE_OF_SECTION_HEADER
        new_section_header_index = 0

        section_name_bytes = '.scode\00\00'.encode('utf-8')
        first_half = section_name_bytes[3::-1]
        second_half = section_name_bytes[-1:-5:-1]
        MultiByteHandler.set_dword_given_offset(
            new_section_header, new_section_header_index,
            int("".join("{:02x}".format(ord(c)) for c in first_half), 16))
        MultiByteHandler.set_dword_given_offset(
            new_section_header, new_section_header_index + 4,
            int("".join("{:02x}".format(ord(c)) for c in second_half), 16))
        new_section_header_index += 8

        MultiByteHandler.set_dword_given_offset(new_section_header,
                                                new_section_header_index,
                                                virtual_size)
        new_section_header_index += 4

        MultiByteHandler.set_dword_given_offset(new_section_header,
                                                new_section_header_index,
                                                virtual_address)
        new_section_header_index += 4

        MultiByteHandler.set_dword_given_offset(new_section_header,
                                                new_section_header_index,
                                                size_of_raw_data)
        new_section_header_index += 4

        MultiByteHandler.set_dword_given_offset(new_section_header,
                                                new_section_header_index,
                                                pointer_to_raw_data)
        new_section_header_index += 4

        pointer_to_relocations = 0
        MultiByteHandler.set_dword_given_offset(new_section_header,
                                                new_section_header_index,
                                                pointer_to_relocations)
        new_section_header_index += 4
        pointer_to_line_numbers = 0
        MultiByteHandler.set_dword_given_offset(new_section_header,
                                                new_section_header_index,
                                                pointer_to_line_numbers)
        new_section_header_index += 4
        number_of_relocations = 0
        MultiByteHandler.set_word_given_offset(new_section_header,
                                               new_section_header_index,
                                               number_of_relocations)
        new_section_header_index += 2
        number_of_line_numbers = 0
        MultiByteHandler.set_word_given_offset(new_section_header,
                                               new_section_header_index,
                                               number_of_line_numbers)
        new_section_header_index += 2
        characteristics = (0x00000020 | 0x20000000 | 0x40000000)
        MultiByteHandler.set_dword_given_offset(new_section_header,
                                                new_section_header_index,
                                                characteristics)
        return new_section_header