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