예제 #1
0
def test_html():
    """Tests the html construct."""
    # Test doctests
    results = doctest.testmod(construct.construct_html)
    assert not results.failed

    # Test with an example
    EMBED_SPEC = construct.Struct(
        'a' / construct.IP4Address,
        'b' / construct.IP4Address,
        'c' / construct.IP4Address,
        'd' / construct.IP4Address
    )

    address_struct = construct.Struct(
        'first' / construct.Struct('a' / construct.Byte, 'b' / construct.Byte),
        'second' / construct.Struct('inner2' / construct.Bytes(2))
        # 'internal' / IP4Address
    )

    PACKET = construct.Struct(
        construct.Padding(0x9),
        'Hardcoded Value 1' / construct.HexString(construct.Int32ul),
        'Hardcoded Value 2' / construct.HexString(construct.Int32ul),
        'Hardcoded Value 3' / construct.HexString(construct.Int32ul),
        construct.Padding(0x17),
        'Compromised Host IP' / construct.IP4Address,  # Use IP adapter
        # 'Unknown IP Addresses' / construct.Switch(
        #     this['Hardcoded Value 1'],
        #     {
        #         '0x1f4' : EMBED_SPEC
        #     },
        # ),
        'Unknown IP Addresses' / address_struct[4],
        # 'Unknown IP Addresses' / IP4Address[4],
        construct.Padding(8),
        'Unknown Indicator' / construct.String(0xF),
        construct.Padding(2),
        'Number of CPUs' / construct.Int32ul,
        'CPU Mhz' / construct.Int32ul,
        'Total Memory (MB)' / construct.Int32ul,
        'Compromised System Kernel' / construct.CString(),
        'Possible Trojan Version' / construct.CString()
    )

    data = (b'\x01\x00\x00\x00}\x00\x00\x00\x00\xf4\x01\x00\x002\x00\x00\x00\xe8'
            b'\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
            b'\x01\x00\x00\x00\x00\x01\x00\x00\x00\xc0\xa8\x01\r\xc0\xa8\x01\r\xc0'
            b'\xa8\x01\r\xc0\xa8\x01\r\xc0\xa8\x01\r\xff\xff\x01\x00\x00\x00\x00\x00'
            b'-== Love AV ==-:\x00\x01\x00\x00\x00d\n\x00\x00\xc4\x07\x00\x00'
            b'Linux 3.13.0-93-generic\x001:G2.40\x00')

    html_data = construct.html_hex(PACKET, data, depth=1)

    with open(os.path.join(os.path.dirname(__file__), 'construct_html.html'), 'r') as fo:
        expected_html_data = fo.read()

    assert html_data == expected_html_data
예제 #2
0
    def build(self, write_section_data=True):
        """
        Generate PE file.

        :param write_section_data: Whether to include section data (otherwise only the headers are written)

        :returns bytes: PE file data.

        :raises ValueError: If set attributes contains contradicting data.
        """
        pe = copy.deepcopy(self)

        # Pad dos stub to match e_lfanew. (Warn if dos stub is too large.)
        dos_stub_size = pe.DosHeader.e_lfanew - construct.IMAGE_DOS_HEADER.sizeof(
        )
        if len(pe.DosStub) > dos_stub_size:
            raise ValueError(
                'Provided DOS stub is too large for provided DosHeader.e_lfanew: {}'
                .format(pe.DosHeader.e_lfanew))
        pe.DosStub = pe.DosStub.ljust(dos_stub_size, b'\x00')

        # Fix file header.
        file_header = pe.NTHeaders.FileHeader
        if file_header.NumberOfSections and file_header.NumberOfSections != len(
                pe.SectionTable):
            logger.debug(
                'NTHeaders.FileHeader.NumberOfSections does not equal the number of sections provided. Auto-adjusting.'
            )
        file_header.NumberOfSections = len(pe.SectionTable)
        if isinstance(file_header.Characteristics, list):
            file_header.Characteristics = {
                flag: True
                for flag in file_header.Characteristics
            }

        # Fix sections.
        pe.SectionTable = list(map(self._fix_section, pe.SectionTable))

        # Fix optional header.
        optional_header = pe.NTHeaders.OptionalHeader
        number_of_rva_and_sizes = len(optional_header.DataDirectory)
        optional_header.NumberOfRvaAndSizes = number_of_rva_and_sizes
        file_header.SizeOfOptionalHeader = construct.IMAGE_OPTIONAL_HEADER.sizeof(
            NumberOfRvaAndSizes=number_of_rva_and_sizes)
        if isinstance(optional_header.DllCharacteristics, list):
            optional_header.DllCharacteristics = {
                flag: True
                for flag in optional_header.DllCharacteristics
            }

        # SizeOfHeaders is the sum of the headers rounded by FileAlignment.
        headers_size = construct.PEFILE_HEADER.sizeof(**pe)
        file_alignment = optional_header.FileAlignment - 1
        headers_size = (headers_size +
                        file_alignment) & 0xffffffff - file_alignment
        optional_header.SizeOfHeaders = headers_size

        pe_data = construct.PEFILE_HEADER.build(pe)

        # Add section data.
        if write_section_data:
            stream = io.BytesIO(pe_data)
            spec = construct.Pointer(this.PointerToRawData,
                                     construct.Bytes(this.SizeOfRawData))
            for section in pe.SectionTable:
                spec.build_stream(section.data, stream, **section)
            pe_data = stream.getvalue()

        return pe_data