Esempio n. 1
0
 def __determine_file_extension(parsed_pe_file: pefile.PE) -> str:
     if parsed_pe_file.is_dll():
         return 'dll'
     if parsed_pe_file.is_driver():
         return 'sys'
     if parsed_pe_file.is_exe():
         return 'exe'
     else:
         return 'bin'
Esempio n. 2
0
    def unpack(self, data):
        cursor = 0
        mv = memoryview(data)

        while True:
            offset = data.find(B'MZ', cursor)
            if offset < cursor: break
            cursor = offset + 2
            ntoffset = mv[offset + 0x3C:offset + 0x3E]
            if len(ntoffset) < 2:
                return
            ntoffset, = unpack('H', ntoffset)
            if mv[offset + ntoffset:offset + ntoffset + 2] != B'PE':
                self.log_debug(
                    F'invalid NT header signature for candidate at 0x{offset:08X}'
                )
                continue
            try:
                pe = PE(data=data[offset:], fast_load=True)
            except PEFormatError as err:
                self.log_debug(
                    F'parsing of PE header at 0x{offset:08X} failed:', err)
                continue

            pesize = get_pe_size(pe, memdump=self.args.memdump)
            pedata = mv[offset:offset + pesize]
            info = {}
            if self.args.fileinfo:
                try:
                    info = pemeta().parse_version(pe) or {}
                except Exception as error:
                    self.log_warn(
                        F'Unable to obtain file information: {error!s}')
            try:
                path = info['OriginalFilename']
            except KeyError:
                extension = 'exe' if pe.is_exe() else 'dll' if pe.is_dll(
                ) else 'sys'
                path = F'carve-0x{offset:08X}.{extension}'

            if offset > 0 or self.args.keep_root:
                yield UnpackResult(path, pedata, offset=offset)
                self.log_info(
                    F'extracted PE file of size 0x{pesize:08X} from 0x{offset:08X}'
                )
            else:
                self.log_info(
                    F'ignored root file of size 0x{pesize:08X} from 0x{offset:08X}'
                )
                continue

            if not offset or self.args.recursive:
                cursor += pe.OPTIONAL_HEADER.SizeOfHeaders
            else:
                cursor += pesize