def parse_volume(_regData, _shell_item_result, _info):
    (shell_item_size, shell_item_type, shell_item_data, pos) = _info
    volume_type_flag = cv.bytes_to_int(shell_item_type) & 0x0F

    if volume_type_flag == 0x0E:  # Root Shell item (doesn't have name flags.) -> Shell folder
        volume_item_data = shell_item_data[1:]
        (guid, name) = cv.guid_to_text(volume_item_data[0x00:0x10])
        extension_blocks = volume_item_data[0x10:]

        _shell_item_result["shell_type"] = "Root folder: GUID"
        _shell_item_result["mapped_guid"] = (guid, name)
        _shell_item_result["value"] = name

    elif volume_type_flag == 0x0F:
        offset = cv.find_end_of_stream(shell_item_data, 2, b"\x00\x00") - 2
        volume_letter = shell_item_data[:offset].decode()

        _shell_item_result["shell_type"] = "Drive"
        _shell_item_result["value"] = volume_letter
        extension_blocks = ""

    else:
        pass


# raise ShellItemFormatError("New volume type flag (Volume Shell Item)")

    extension_block_result = extension_block_parser.parse(
        extension_blocks, _regData)
    _shell_item_result["extension_block_result"] = extension_block_result

    return _shell_item_result
def parse_http_uri(_htu_data, _parsing_result):
    _parsing_result["shell_type"] = "HTTP URI"

    loop = 0
    while True:
        if len(_htu_data) < 20:
            return _parsing_result

        (HTU_DATA, pos) = cv.format_parser(_htu_data,
                                           data_format.HTU_SHELL_ITEM_FORMAT,
                                           0)
        htu_url_size = cv.bytes_to_int(HTU_DATA["htu_url_size"])

        if loop == 0:
            _parsing_result["value"] = urllib.parse.unquote(
                _htu_data[pos:pos + htu_url_size].decode("UTF-16LE"))

        elif loop == 1:
            _parsing_result["full_url"] = _htu_data[pos:pos +
                                                    htu_url_size].decode(
                                                        "UTF-16LE")

        else:
            if htu_url_size == 8 and HTU_DATA["htu_url"][-1] == 1:
                unknown_win64_time = cv.win64_timestamp(HTU_DATA["htu_url"])
                _parsing_result["unknown_data"] = ("Unknown Time",
                                                   unknown_win64_time)

            else:
                pass
                # raise ShellItemFormatError("New HTTP URI(HTU) format (Users Property View Shell Item)")
        _htu_data = _htu_data[pos + htu_url_size:]
        loop += 1
def parse_control_panel_category(_regData, _shell_item_result, _info):
    (shell_item_size, shell_item_type, shell_item_data, pos) = _info

    (ITEM_DATA, pos) = cv.format_parser(
        shell_item_data, data_format.CONTROL_PANEL_CATEGORY_SHELL_ITEM_FORMAT,
        pos)

    if ITEM_DATA["sig"] != b"\x84\x21\xDE\x39":
        pass
# raise ShellItemFormatError("New signature (Control Panel Category)")

    category_id = cv.bytes_to_int(ITEM_DATA["category_id"])
    if category_id in data_id.CONTROL_PANEL_CATEGORY_ID.keys():
        _shell_item_result["value"] = data_id.CONTROL_PANEL_CATEGORY_ID[
            category_id]

    else:
        pass


# raise ShellItemFormatError("New category id (Control Panel Category)")

    extension_blocks = ITEM_DATA["extension_block"]
    extension_block_result = extension_block_parser.parse(
        extension_blocks, _regData)
    _shell_item_result["extension_block_result"] = extension_block_result

    return _shell_item_result
def split_shell_item(_shell_item_blocks):
    shell_item_list = []
    shell_item_blocks = _shell_item_blocks

    while True:
        shell_item_size = cv.bytes_to_int(shell_item_blocks[0:2])
        shell_item = shell_item_blocks[:shell_item_size]
        shell_item_blocks = shell_item_blocks[shell_item_size:]
        shell_item_list.append(shell_item)

        if shell_item_blocks[:2] == b"\x00\x00" or shell_item_blocks == b"":
            return shell_item_list
def split_property_value(_spv_blocks):
    spv_list = []
    spv_blocks = _spv_blocks

    while True:
        spv_size = cv.bytes_to_int(spv_blocks[0:4])
        spv = spv_blocks[:spv_size]
        spv_blocks = spv_blocks[spv_size:]
        spv_list.append(spv)

        if spv_blocks[:4] == b"\x00\x00\x00\x00":
            return spv_list
def split_property_storage_block(_sps_blocks):
    sps_block_list = []
    sps_blocks = _sps_blocks

    while True:
        (SPS_DATA, pos) = cv.format_parser(sps_blocks, data_format.SPS_FORMAT,
                                           0)
        sps_size = cv.bytes_to_int(SPS_DATA["storage_size"])
        sps_block = sps_blocks[:sps_size]
        sps_blocks = sps_blocks[sps_size:]
        sps_block_list.append(sps_block)

        if sps_blocks[:4] == b"\x00\x00\x00\x00" or sps_blocks == b"":
            return sps_block_list
def parse_file_extension_block(_extension_block, _extension_version,
                               _extension_block_result):
    # TODO : WinXP ~ Win 8 추가 필요.
    (FILE_EXTENSION_BLOCK_COMMON,
     pos) = cv.format_parser(_extension_block,
                             data_format.FILE_EXTENSION_BLOCK_COMMON_FORMAT, 0)
    _extension_block_result["ctime"] = cv.msdos_timestamp(
        FILE_EXTENSION_BLOCK_COMMON["fat_ctime"])
    _extension_block_result["atime"] = cv.msdos_timestamp(
        FILE_EXTENSION_BLOCK_COMMON["fat_atime"])

    if _extension_version == 9:  # Win8.1 ~ Win10
        (FILE_EXTENSION_BLOCK_DATA,
         pos) = cv.format_parser(FILE_EXTENSION_BLOCK_COMMON["data"],
                                 data_format.FILE_EXTENSION_BLOCK_WIN81_FORMAT,
                                 0)
        mft_reference = FILE_EXTENSION_BLOCK_DATA["mft_reference"]
        name_size = cv.bytes_to_int(FILE_EXTENSION_BLOCK_DATA["name_size"])
        dummy_name = FILE_EXTENSION_BLOCK_DATA["long_name"]
        _extension_block_result["mft_entry_number"] = cv.bytes_to_int(
            mft_reference[0:4])
        _extension_block_result["mft_sequence_number"] = cv.bytes_to_int(
            mft_reference[4:6])

        if name_size == 0:
            long_name = dummy_name[:-4].decode("UTF-16LE")
            _extension_block_result["long_name"] = long_name

        elif name_size > 0:
            offset = cv.find_end_of_stream(dummy_name, 2, b"\x00\x00")
            long_name = dummy_name[:offset].decode("UTF-16LE")
            local_name = dummy_name[offset + 2:-4].decode("UTF-16LE")

            _extension_block_result["long_name"] = long_name
            _extension_block_result["localized_name"] = local_name

        return _extension_block_result
Exemple #8
0
def parse_mru_list_ex(_regData):
  loop = 0
  result = []

  while loop < len(_regData):
    mru_index_bytes = _regData[loop:loop+0x04]

    if mru_index_bytes == b"\xFF\xFF\xFF\xFF":
      break

    mru_index = cv.bytes_to_int(mru_index_bytes)
    result.append(mru_index)

    loop += 4
  return result
def split_extension_blocks(_extension_blocks):
    extension_block_list = []
    extension_blocks = _extension_blocks

    while True:
        (EXTENSION_BLOCK_SIG,
         pos) = cv.format_parser(extension_blocks,
                                 data_format.EXTENSION_BLOCK_SIGNATURE_FORMAT,
                                 0)
        block_size = cv.bytes_to_int(EXTENSION_BLOCK_SIG["extension_size"])
        extension_block = extension_blocks[:block_size]
        extension_blocks = extension_blocks[block_size:]
        extension_block_list.append(extension_block)

        if extension_blocks[:2] == b"\x00\x00" or extension_blocks == b"":
            return extension_block_list
def parse_file_entry(_regData, _shell_item_result, _info):
    (shell_item_size, shell_item_type, shell_item_data, pos) = _info

    (ITEM_DATA,
     pos) = cv.format_parser(shell_item_data,
                             data_format.FILE_ENTRY_SHELL_ITEM_FORMAT, pos)

    _shell_item_result["file_size"] = cv.bytes_to_int(ITEM_DATA["file_size"])
    _shell_item_result["fat_mtime"] = cv.msdos_timestamp(
        ITEM_DATA["fat_mtime"])

    offset = cv.find_end_of_stream(ITEM_DATA["short_name"], 2,
                                   b"\x04\x00\xef\xbe") - 4
    _shell_item_result["short_name"] = cv.solve_encoding(
        ITEM_DATA["short_name"][:offset]).replace("\x00", "")

    extension_blocks = ITEM_DATA["short_name"][offset:]

    if _shell_item_result["file_size"] == 0:
        _shell_item_result["shell_type"] = "Directory"
    elif _shell_item_result["file_size"] > 0:
        _shell_item_result["shell_type"] = "File"
    else:
        pass
        # raise ShellItemFormatError("New file size (File Shell Item)")

    extension_block_result = extension_block_parser.parse(
        extension_blocks, _regData)
    _shell_item_result["extension_block_result"] = extension_block_result

    extension_block_dict = extension_block_result[0]
    _shell_item_result["value"] = extension_block_dict["long_name"]
    _shell_item_result["ext_all_time"] = (extension_block_dict["mtime"],
                                          extension_block_dict["atime"],
                                          extension_block_dict["ctime"])
    return _shell_item_result
Exemple #11
0
def parse_mru_data(_regData):
  shell_item_result = {
    "last_written_time" : None,
    "shell_type"  : None,
    "file_size"   : 0,
    "fat_mtime"   : None,
    "short_name"  : None,
    "full_url" : None,
    "value"    : None,
    "mapped_guid"  : None,
    "unknown_data" : None,
    "extension_block_result" : [],
    "sps_result" : [],          # sps_result can have shell_item_result. so, it can have extension_block_result also.
    "ext_all_time": (None, None, None),
    # "registry_data"  : _regData
  }

  (MRU_DATA, shell_item_pos) = cv.format_parser(_regData, data_format.MRU_DATA_FORMAT, 0)

  shell_item_size = cv.bytes_to_int(MRU_DATA["shell_item_size"])
  shell_item_type = cv.return_type(MRU_DATA["shell_item_type"], data_format.SHELL_ITEM_TYPES)
  shell_item_data = MRU_DATA["shell_item_data"]

  shell_item_info = (shell_item_size, MRU_DATA["shell_item_type"], shell_item_data, shell_item_pos)
  if shell_item_type == "root_folder_shell_item":         # Shell folder (GUID)
    shell_item_result = shell_item_parser.parse_root_folder(_regData, shell_item_result, shell_item_info)

  elif shell_item_type == "volume_shell_item":      # My Computer in Explorer
    shell_item_result = shell_item_parser.parse_volume(_regData, shell_item_result, shell_item_info)

  elif shell_item_type == "file_entry_shell_item":
    shell_item_result = shell_item_parser.parse_file_entry(_regData, shell_item_result, shell_item_info)

  # elif shell_item_type == "network_location_shell_item":
  #   # Never seen.

  elif shell_item_type == "control_panel_shell_item":
    shell_item_result = shell_item_parser.parse_control_panel(_regData, shell_item_result, shell_item_info)

  elif shell_item_type == "control_panel_category_shell_item":
    shell_item_result = shell_item_parser.parse_control_panel_category(_regData, shell_item_result, shell_item_info)

  elif shell_item_type == "users_property_view_shell_item":
    shell_item_result = shell_item_parser.parse_user_property_view(_regData, shell_item_result, shell_item_info)

  elif shell_item_type == "favorite_shell_item":
    shell_item_result = shell_item_parser.parse_user_property_view(_regData, shell_item_result, shell_item_info)
    return None

  elif shell_item_type == "added_shell_item":
    return None
    pass

  else:
    return None
    pass

  if shell_item_result["value"] is None:
    shell_item_result["value"] = "Coming Soon"
    pass

  # df.PrintBeauty(shell_item_result, _sept_count=67)

  return shell_item_result
def parse_property_value(_sps_guid, _idx, _spv, _debug=None):
    spv_result = {
        "value_id": None,
        "value": None,
        "shell_item_result": [],
    }

    (SPV, pos) = cv.format_parser(_spv, data_format.SPV_FORMAT, 0)
    value_id = cv.bytes_to_int(SPV["value_id"])
    value_type = cv.bytes_to_int(SPV["value_type"])
    value_data = SPV["value_data"]
    spv_result["value_id"] = value_id

    # all spv are named property
    if _sps_guid == "D5CDD505-2E9C-101B-9397-08002B2CF9AE":
        spv_data = SPV["value_type"] + SPV["reserved2"] + value_data
        spv_result["value_id"] = spv_data[:value_id - 2].decode(
            "UTF-16LE")  # value id is name_size

        value_type = cv.bytes_to_int(spv_data[value_id:value_id + 4])
        value_data = spv_data[value_id + 4:]

    if value_type == 0x0001:  # VT_NULL
        spv_result["value"] = "NULL"

    elif value_type == 0x0002:  # VT_I2 (signed 16-bit)
        spv_result["value"] = cv.bytes_to_signed_int(16, value_data[:2])

    elif value_type in [0x0003, 0x0016]:  # VT_I4, VT_INT (signed 32-bit)
        spv_result["value"] = cv.bytes_to_signed_int(32, value_data)

    elif value_type == 0x000B:  # VT_BOOL
        if value_data[:2] == b"\xFF\xFF":
            spv_result["value"] = "TRUE"
        elif value_data[:2] == b"\x00\x00":
            spv_result["value"] = "FALSE"
        else:
            pass
# raise WindowsPropertyFormatError("New value_type (VT_BOOL)")

    elif value_type == 0x0010:  # VT_I1 (signed 8-bit)
        spv_result["value"] = cv.bytes_to_signed_int(8, value_data)

    elif value_type == 0x0011:  # VT_UI1 (unsigned 8-bit)
        spv_result["value"] = cv.bytes_to_int(value_data)

    elif value_type == 0x0012:  # VT_UI2 (unsigned 16-bit)
        spv_result["value"] = cv.bytes_to_int(value_data)

    elif value_type in [
            0x0013, 0x0017, 0x0015
    ]:  # VT_UI4, VT_UINT (unsigned 32-bit), VT_UI8 (unsigned 64-bit)
        spv_result["value"] = cv.bytes_to_int(value_data)

    elif value_type == 0x0014:  # VT_I8 (signed 64-bit)
        spv_result["value"] = cv.bytes_to_signed_int(64, value_data)

    elif value_type == 0x001F:  # VT_LPWSTR (Unicode string)
        str_size = (cv.bytes_to_int(value_data[0:4]) * 2) - 2
        string = value_data[4:4 + str_size].decode("UTF-16LE")
        spv_result["value"] = string

    elif value_type == 0x0040:  # VT_FILETIME (aka. Windows 64-bit timestamp)
        spv_result["value"] = cv.win64_timestamp(value_data)

    elif value_type == 0x0042:  # VT_STREAM
        spv_result["value"] = "VT_STREAM (0x0042)"
        prop_name_size = cv.bytes_to_int(value_data[0x00:0x04])
        prop_name = value_data[0x04:0x04 + prop_name_size].decode("UTF-16LE")
        value_data = value_data[0x04 + prop_name_size:][2:]  # \x00\x00

        if prop_name[:4] != "prop":
            pass
# raise WindowsPropertyFormatError("new value_type (VT_STREAM) : Not a prop~")

        idk_block_size = cv.bytes_to_int(value_data[0x00:0x02])
        idk_block = value_data[:idk_block_size]
        idk_block_guid = cv.guid_to_text(idk_block[0x04:0x04 + 0x10])

        dummy_shell_item_blocks = idk_block[0x04 + 0x10 + 0x24:]
        shell_item_blocks_size = cv.bytes_to_int(
            dummy_shell_item_blocks[0x00:0x02])
        shell_item_blocks = dummy_shell_item_blocks[
            0x02:shell_item_blocks_size]  # 0x02 is shell_item_blocks_size
        last_idk_block = dummy_shell_item_blocks[shell_item_blocks_size:]
        shell_item_result_list = parse_shell_item(shell_item_blocks)
        spv_result["shell_item_result"] = shell_item_result_list

        (LAST_IDK_BLOCK, pos) = cv.format_parser(last_idk_block,
                                                 data_format.LAST_IDK_BLOCK, 0)
        item_field = LAST_IDK_BLOCK["item_field"]
        offset = cv.find_end_of_stream(item_field, 2, b"\x00\x00")
        str_item = item_field[:offset].decode("UTF-16LE")

        if str_item != "item":
            pass
# raise WindowsPropertyFormatError("new value_type (VT_STREAM) : Not \"item\" in last_idk_block")
        last_idk_block_guid = cv.guid_to_text(LAST_IDK_BLOCK["guid"])

        dummy_search_result = LAST_IDK_BLOCK["search_result"]
        offset = cv.find_end_of_stream(dummy_search_result, 2, "\x00\x00")
        search_result = dummy_search_result[:offset].decode("UTF-16LE")

        # print("#"*100)
        # df.PrintBeauty(shell_item_result_list)
        # print(str_item)
        # print(search_result)

    elif value_type == 0x101F:  # VT_VECTOR(0x1000) | VT_LPWSTR
        vector_count = cv.bytes_to_int(value_data[0:4])
        str_size = (cv.bytes_to_int(value_data[4:8]) * 2) - 2
        string = value_data[8:8 + str_size].decode("UTF-16LE")
        spv_result["value"] = string

        if vector_count != 1:
            pass
# raise WindowsPropertyFormatError("New value_type (0x101F)")

    elif value_type == 0x1011:
        if value_data[5:8] == "\x00\x00\x00":
            vector_count = cv.bytes_to_int(value_data[0:4])
            spv_result["value"] = cv.bytes_to_int(value_data[4:8])

            if vector_count != 1:
                pass
# raise WindowsPropertyFormatError("New value_type (0x1011)")

        else:
            spv_result["value"] = "VT_VECTOR with data (0x011)"

            shell_item_result_list = parse_shell_item(value_data[4:])
            spv_result["shell_item_result"] = shell_item_result_list

    else:
        output_spv_id = "0x" + hex(value_type)[2:].zfill(4)
        pass


# raise WindowsPropertyFormatError("New value_id (Others : %s)" %output_spv_id)

# df.PrintBeauty(spv_result)

    return spv_result
def parse_extension_block(_extension_block):
    extension_block_result = {
        "extension_sig": None,
        "mapped_guid": None,  # [(guid, name), (guid, name), ...]
        "filesystem": None,
        "mft_entry_number": None,
        "mft_sequence_number": None,
        "ctime": None,
        "mtime": None,
        "atime": None,
        "long_name": None,
        "localized_name": None,
        "comment": None,
        "sps_result": []
    }

    (EXTENSION_BLOCK_SIGNATURE,
     pos) = cv.format_parser(_extension_block,
                             data_format.EXTENSION_BLOCK_SIGNATURE_FORMAT, 0)
    extension_size = cv.bytes_to_int(
        EXTENSION_BLOCK_SIGNATURE["extension_size"])
    extension_version = cv.bytes_to_int(
        EXTENSION_BLOCK_SIGNATURE["extension_version"])
    extension_sig = EXTENSION_BLOCK_SIGNATURE["extension_sig"]
    extension_block_result["extension_sig"] = "0x" + hex(
        cv.bytes_to_int(extension_sig))[2:].zfill(8)

    if extension_sig in [b"\x00\x00\xef\xbe", b"\x19\x00\xef\xbe"]:
        (EXTENSION_BLOCK_0000,
         pos) = cv.format_parser(_extension_block,
                                 data_format.EXTENSION_BLOCK_0000_FORMAT, 0)

        if extension_size == 14:  # Unknown Data
            pass

        elif extension_size == 42:
            mapped_guid1 = cv.guid_to_text(
                EXTENSION_BLOCK_0000["folder_type_id1"])
            mapped_guid2 = cv.guid_to_text(
                EXTENSION_BLOCK_0000["folder_type_id2"])

            extension_block_result["mapped_guid"] = [
                mapped_guid1, mapped_guid2
            ]

        else:
            pass
# raise ExtensionBlockFormatError("New BEEF0000, BEEF0019 block size.")

    elif extension_sig == b"\x03\x00\xef\xbe":
        (EXTENSION_BLOCK_0003,
         pos) = cv.format_parser(_extension_block,
                                 data_format.EXTENSION_BLOCK_0003_FORMAT, 0)

        extension_block_result["mapped_guid"] = cv.guid_to_text(
            EXTENSION_BLOCK_0003["guid"])

    elif extension_sig == b"\x04\x00\xef\xbe":
        extension_block_result = parse_file_extension_block(
            _extension_block, extension_version, extension_block_result)

    elif extension_sig == b"\x13\x00\xef\xbe":
        extension_block_result["comment"] = "Unknown extension block."

    elif extension_sig == b"\x26\x00\xef\xbe":
        (EXTENSION_BLOCK_0026,
         pos) = cv.format_parser(_extension_block,
                                 data_format.EXTENSION_BLOCK_0026_FORMAT, 0)

        extension_block_result["ctime"] = cv.win64_timestamp(
            EXTENSION_BLOCK_0026["win64_ctime"])
        extension_block_result["mtime"] = cv.win64_timestamp(
            EXTENSION_BLOCK_0026["win64_mtime"])
        extension_block_result["atime"] = cv.win64_timestamp(
            EXTENSION_BLOCK_0026["win64_atime"])

    elif extension_sig == b"\x27\x00\xef\xbe":
        (EXTENSION_BLOCK,
         pos) = cv.format_parser(_extension_block,
                                 data_format.EXTENSION_BLOCK_SIGNATURE_FORMAT,
                                 0)
        extension_data = EXTENSION_BLOCK["extension_data"]

        # TODO : SPS 파싱 끝나면, 여기에 반영하기.
        storage_property_parser.parse(extension_data)

    else:
        sig = repr(extension_sig)[1:].replace("'", "")
        pass


# raise ExtensionBlockFormatError("New extension block (%s)" %sig)

    return extension_block_result
def parse_user_property_view(_regData, _shell_item_result, _info):
    (shell_item_size, shell_item_type, shell_item_data, pos) = _info

    (ITEM_DATA, pos) = cv.format_parser(shell_item_data,
                                        data_format.USERS_SHELL_ITEM_FORMAT,
                                        pos)
    _shell_item_result["shell_type"] = "Users property view"

    sps_blocks = ""
    extension_blocks = ""
    upv_size = cv.bytes_to_int(ITEM_DATA["upv_size"])
    upv_data_size = cv.bytes_to_int(ITEM_DATA["upv_data_size"])
    upv_id_size = cv.bytes_to_int(ITEM_DATA["upv_id_size"])

    if ITEM_DATA["upv_sig"] in [
            b"\x81\x19\x14\x10", b"\x00\xEE\xEB\xBE", b"\xBB\xAF\x93\x3B"
    ]:
        upv_id_data = ITEM_DATA["upv_id_data"][:
                                               upv_id_size]  # unknown 32 bytes
        sps_blocks = ITEM_DATA["upv_id_data"][upv_id_size:]

    elif ITEM_DATA["upv_sig"] == b"\xEE\xBB\xFE\x23":
        upv_id_data = ITEM_DATA["upv_id_data"][:upv_id_size]
        (guid, name) = cv.guid_to_text(upv_id_data)

        _shell_item_result["mapped_guid"] = (guid, name)
        _shell_item_result["value"] = name

        if upv_data_size == 0:
            extension_blocks = ITEM_DATA["upv_id_data"][upv_id_size + 2:]

        elif upv_id_size > 0:
            sps_blocks = ITEM_DATA["upv_id_data"][upv_id_size:]

        else:
            pass


# raise ShellItemFormatError("New upv_id_size (Users property view Shell Item --> \\xEE\\xBB\\xFE\\x23)")

    elif ITEM_DATA["upv_sig"] == b"\x10\xB7\xA6\xF5":
        volume_shell_item_data = shell_item_data[pos - 2:upv_size]
        two_guids = shell_item_data[upv_size + 3:]

        offset = cv.find_end_of_stream(volume_shell_item_data, 2, b"\x00\x00")
        volume_letter = volume_shell_item_data[:offset].decode()

        guid1 = cv.guid_to_text(two_guids[:16])
        guid2 = cv.guid_to_text(two_guids[16:32])
        extension_blocks = two_guids[32:]

        _shell_item_result["value"] = volume_letter
        _shell_item_result["mapped_guid"] = [guid1, guid2]

    elif ITEM_DATA["upv_sig"] == b"\xD5\xDF\xA3\x23":
        # size(upv_size, upv_sig, upv_data_size, upv_id_size) == 10
        sps_blocks = ITEM_DATA["upv_id_data"][upv_id_size:upv_size - 10]
        root_item = ITEM_DATA["upv_id_data"][upv_size -
                                             8:]  # 8 == 10 - len(\x00\x00)

        guid1 = cv.guid_to_text(root_item[:16])
        guid2 = cv.guid_to_text(root_item[16:32])
        extension_blocks = root_item[32:]

        (guid, name) = guid2
        _shell_item_result["value"] = name
        _shell_item_result["mapped_guid"] = [guid1, guid2]

    elif ITEM_DATA["upv_sig"] == b"\xC9\xC0\x1E\x0C":  # My PC
        # df.PrintHexString(shell_item_data)

        upv_id_data = ITEM_DATA["upv_id_data"][:
                                               upv_id_size]  # unknown 32 bytes
        sps_blocks = ITEM_DATA["upv_id_data"][upv_id_size:]

        full_path = ""
        _shell_item_result_list = storage_property_parser.parse(
            sps_blocks, _debug=_regData)[0][0]
        for __shell_item_result in _shell_item_result_list[
                "shell_item_result"][1:]:
            folder_name = __shell_item_result["value"]
            full_path += "/" + folder_name

        _extension_block_result = __shell_item_result[
            "extension_block_result"][0]
        _shell_item_result["value"] = full_path[:-1]
        _shell_item_result["ext_all_time"] = (_extension_block_result["mtime"],
                                              _extension_block_result["atime"],
                                              _extension_block_result["ctime"])
        sps_blocks = ""
        # _shell_item_result["sps_result"] = sps_result

    # TODO: parser 추가 필요.
    elif ITEM_DATA["upv_sig"] in [b"\x10\xB7\xA6\xF5", b"LibL"]:
        pass

    elif ITEM_DATA["upv_sig"][:2] == b"\x01\xC0":
        htu_size = cv.bytes_to_int(shell_item_data[5:9])
        htu_data = shell_item_data[1:htu_size - 3]
        _shell_item_result = parse_http_uri(htu_data, _shell_item_result)

    else:
        pass
        # print(str(ITEM_DATA["upv_sig"]).upper().replace("\\X", "\\x"))
        # df.PrintHexString(shell_item_data)
        # print(ITEM_DATA["upv_sig"])
        # df.PrintHexString(shell_item_data)

    sps_result = storage_property_parser.parse(sps_blocks, _debug=_regData)
    _shell_item_result["sps_result"] = sps_result

    if sps_result:
        refine_parsed_sps(sps_result)

    extension_block_result = extension_block_parser.parse(
        extension_blocks, _regData)
    _shell_item_result["extension_block_result"] = extension_block_result

    return _shell_item_result