def parse_root_folder(_regData, _shell_item_result, _info): _shell_item_result["shell_type"] = "Root folder" (shell_item_size, shell_item_type, shell_item_data, pos) = _info extension_blocks = "" if shell_item_size in [0x14, 0x3A]: _shell_item_result["shell_type"] += ": GUID" (ITEM_DATA, pos) = cv.format_parser(shell_item_data, data_format.ROOT_SHELL_ITEM_0014_FORMAT, pos) if ITEM_DATA["sort_index"] == b"\x00": pass # raise ShellItemFormatError("New sort index (Root folder: GUID)") (guid, name) = cv.guid_to_text(ITEM_DATA["guid"]) _shell_item_result["mapped_guid"] = (guid, name) _shell_item_result["value"] = name extension_blocks = ITEM_DATA["extension_block"] elif shell_item_size == 0x55: (ITEM_DATA, pos) = cv.format_parser(shell_item_data, data_format.ROOT_SHELL_ITEM_0055_FORMAT, pos) if ITEM_DATA["sort_index"] != b"\x00": pass # raise ShellItemFormatError("New sort index (Root folder: Drive)") if ITEM_DATA["upv_sig"] != b"\x10\xB7\xA6\xF5": pass # raise ShellItemFormatError("New UPV signature of Root folder: Drive --> %s" %repr(ITEM_DATA["upv_sig"])) _shell_item_result = parse_user_property_view(_regData, _shell_item_result, _info) _shell_item_result["shell_type"] = "Root folder: Drive" else: # UPV format (ITEM_DATA, pos) = cv.format_parser(shell_item_data, data_format.USERS_SHELL_ITEM_FORMAT, pos) if ITEM_DATA["upv_sig"] != b"\xD5\xDF\xA3\x23": pass # raise ShellItemFormatError("New UPV signature of Root folder: Variable --> %s" %repr(ITEM_DATA["upv_sig"])) _shell_item_result = parse_user_property_view(_regData, _shell_item_result, _info) _shell_item_result["shell_type"] += ": Search Folder" 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_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
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_control_panel(_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_SHELL_ITEM_FORMAT, pos) (guid, name) = cv.guid_to_text(ITEM_DATA["guid"]) _shell_item_result["mapped_guid"] = (guid, name) _shell_item_result["value"] = name 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 parse_property_storage(_sps_block): (SPS_DATA, pos) = cv.format_parser(_sps_block, data_format.SPS_FORMAT, 0) if SPS_DATA["storage_version"] != b"1SPS": pass # raise WindowsPropertyFormatError("New Property Storage Version (Not 1SPS)") sps_guid = cv.bytes_to_guid(SPS_DATA["storage_guid"]) spv_list = split_property_value(SPS_DATA["value_list"]) spv_result_list = [] for idx, spv in enumerate(spv_list): # print("# Property Value %2d #" % idx) # df.PrintHexString(spv) spv_result = parse_property_value(sps_guid, idx, spv) spv_result_list.append(spv_result) return spv_result_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
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