예제 #1
0
// read utf16 and return unvalidated utf8
string get_possible_utf16(const sbuf_t sbuf, size_t count, sbuf_t::byte_order_t byte_order) {

    // check for sequence
    if (chars_match(sbuf, count) || char_pairs_match(sbuf, count)) {
        // this is an uninteresting sequence, so return ""
        return "";
    }

    // get wstring accounting for byte order
    wstring wstr;
    sbuf.getUTF16(0, count, byte_order, wstr);

    // convert wstring to string
    string utf8_string = all_utf16to8(wstr);

#ifdef DEBUG
    cout << "exif_entry.get_possible_utf16 utf8_string (escaped): '" << validateOrEscapeUTF8(utf8_string, true, true) << "'\n";
#endif
    return utf8_string;
}
    prefetch_record_t(const sbuf_t &sbuf):prefetch_version(), header_size(0), execution_filename(),
        execution_counter(0), execution_time(0), volume_path_name(),
        volume_serial_number(0), volume_creation_time(0),
        files(), directories() {

        // read fields in order until done or range exception
        try {

            // get prefetch version identifier
            uint8_t prefetch_version_byte = sbuf.get8u(0);

            // set values based on prefetch version
            size_t execution_time_offset=0;
            size_t execution_counter_offset=0;
            if (prefetch_version_byte == 0x11) {
                prefetch_version = "Windows XP";
                execution_time_offset = 0x78;
                execution_counter_offset = 0x90;
            } else if (prefetch_version_byte == 0x17) {
                prefetch_version = "Windows Vista or Windows 7";
                execution_time_offset = 0x80;
                execution_counter_offset = 0x98;
            } else {
                // program error: don't create prefetch_record if this byte is invalid.
                // This was an assert(0), but let's just return
                return ;
            }

            // size in bytes of the whole prefetch file
            uint32_t prefetch_file_length = sbuf.get32u(0x0c);

            // get execution file filename
            wstring utf16_execution_filename;
            sbuf.getUTF16(0x10, utf16_execution_filename);
            execution_filename = safe_utf16to8(utf16_execution_filename);

            // get the offset to Section A
            uint32_t section_a_offset = sbuf.get32u(0x54);
            header_size = section_a_offset; // header is everything before section A

            // validate the offset since we know what it should be
            if ((prefetch_version_byte == 0x11 && header_size != 0x98)		// XP and 2003
                    || (prefetch_version_byte == 0x17 && header_size != 0xf0)) {	// Vista and 7
                // invalid so quit trying
                return;
            }

            execution_time = sbuf.get64u(execution_time_offset);
            execution_counter = sbuf.get32u(execution_counter_offset);

            // get the list of files from Section C
            uint32_t section_c_offset = sbuf.get32u(0x64);
            uint32_t section_c_length = sbuf.get32u(0x68);
            sbuf_stream filename_stream(sbuf + section_c_offset);
            while (filename_stream.tell() < section_c_length) {
                wstring utf16_filename;
                filename_stream.getUTF16(utf16_filename);
                string filename = safe_utf16to8(utf16_filename);
                if (!valid_full_path_name(filename)) return;
                files.push_back(filename);
            }

            // Process Section D
            uint32_t section_d_offset = sbuf.get32u(0x6c);

            uint32_t volume_name_offset = sbuf.get32u(section_d_offset + 0x00);
            wstring utf16_volume_name;
            sbuf.getUTF16(section_d_offset+volume_name_offset, utf16_volume_name);
            volume_path_name = safe_utf16to8(utf16_volume_name);

            volume_creation_time = sbuf.get64i(section_d_offset+0x08);
            volume_serial_number = sbuf.get32u(section_d_offset+0x10);

            uint32_t section_d_2_offset = sbuf.get32u(section_d_offset + 0x1c);
            size_t   directory_offset = section_d_offset + section_d_2_offset;
            uint32_t num_directory_entries = sbuf.get32u(section_d_offset + 0x20);

            // get each of the directory entries from Section D subsection 2
            if (directory_offset > prefetch_file_length) {
                // the offset is out of range so don't get the list of directories
            } else {
                // calculate a rough maximum number of bytes for directory entries
                size_t upper_max = prefetch_file_length - directory_offset;

                sbuf_stream directory_stream = sbuf_stream(sbuf + directory_offset);

                for (uint32_t i=0; i<num_directory_entries; i++) {
                    // break if obviously out of range
                    if (directory_stream.tell() > upper_max) {
                        return;		// rest of data not good
                    }

                    // for directories, the first int16 is the directory name length.
                    // We read to \U0000 instead so we throw away the directory name length.
                    directory_stream.get16u();

                    // read the directory name
                    wstring utf16_directory_name;
                    directory_stream.getUTF16(utf16_directory_name);
                    string directory_name = safe_utf16to8(utf16_directory_name);
                    if (!valid_full_path_name(directory_name)) return;
                    directories.push_back(directory_name);
                }
            }
        } catch (sbuf_t::range_exception_t &e) {
            // no action, just return what was gleaned before range exception
        }
    }