Unpack the string (presumably packed by pack(fmt, ...)) according to the
    given format. The actual unpacking is performed by ``struct.unpack``
    but the byte order will be set according to the given `endian`, `target`
    or byte order of the global target.

    Args:
        fmt(str): The format string.
        data(bytes): The data to unpack.
        endian(:class:`~pwnypack.target.Target.Endian`): Override the default
            byte order. If ``None``, it will look at the byte order of
            the ``target`` argument.
        target(:class:`~pwnypack.target.Target`): Override the default byte
            order. If ``None``, it will look at the byte order of
            the global :data:`~pwnypack.target.target`.

    Returns:
        list: The unpacked values according to the format.

def unpack(fmt, data, endian=None, target=None):
    """
    Unpack the string (presumably packed by pack(fmt, ...)) according to the
    given format. The actual unpacking is performed by ``struct.unpack``
    but the byte order will be set according to the given `endian`, `target`
    or byte order of the global target.

    Args:
        fmt(str): The format string.
        data(bytes): The data to unpack.
        endian(:class:`~pwnypack.target.Target.Endian`): Override the default
            byte order. If ``None``, it will look at the byte order of
            the ``target`` argument.
        target(:class:`~pwnypack.target.Target`): Override the default byte
            order. If ``None``, it will look at the byte order of
            the global :data:`~pwnypack.target.target`.

    Returns:
        list: The unpacked values according to the format.
    """

    endian = endian if endian is not None else target.endian if target is not None else pwnypack.target.target.endian
    if fmt and fmt[0] not in '@=<>!':
        if endian is pwnypack.target.Target.Endian.little:
            fmt = '<' + fmt
        elif endian is pwnypack.target.Target.Endian.big:
            fmt = '>' + fmt
        else:
            raise NotImplementedError('Unsupported endianness: %s' % endian)
    return struct.unpack(fmt, data)