Skip to content

unpacker.py

ofrak.core.pe.unpacker

PeUnpacker (Unpacker)

unpack(self, resource, config=None) async

Unpack a PE file using the pefile library for the parsing itself, then create the appropriate OFRAK child resources for the PE file.

Source code in ofrak/core/pe/unpacker.py
async def unpack(self, resource: Resource, config=None):
    """
    Unpack a PE file using the pefile library for the parsing itself, then
    create the appropriate OFRAK child resources for the PE file.
    """
    pe = pefile.PE(data=await resource.get_data())

    # MS-DOS header
    ms_dos_header = self.ms_dos_header_from_pefile(pe.DOS_HEADER)
    await resource.create_child_from_view(
        ms_dos_header,
        data_range=Range.from_size(pe.DOS_HEADER.get_file_offset(), pe.DOS_HEADER.sizeof()),
    )

    # File header
    file_header = self.file_header_from_pefile(pe.FILE_HEADER)
    await resource.create_child_from_view(
        file_header,
        data_range=Range.from_size(pe.FILE_HEADER.get_file_offset(), pe.FILE_HEADER.sizeof()),
    )

    # Optional header
    if pe.OPTIONAL_HEADER is not None:
        optional_header = self.optional_header_from_pefile(pe.OPTIONAL_HEADER)
        await resource.create_child_from_view(
            optional_header,
            data_range=Range.from_size(
                pe.OPTIONAL_HEADER.get_file_offset(), pe.OPTIONAL_HEADER.sizeof()
            ),
        )

        # Data directories
        for pe_data_directory in pe.OPTIONAL_HEADER.DATA_DIRECTORY:
            data_directory = self.data_directory_from_pefile(pe_data_directory)
            await resource.create_child_from_view(
                data_directory,
                data_range=Range.from_size(
                    pe_data_directory.get_file_offset(), pe_data_directory.sizeof()
                ),
            )

    # Sections
    for index, pe_section in enumerate(pe.sections):
        # Section header
        section_header = self.section_header_from_pefile(pe_section, index)
        await resource.create_child_from_view(
            section_header,
            data_range=Range.from_size(pe_section.get_file_offset(), pe_section.sizeof()),
        )
        # The section itself
        section = PeSection(
            section_index=index,
            name=section_header.name,
            virtual_address=section_header.m_virtual_address,
            size=section_header.m_virtual_size,
        )
        if pe_section.SizeOfRawData > 0:
            section_range = Range.from_size(
                pe_section.PointerToRawData, pe_section.SizeOfRawData
            )
        else:
            section_range = None

        section_r = await resource.create_child_from_view(
            section,
            data_range=section_range,
        )

        if section_header.has_flag(PeSectionFlag.IMAGE_SCN_CNT_CODE):
            section_r.add_tag(CodeRegion)