Esempio n. 1
0
def Volume(_regData, _shell_item_result, _info):
    (shell_item_size, shell_item_type, shell_item_data, pos) = _info
    volume_type_flag = cv.Bytes2Int(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.GUID2Text(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.FindEndOfStream(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:
        raise ShellItemFormatError("New volume type flag (Volume Shell Item)")

    extension_block_result = parse_extension_block.Parse(
        extension_blocks, _regData)
    _shell_item_result["extension_block_result"] = extension_block_result

    return _shell_item_result
Esempio n. 2
0
def RootFolder(_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.FormatParser(shell_item_data,
                                data_format.ROOT_SHELL_ITEM_0014_FORMAT, pos)

        if ITEM_DATA["sort_index"] == b"\x00":
            raise ShellItemFormatError("New sort index (Root folder: GUID)")

        (guid, name) = cv.GUID2Text(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.FormatParser(shell_item_data,
                                data_format.ROOT_SHELL_ITEM_0055_FORMAT, pos)

        if ITEM_DATA["sort_index"] != b"\x00":
            raise ShellItemFormatError("New sort index (Root folder: Drive)")

        if ITEM_DATA["upv_sig"] != b"\x10\xB7\xA6\xF5":
            raise ShellItemFormatError(
                "New UPV signature of Root folder: Drive --> %s" %
                repr(ITEM_DATA["upv_sig"]))

        _shell_item_result = UsersPropertyView(_regData, _shell_item_result,
                                               _info)
        _shell_item_result["shell_type"] = "Root folder: Drive"

    else:  # UPV format
        (ITEM_DATA, pos) = cv.FormatParser(shell_item_data,
                                           data_format.USERS_SHELL_ITEM_FORMAT,
                                           pos)

        if ITEM_DATA["upv_sig"] != b"\xD5\xDF\xA3\x23":
            raise ShellItemFormatError(
                "New UPV signature of Root folder: Variable --> %s" %
                repr(ITEM_DATA["upv_sig"]))

        _shell_item_result = UsersPropertyView(_regData, _shell_item_result,
                                               _info)
        _shell_item_result["shell_type"] += ": Search Folder"

    extension_block_result = parse_extension_block.Parse(
        extension_blocks, _regData)
    _shell_item_result["extension_block_result"] = extension_block_result

    return _shell_item_result
Esempio n. 3
0
def ControlPanel(_regData, _shell_item_result, _info):
    (shell_item_size, shell_item_type, shell_item_data, pos) = _info

    (ITEM_DATA,
     pos) = cv.FormatParser(shell_item_data,
                            data_format.CONTROL_PANEL_SHELL_ITEM_FORMAT, pos)
    (guid, name) = cv.GUID2Text(ITEM_DATA["guid"])

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

    extension_blocks = ITEM_DATA["extension_block"]
    extension_block_result = parse_extension_block.Parse(
        extension_blocks, _regData)
    _shell_item_result["extension_block_result"] = extension_block_result

    return _shell_item_result
Esempio n. 4
0
def UsersPropertyView(_regData, _shell_item_result, _info):
    (shell_item_size, shell_item_type, shell_item_data, pos) = _info

    (ITEM_DATA, pos) = cv.FormatParser(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.Bytes2Int(ITEM_DATA["upv_size"])
    upv_data_size = cv.Bytes2Int(ITEM_DATA["upv_data_size"])
    upv_id_size = cv.Bytes2Int(ITEM_DATA["upv_id_size"])

    if ITEM_DATA["upv_sig"] in [b"\x81\x19\x14\x10", b"\x00\xEE\xEB\xBE"]:
        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.GUID2Text(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:
            raise ShellItemFormatError(
                "New upv_id_size (Users property view Shell Item --> \\xEE\\xBB\\xFE\\x23)"
            )

    elif ITEM_DATA["upv_sig"] == b"\xBB\xAF\x93\x3B":
        raise ShellItemFormatError(
            "New upv_sig (Users property view Shell Item --> \\xBB\\xAF\\x93\\x3B)"
        )

    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.FindEndOfStream(volume_shell_item_data, 2, b"\x00\x00")
        volume_letter = volume_shell_item_data[:offset].decode()

        guid1 = cv.GUID2Text(two_guids[:16])
        guid2 = cv.GUID2Text(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.GUID2Text(root_item[:16])
        guid2 = cv.GUID2Text(root_item[16:32])
        extension_blocks = root_item[32:]

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

    else:
        htu_size = cv.Bytes2Int(shell_item_data[5:9])
        htu_data = shell_item_data[1:htu_size - 3]

        if shell_item_data[1:5] == b"\x00\xB0\x01\xC0":
            _shell_item_result = HttpURIParser(htu_data, _shell_item_result)

        else:
            raise ShellItemFormatError(
                "New HTTP URI(UTU) sig (Users Property View Shell Item) --> %s"
                % repr(ITEM_DATA["upv_sig"]))

    sps_result = parse_sps_block.Parse(sps_blocks, _debug=_regData)
    _shell_item_result["sps_result"] = sps_result

    if sps_result:
        RefineSPSResult(sps_result)

    extension_block_result = parse_extension_block.Parse(
        extension_blocks, _regData)
    _shell_item_result["extension_block_result"] = extension_block_result

    return _shell_item_result
Esempio n. 5
0
def PropertyValueParser(_sps_guid, _idx, _spv, _debug=None):
    spv_result = {
        "value_id": None,
        "value": None,
        "shell_item_result": [],
    }

    (SPV, pos) = cv.FormatParser(_spv, data_format.SPV_FORMAT, 0)
    value_id = cv.Bytes2Int(SPV["value_id"])
    value_type = cv.Bytes2Int(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.Bytes2Int(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.Bytes2SignedInt(16, value_data[:2])

    elif value_type in [0x0003, 0x0016]:  # VT_I4, VT_INT (signed 32-bit)
        spv_result["value"] = cv.Bytes2SignedInt(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:
            raise WindowsPropertyFormatError("New value_type (VT_BOOL)")

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

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

    elif value_type == 0x0012:  # VT_UI2 (unsigned 16-bit)
        spv_result["value"] = cv.Bytes2Int(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.Bytes2Int(value_data)

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

    elif value_type == 0x001F:  # VT_LPWSTR (Unicode string)
        str_size = (cv.Bytes2Int(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.TSWin64bit(value_data)

    elif value_type == 0x0042:  # VT_STREAM
        spv_result["value"] = "VT_STREAM (0x0042)"
        prop_name_size = cv.Bytes2Int(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":
            raise WindowsPropertyFormatError(
                "new value_type (VT_STREAM) : Not a prop~")

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

        dummy_shell_item_blocks = idk_block[0x04 + 0x10 + 0x24:]
        shell_item_blocks_size = cv.Bytes2Int(
            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 = ShellItemParser(shell_item_blocks)
        spv_result["shell_item_result"] = shell_item_result_list

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

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

        dummy_search_result = LAST_IDK_BLOCK["search_result"]
        offset = cv.FindEndOfStream(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.Bytes2Int(value_data[0:4])
        str_size = (cv.Bytes2Int(value_data[4:8]) * 2) - 2
        string = value_data[8:8 + str_size].decode("UTF-16LE")
        spv_result["value"] = string

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

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

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

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

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

    else:
        output_spv_id = "0x" + hex(value_type)[2:].zfill(4)
        raise WindowsPropertyFormatError("New value_id (Others : %s)" %
                                         output_spv_id)

    # df.PrintBeauty(spv_result)

    return spv_result
Esempio n. 6
0
def ExtensionBlockParser(_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.FormatParser(_extension_block, data_format.EXTENSION_BLOCK_SIGNATURE_FORMAT, 0)
  extension_size    = cv.Bytes2Int(EXTENSION_BLOCK_SIGNATURE["extension_size"])
  extension_version = cv.Bytes2Int(EXTENSION_BLOCK_SIGNATURE["extension_version"])
  extension_sig     = EXTENSION_BLOCK_SIGNATURE["extension_sig"]
  extension_block_result["extension_sig"] = "0x" + hex(cv.Bytes2Int(extension_sig))[2:].zfill(8)

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

    if extension_size == 14: # Unknown Data
      pass

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

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

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

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

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

  elif extension_sig == b"\x04\x00\xef\xbe":
    extension_block_result = FileExtensionBlockParser(_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.FormatParser(_extension_block, data_format.EXTENSION_BLOCK_0026_FORMAT, 0)

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

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

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

  else:
    sig = repr(extension_sig)[1:].replace("'", "")
    raise ExtensionBlockFormatError("New extension block (%s)" %sig)

  return extension_block_result