<commit_before>import struct, re, base64, random, pwn
_AssemblerBlock = None

# conversion functions
def pint(x):
    '''Packs an integer into a string as long as needed, little endian'''
    out = ''
    while True:
        b = x & 0xff
        out += p8(b)
        x = x >> 8
        if x == 0 or x == -1:
            break
    return out

def pintb(x):
    '''Packs an integer into a string as long as needed, endian'''
    out = []
    while True:
        b = x & 0xff
        out.insert(0, p8(b))
        x = x >> 8
        if x == 0 or x == -1:
            break
    return ''.join(out)

def uint(x):
    '''Unpacks a string of arbitrary length into an integer, little endian'''
    out = 0
    for b in x[::-1]:
        out <<= 8
        out += u8(b)
    return out

def uintb(x):
    '''Unpacks a string of arbitrary length into an integer, big endian'''
    out = 0
    for b in x:
        out <<= 8
        out += u8(b)
    return out

def p8(x):
    """Packs an integer into a 1-byte string"""
    return struct.pack('<B', x & 0xff)

def p8b(x):
    """Packs an integer into a 1-byte string"""
    return struct.pack('>B', x & 0xff)

def p16(x):
    """Packs an integer into a 2-byte string (little endian)"""
    return struct.pack('<H', x & 0xffff)

def p16b(x):
    """Packs an integer into a 2-byte string (big endian)"""
    return struct.pack('>H', x & 0xffff)

def p32(x):
    """Packs an integer into a 4-byte string (little endian)"""
    return struct.pack('<I', x & 0xffffffff)

def p32b(x):
    """Packs an integer into a 4-byte string (big endian)"""
    return struct.pack('>I', x & 0xffffffff)

def p64(x):
    """Packs an integer into a 8-byte string (little endian)"""
    return struct.pack('<Q', x & 0xffffffffffffffff)

def p64b(x):
    """Packs an integer into a 8-byte string (big endian)"""
    return struct.pack('>Q', x & 0xffffffffffffffff)

def u8(x):
    """Unpacks a 1-byte string into an integer"""
    return struct.unpack('<B', x)[0]

def u8b(x):
    """Unpacks a 1-byte string into an integer"""
    return struct.unpack('>B', x)[0]

def u16(x):
    """Unpacks a 2-byte string into an integer (little endian)"""
    return struct.unpack('<H', x)[0]

def u16b(x):
    """Unpacks a 2-byte string into an integer (big endian)"""
    return struct.unpack('>H', x)[0]

def u32(x):
    """Unpacks a 4-byte string into an integer (little endian)"""
    return struct.unpack('<I', x)[0]

def u32b(x):
    """Unpacks a 4-byte string into an integer (big endian)"""
    return struct.unpack('>I', x)[0]

def u64(x):
    """Unpacks a 8-byte string into an integer (little endian)"""
    return struct.unpack('<Q', x)[0]

def u64b(x):
    """Unpacks a 8-byte string into an integer (big endian)"""
    return struct.unpack('>Q', x)[0]

@pwn.need_context
def p(x, arch = None):
    """Packs an integer into a string based on the current context"""
    if arch == 'amd64':
        return p64(x)
    elif arch == 'i386':
        return p32(x)
    pwn.die('Architecture not set in the context while calling p(%d)' % x)

@pwn.need_context
def u(x, arch = None):
    """Unpacks a string into an integer based on the current context"""
    if arch == 'amd64':
        return u64(x)
    elif arch == 'i386':
        return u32(x)
    pwn.die('Architecture not set in the context while calling u(%s)' % repr(x))

def pack_size(f):
    if f == p8:   return "8"
    if f == p16:  return "16"
    if f == p32:  return "32"
    if f == p64:  return "64"

    if f == p8b:  return "8b"
    if f == p16b: return "16b"
    if f == p32b: return "32b"
    if f == p64b: return "64b"

    return ""

packs_big_endian      = {64: p64b, 32: p32b, 16: p16b, 8: p8b, 'any': pintb}
packs_little_endian   = {64: p64,  32: p32,  16: p16,  8: p8,  'any': pint}
unpacks_big_endian    = {64: u64b, 32: u32b, 16: u16b, 8: u8b, 'any': uintb}
unpacks_little_endian = {64: u64,  32: u32,  16: u16,  8: u8,  'any': uint}

@pwn.need_context
def flat(*args, **kwargs):
    """Flattens the arguments into a string.
Takes a single named argument 'func', which defaults to "p32" if no context is set and to "p" otherwise.
  - Strings are returned
  - Integers are converted using the 'func' argument.
  - Shellcode is assembled
  - Enumerables (such as lists) traversed recursivly and the concatenated.

Example:
  - flat(5, "hello", [[6, "bar"], "baz"]) == '\\x05\\x00\\x00\\x00hello\\x06\\x00\\x00\\x00barbaz'
"""

    global _AssemblerBlock

    if _AssemblerBlock == None:
        from pwn.internal.shellcode_helper import AssemblerBlock as _AssemblerBlock

    if 'arch' in kwargs and kwargs['arch'] != None:
        default_func = p
    else:
        default_func = p32

    func = kwargs.get('func', default_func)

    obj = args[0] if len(args) == 1 else args

    if isinstance(obj, str):
        return obj
    elif isinstance(obj, int):
        return func(obj)
    elif hasattr(obj, '__flat__'):
        return obj.__flat__()
    else:
        return "".join(flat(o, func=func) for o in obj)

def dehex(s):
    """Hex-decodes a string"""
    return s.decode('hex')

def unhex(s):
    """Hex-decodes a string"""
    return s.decode('hex')

def enhex(s):
    """Hex-encodes a string"""
    return s.encode('hex')

def urlencode(s):
    """urlencodes a string"""
    return ''.join(['%%%02x' % ord(c) for c in s])

def urldecode(s, ignore_invalid = False):
    """urldecodes a string"""
    res = ''
    n = 0
    while n < len(s):
        if s[n] != '%':
            res += s[n]<commit_msg>extended enhex to handle ints as well as strings<commit_after>import struct, re, base64, random, pwn
_AssemblerBlock = None

# conversion functions
def pint(x):
    '''Packs an integer into a string as long as needed, little endian'''
    out = ''
    while True:
        b = x & 0xff
        out += p8(b)
        x = x >> 8
        if x == 0 or x == -1:
            break
    return out

def pintb(x):
    '''Packs an integer into a string as long as needed, endian'''
    out = []
    while True:
        b = x & 0xff
        out.insert(0, p8(b))
        x = x >> 8
        if x == 0 or x == -1:
            break
    return ''.join(out)

def uint(x):
    '''Unpacks a string of arbitrary length into an integer, little endian'''
    out = 0
    for b in x[::-1]:
        out <<= 8
        out += u8(b)
    return out

def uintb(x):
    '''Unpacks a string of arbitrary length into an integer, big endian'''
    out = 0
    for b in x:
        out <<= 8
        out += u8(b)
    return out

def p8(x):
    """Packs an integer into a 1-byte string"""
    return struct.pack('<B', x & 0xff)

def p8b(x):
    """Packs an integer into a 1-byte string"""
    return struct.pack('>B', x & 0xff)

def p16(x):
    """Packs an integer into a 2-byte string (little endian)"""
    return struct.pack('<H', x & 0xffff)

def p16b(x):
    """Packs an integer into a 2-byte string (big endian)"""
    return struct.pack('>H', x & 0xffff)

def p32(x):
    """Packs an integer into a 4-byte string (little endian)"""
    return struct.pack('<I', x & 0xffffffff)

def p32b(x):
    """Packs an integer into a 4-byte string (big endian)"""
    return struct.pack('>I', x & 0xffffffff)

def p64(x):
    """Packs an integer into a 8-byte string (little endian)"""
    return struct.pack('<Q', x & 0xffffffffffffffff)

def p64b(x):
    """Packs an integer into a 8-byte string (big endian)"""
    return struct.pack('>Q', x & 0xffffffffffffffff)

def u8(x):
    """Unpacks a 1-byte string into an integer"""
    return struct.unpack('<B', x)[0]

def u8b(x):
    """Unpacks a 1-byte string into an integer"""
    return struct.unpack('>B', x)[0]

def u16(x):
    """Unpacks a 2-byte string into an integer (little endian)"""
    return struct.unpack('<H', x)[0]

def u16b(x):
    """Unpacks a 2-byte string into an integer (big endian)"""
    return struct.unpack('>H', x)[0]

def u32(x):
    """Unpacks a 4-byte string into an integer (little endian)"""
    return struct.unpack('<I', x)[0]

def u32b(x):
    """Unpacks a 4-byte string into an integer (big endian)"""
    return struct.unpack('>I', x)[0]

def u64(x):
    """Unpacks a 8-byte string into an integer (little endian)"""
    return struct.unpack('<Q', x)[0]

def u64b(x):
    """Unpacks a 8-byte string into an integer (big endian)"""
    return struct.unpack('>Q', x)[0]

@pwn.need_context
def p(x, arch = None):
    """Packs an integer into a string based on the current context"""
    if arch == 'amd64':
        return p64(x)
    elif arch == 'i386':
        return p32(x)
    pwn.die('Architecture not set in the context while calling p(%d)' % x)

@pwn.need_context
def u(x, arch = None):
    """Unpacks a string into an integer based on the current context"""
    if arch == 'amd64':
        return u64(x)
    elif arch == 'i386':
        return u32(x)
    pwn.die('Architecture not set in the context while calling u(%s)' % repr(x))

def pack_size(f):
    if f == p8:   return "8"
    if f == p16:  return "16"
    if f == p32:  return "32"
    if f == p64:  return "64"

    if f == p8b:  return "8b"
    if f == p16b: return "16b"
    if f == p32b: return "32b"
    if f == p64b: return "64b"

    return ""

packs_big_endian      = {64: p64b, 32: p32b, 16: p16b, 8: p8b, 'any': pintb}
packs_little_endian   = {64: p64,  32: p32,  16: p16,  8: p8,  'any': pint}
unpacks_big_endian    = {64: u64b, 32: u32b, 16: u16b, 8: u8b, 'any': uintb}
unpacks_little_endian = {64: u64,  32: u32,  16: u16,  8: u8,  'any': uint}

@pwn.need_context
def flat(*args, **kwargs):
    """Flattens the arguments into a string.
Takes a single named argument 'func', which defaults to "p32" if no context is set and to "p" otherwise.
  - Strings are returned
  - Integers are converted using the 'func' argument.
  - Shellcode is assembled
  - Enumerables (such as lists) traversed recursivly and the concatenated.

Example:
  - flat(5, "hello", [[6, "bar"], "baz"]) == '\\x05\\x00\\x00\\x00hello\\x06\\x00\\x00\\x00barbaz'
"""

    global _AssemblerBlock

    if _AssemblerBlock == None:
        from pwn.internal.shellcode_helper import AssemblerBlock as _AssemblerBlock

    if 'arch' in kwargs and kwargs['arch'] != None:
        default_func = p
    else:
        default_func = p32

    func = kwargs.get('func', default_func)

    obj = args[0] if len(args) == 1 else args

    if isinstance(obj, str):
        return obj
    elif isinstance(obj, int):
        return func(obj)
    elif hasattr(obj, '__flat__'):
        return obj.__flat__()
    else:
        return "".join(flat(o, func=func) for o in obj)

def unhex(s):
    """Hex-decodes a string"""
    return s.decode('hex')

def enhex(x):
    """Hex-encodes a string or integer"""
    if isinstance(x, int):
        x = pint(x)
    return x.encode('hex')

def urlencode(s):
    """urlencodes a string"""
    return ''.join(['%%%02x' % ord(c) for c in s])

def urldecode(s, ignore_invalid = False):
    """urldecodes a string"""
    res = ''
    n = 0
    while n < len(s):
        if s[n] != '%':
            res += s[n]
{'fraction_non_alphanumeric': 0.15264401235689623, 'fraction_numerical': 0.03797928402689442, 'mean_word_length': 2.699831932773109, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 8, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4844085', 'n_tokens_mistral': 4255, 'n_tokens_neox': 3969, 'n_words': 1355}