# `pwnlib.context` — Setting runtime variables

Many settings in `pwntools` are controlled via the global variable `context`, such as the selected target operating system, architecture, and bit-width.

In general, exploits will start with something like:

    from pwn import *
    context.arch = 'amd64'

Which sets up everything in the exploit for exploiting a 64-bit Intel binary.

The recommended method is to use `context.binary` to automagically set all of the appropriate values.

    from pwn import *
    context.binary = './challenge-binary'

## Module Members

Implements context management so that nested/scoped contexts and threaded contexts work properly and as expected.

class pwnlib.context.ContextType(**kwargs)

  Class for specifying information about the target machine. Intended for use as a pseudo-singleton through the global variable `context`, available via `from pwn import *` as `context`.

  The context is usually specified at the top of the Python file for clarity.

      #!/usr/bin/env python
      context.update(arch='i386', os='linux')

  Currently supported properties and their defaults are listed below. The defaults are inherited from `pwnlib.context.ContextType.defaults`.

  Additionally, the context is thread-aware when using `pwnlib.context.Thread` instead of `threading.Thread` (all internal `pwntools` threads use the former).

  The context is also scope-aware by using the `with` keyword.

  Examples

      >>> context.clear()
      >>> context.update(os='linux')
      >>> context.os == 'linux'
      True
      >>> context.arch = 'arm'
      >>> vars(context) == {'arch': 'arm', 'bits': 32, 'endian': 'little', 'os': 'linux', 'newline': b'\n'}
      True
      >>> context.endian
      'little'
      >>> context.bits
      32
      >>> def nop():
      ...   print(enhex(pwnlib.asm.asm('nop')))
      >>> nop()
      00f020e3
      >>> with context.local(arch = 'i386'):
      ...   nop()
      90
      >>> from pwnlib.context import Thread as PwnThread
      >>> from threading      import Thread as NormalThread
      >>> with context.local(arch = 'mips'):
      ...     pwnthread = PwnThread(target=nop)
      ...     thread    = NormalThread(target=nop)
      >>> # Normal thread uses the default value for arch, 'i386'
      >>> _=(thread.start(), thread.join())
      90
      >>> # Pwnthread uses the correct context from creation-time
      >>> _=(pwnthread.start(), pwnthread.join())
      00000000
      >>> nop()
      00f020e3

  Initialize the ContextType structure.

  All keyword arguments are passed to `update()`.

  class Thread(*args, **kwargs)

    Instantiates a context-aware thread, which inherit its context when it is instantiated. The class can be accessed both on the context module as pwnlib.context.Thread and on the context singleton object inside the context module as pwnlib.context.context.Thread.

    Threads created by using the native :class`threading`.Thread` will have a clean (default) context.

    Regardless of the mechanism used to create any thread, the context is de-coupled from the parent thread, so changes do not cascade to child or parent.

    Saves a copy of the context when instantiated (at `__init__`) and updates the new thread’s context before passing control to the user code via `run` or `target=`.

    Examples

        >>> context.clear()
        >>> context.update(arch='arm')
        >>> def p():
        ...     print(context.arch)
        ...     context.arch = 'mips'
        ...     print(context.arch)
        >>> # Note that a normal Thread starts with a clean context
        >>> # (i386 is the default architecture)
        >>> t = threading.Thread(target=p)
        >>> _=(t.start(), t.join())
        i386
        mips
        >>> # Note that the main Thread's context is unchanged
        >>> print(context.arch)
        arm
        >>> # Note that a context-aware Thread receives a copy of the context
        >>> t = pwnlib.context.Thread(target=p)
        >>> _=(t.start(), t.join())
        arm
        mips
        >>> # Again, the main thread is unchanged
        >>> print(context.arch)
        arm

    Implementation Details:

    > This class implemented by hooking the private function `threading.Thread._Thread_bootstrap()`, which is called before passing control to `threading.Thread.run()`.

    > This could be done by overriding `run` itself, but we would have to ensure that all uses of the class would only ever use the keyword `target=` for `__init__`, or that all subclasses invoke `super(Subclass.self).set_up_context()` or similar.

    This constructor should always be called with keyword arguments. Arguments are:

    group should be None; reserved for future extension when a ThreadGroup class is implemented.

    target is the callable object to be invoked by the run() method. Defaults to None, meaning nothing is called.

    name is the thread name. By default, a unique name is constructed of the form “Thread-N” where N is a small decimal number.

    args is a list or tuple of arguments for the target invocation. Defaults to ().

    kwargs is a dictionary of keyword arguments for the target invocation. Defaults to {}.

    If a subclass overrides the constructor, it must make sure to invoke the base class constructor (Thread.__init__()) before doing anything else to the thread.

    __bootstrap()
      Implementation Details:

        This only works because the class is named `Thread`. If its name is changed, we have to implement this hook differently.

    __init__(*args, **kwargs)

      This constructor should always be called with keyword arguments. Arguments are:

      group should be None; reserved for future extension when a ThreadGroup class is implemented.

      target is the callable object to be invoked by the run() method. Defaults to None, meaning nothing is called.

      name is the thread name. By default, a unique name is constructed of the form “Thread-N” where N is a small decimal number.

      args is a list or tuple of arguments for the target invocation. Defaults to ().

      kwargs is a dictionary of keyword arguments for the target invocation. Defaults to {}.

      If a subclass overrides the constructor, it must make sure to invoke the base class constructor (Thread.__init__()) before doing anything else to the thread.

    _bootstrap()
      Implementation Details:

        This only works because the class is named `Thread`. If its name is changed, we have to implement this hook differently.

  __call__(**kwargs)

    Alias for `pwnlib.context.ContextType.update()`

  __init__(**kwargs)

    Initialize the ContextType structure.

    All keyword arguments are passed to `update()`.

  __repr__()

    Return repr(self).

  clear(*a, **kw)

    Clears the contents of the context. All values are set to their defaults.

    Parameters:

      - a – Arguments passed to `update`

      - kw – Arguments passed to `update`

    Examples

        >>> # Default value
        >>> context.clear()
        >>> context.arch == 'i386'
        True
        >>> context.arch = 'arm'
        >>> context.arch == 'i386'
        False
        >>> context.clear()
        >>> context.arch == 'i386'
        True

  copy() → dict

    Returns a copy of the current context as a dictionary.

    Examples

        >>> context.clear()
        >>> context.os   = 'linux'
        >>> vars(context) == {'os': 'linux', 'newline': b'\n'}
        True

  local(**kwargs) → context manager

    Create a context manager for use with the `with` statement.

    For more information, see the example below or PEP 343.

    Parameters:

      kwargs – Variables to be assigned in the new environment.

    Returns:

      ContextType manager for managing the old and new environment.

    Examples

        >>> context.clear()
        >>> context.timeout = 1
        >>> context.timeout == 1
        True
        >>> print(context.timeout)
        1.0
        >>> with context.local(timeout = 2):
        ...     print(context.timeout)
        ...     context.timeout = 3
        ...     print(context.timeout)
        2.0
        3.0
        >>> print(context.timeout)
        1.0

  quietfunc(function)

    Similar to `quiet`, but wraps a whole function.

    Example

    Let’s set up two functions, which are the same but one is wrapped with `quietfunc`.

        >>> def loud(): log.info("Loud")
        >>> @context.quietfunc
        ... def quiet(): log.info("Quiet")

    If we set the logging level to ‘info’, the loud function prints its contents.

        >>> with context.local(log_level='info'): loud()
        [*] Loud

    However, the quiet function does not, since `quietfunc` silences all output unless the log level is DEBUG.

        >>> with context.local(log_level='info'): quiet()

    Now let’s try again with debugging enabled.

        >>> with context.local(log_level='debug'): quiet()
        [*] Quiet

  reset_local()

    Deprecated. Use `clear()`.

  update(*args, **kwargs)

    Convenience function, which is shorthand for setting multiple variables at once.

    It is a simple shorthand such that:

        context.update(os = 'linux', arch = 'arm', ...)

    is equivalent to:

        context.os   = 'linux'
        context.arch = 'arm'
        ...

    The following syntax is also valid:

        context.update({'os': 'linux', 'arch': 'arm'})

    Parameters:

      kwargs – Variables to be assigned in the environment.

    Examples

        >>> context.clear()
        >>> context.update(arch = 'i386', os = 'linux')
        >>> context.arch, context.os
        ('i386', 'linux')

  property adb

    Returns an argument array for connecting to adb.

    Unless `$ADB_PATH` is set, uses the default `adb` binary in `$PATH`.

  property adb_host

    Sets the target host which is used for ADB.

    This is useful for Android exploitation.

    The default value is inherited from ANDROID_ADB_SERVER_HOST, or set to the default ‘localhost’.

  property adb_port

    Sets the target port which is used for ADB.

    This is useful for Android exploitation.

    The default value is inherited from ANDROID_ADB_SERVER_PORT, or set to the default 5037.

  property arch

    Target binary architecture.

    Allowed values are listed in `pwnlib.context.ContextType.architectures`.

    Side Effects:

    > If an architecture is specified which also implies additional attributes (e.g. ‘amd64’ implies 64-bit words, ‘powerpc’ implies big-endian), these attributes will be set on the context if a user has not already set a value.

    > The following properties may be modified.

    > - `bits`

    > - `endian`

    Raises:

      AttributeError – An invalid architecture was specified

    Examples

        >>> context.clear()
        >>> context.arch == 'i386' # Default architecture
        True

        >>> context.arch = 'mips'
        >>> context.arch == 'mips'
        True

        >>> context.arch = 'doge'
        Traceback (most recent call last):
         ...
        AttributeError: arch must be one of ['aarch64', ..., 'thumb']

        >>> context.arch = 'ppc'
        >>> context.arch == 'powerpc' # Aliased architecture
        True

        >>> context.clear()
        >>> context.bits == 32 # Default value
        True
        >>> context.arch = 'amd64'
        >>> context.bits == 64 # New value
        True

    Note that expressly setting `bits` means that we use that value instead of the default

        >>> context.clear()
        >>> context.bits = 32
        >>> context.arch = 'amd64'
        >>> context.bits == 32
        True

    Setting the architecture can override the defaults for both `endian` and `bits`

        >>> context.clear()
        >>> context.arch = 'powerpc64'
        >>> vars(context) == {'arch': 'powerpc64', 'bits': 64, 'endian': 'big'}
        True

  architectures = {'aarch64': {'bits': 64, 'endian': 'little'}, 'alpha': {'bits': 64, 'endian': 'little'}, 'amd64': {'bits': 64, 'endian': 'little'}, 'arm': {'bits': 32, 'endian': 'little'}, 'avr': {'bits': 8, 'endian': 'little'}, 'cris': {'bits': 32, 'endian': 'little'}, 'i386': {'bits': 32, 'endian': 'little'}, 'ia64': {'bits': 64, 'endian': 'big'}, 'm68k': {'bits': 32, 'endian': 'big'}, 'mips': {'bits': 32, 'endian': 'little'}, 'mips64': {'bits': 64, 'endian': 'little'}, 'msp430': {'bits': 16, 'endian': 'little'}, 'none': {}, 'powerpc': {'bits': 32, 'endian': 'big'}, 'powerpc64': {'bits': 64, 'endian': 'big'}, 'riscv32': {'bits': 32, 'endian': 'little'}, 'riscv64': {'bits': 64, 'endian': 'little'}, 's390': {'bits': 32, 'endian': 'big'}, 'sparc': {'bits': 32, 'endian': 'big'}, 'sparc64': {'bits': 64, 'endian': 'big'}, 'thumb': {'bits': 32, 'endian': 'little'}, 'vax': {'bits': 32, 'endian': 'little'}}

    Values are defaults which are set when `pwnlib.context.ContextType.arch` is set

  property aslr

    ASLR settings for new processes.

    If `False`, attempt to disable ASLR in all processes which are created via `personality` (`setarch -R`) and `setrlimit` (`ulimit -s unlimited`).

    The `setarch` changes are lost if a `setuid` binary is executed.

  property binary

    Infer target architecture, bit-with, and endianness from a binary file. Data type is a `pwnlib.elf.ELF` object.

    Examples

        >>> context.clear()
        >>> context.arch, context.bits
        ('i386', 32)
        >>> context.binary = '/bin/bash'
        >>> context.arch, context.bits
        ('amd64', 64)
        >>> context.binary
        ELF('/bin/bash')

  property bits

    Target machine word size, in bits (i.e. the size of general purpose registers).

    The default value is `32`, but changes according to `arch`.

    Examples

        >>> context.clear()
        >>> context.bits == 32
        True
        >>> context.bits = 64
        >>> context.bits == 64
        True
        >>> context.bits = -1
        Traceback (most recent call last):
        ...
        AttributeError: bits must be > 0 (-1)

  property buffer_size

    Internal buffer size to use for `pwnlib.tubes.tube.tube` objects.

    This is not the maximum size of the buffer, but this is the amount of data which is passed to each raw `read` syscall (or equivalent).

  property bytes

    Target machine word size, in bytes (i.e. the size of general purpose registers).

    This is a convenience wrapper around `bits // 8`.

    Examples

        >>> context.bytes = 1
        >>> context.bits == 8
        True

        >>> context.bytes = 0
        Traceback (most recent call last):
        ...
        AttributeError: bits must be > 0 (0)

  property cache_dir

    Directory used for caching data.

    Note

    May be either a path string, or `None`.

    Example

        >>> cache_dir = context.cache_dir
        >>> cache_dir is not None
        True
        >>> os.chmod(cache_dir, 0o000)
        >>> del context._tls['cache_dir']
        >>> context.cache_dir is None
        True
        >>> os.chmod(cache_dir, 0o755)
        >>> cache_dir == context.cache_dir
        True

  property cache_dir_base

    Base directory to use for caching content.

    Changing this to a different value will clear the cache_dir path stored in TLS since a new path will need to be generated to respect the new cache_dir_base value.

  property cyclic_alphabet

    Cyclic alphabet.

    Default value is string.ascii_lowercase.

  property cyclic_size

    Cyclic pattern size.

    Default value is 4.

  defaults = {'adb_host': 'localhost', 'adb_port': 5037, 'arch': 'i386', 'aslr': True, 'binary': None, 'bits': 32, 'buffer_size': 4096, 'cache_dir_base': '/sbuild-nonexistent/.cache', 'cyclic_alphabet': b'abcdefghijklmnopqrstuvwxyz', 'cyclic_size': 4, 'delete_corefiles': False, 'device': None, 'encoding': 'auto', 'endian': 'little', 'gdbinit': '', 'kernel': None, 'local_libcdb': '/var/lib/libc-database', 'log_console': <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>, 'log_file': <pwnlib.context._devnull object>, 'log_level': 20, 'newline': b'\n', 'noptrace': False, 'os': 'linux', 'proxy': None, 'randomize': False, 'rename_corefiles': True, 'signed': False, 'ssh_session': None, 'terminal': (), 'throw_eof_on_incomplete_line': None, 'timeout': pwnlib.timeout.maximum}

    Default values for `pwnlib.context.ContextType`

  property delete_corefiles

    Whether pwntools automatically deletes corefiles after exiting. This only affects corefiles accessed via `process.corefile`.

    Default value is `False`.

  property device

    Sets the device being operated on.

  property endian

    Endianness of the target machine.

    The default value is `'little'`, but changes according to `arch`.

    Raises:

      AttributeError – An invalid endianness was provided

    Examples

        >>> context.clear()
        >>> context.endian == 'little'
        True

        >>> context.endian = 'big'
        >>> context.endian
        'big'

        >>> context.endian = 'be'
        >>> context.endian == 'big'
        True

        >>> context.endian = 'foobar'
        Traceback (most recent call last):
         ...
        AttributeError: endian must be one of ['be', 'big', 'eb', 'el', 'le', 'little']

  property endianness

    Legacy alias for `endian`.

    Examples

        >>> context.endian == context.endianness
        True

  endiannesses = {'be': 'big', 'big': 'big', 'eb': 'big', 'el': 'little', 'le': 'little', 'little': 'little'}

    Valid values for `endian`

  property gdbinit

    Path to the gdbinit that is used when running GDB locally.

    This is useful if you want pwntools-launched GDB to include some additional modules, like PEDA but you do not want to have GDB include them by default.

    The setting will only apply when GDB is launched locally since remote hosts may not have the necessary requirements for the gdbinit.

    If set to an empty string, GDB will use the default ~/.gdbinit.

    Default value is `""`.

  property kernel

    Target machine’s kernel architecture.

    Usually, this is the same as `arch`, except when running a 32-bit binary on a 64-bit kernel (e.g. i386-on-amd64).

    Even then, this doesn’t matter much – only when the the segment registers need to be known

  property local_libcdb

    Sets path to local libc-database, get more information for libc-database: https://github.com/niklasb/libc-database

    Works in `pwnlib.libcdb` when searching by local database provider.

    The default value is `/var/lib/libc-database`.

    Sets context.local_libcdb to empty string or None will turn off local libc-database integration.

    Examples

        >>> context.local_libcdb = pwnlib.data.elf.path
        >>> context.local_libcdb = 'foobar'
        Traceback (most recent call last):
        ...
        AttributeError: 'foobar' does not exist, please download libc-database first

  property log_console

    Sets the default logging console target.

    Examples

        >>> context.log_level = 'warn'
        >>> log.warn("Hello")
        [!] Hello
        >>> context.log_console=open('/dev/null', 'w')
        >>> log.warn("Hello")
        >>> context.clear()

  property log_file

    Sets the target file for all logging output.

    Works in a similar fashion to `log_level`.

    Examples

        >>> foo_txt = tempfile.mktemp()
        >>> bar_txt = tempfile.mktemp()
        >>> context.log_file = foo_txt
        >>> log.debug('Hello!')
        >>> with context.local(log_level='ERROR'):
        ...     log.info('Hello again!')
        >>> with context.local(log_file=bar_txt):
        ...     log.debug('Hello from bar!')
        >>> log.info('Hello from foo!')
        >>> open(foo_txt).readlines()[-3]
        '...:DEBUG:...:Hello!\n'
        >>> open(foo_txt).readlines()[-2]
        '...:INFO:...:Hello again!\n'
        >>> open(foo_txt).readlines()[-1]
        '...:INFO:...:Hello from foo!\n'
        >>> open(bar_txt).readlines()[-1]
        '...:DEBUG:...:Hello from bar!\n'

  property log_level

    Sets the verbosity of `pwntools` logging mechanism.

    More specifically it controls the filtering of messages that happens inside the handler for logging to the screen. So if you want e.g. log all messages to a file, then this attribute makes no difference to you.

    Valid values are specified by the standard Python `logging` module.

    Default value is set to `INFO`.

    Examples

        >>> context.log_level = 'error'
        >>> context.log_level == logging.ERROR
        True
        >>> context.log_level = 10
        >>> context.log_level = 'foobar'
        Traceback (most recent call last):
        ...
        AttributeError: log_level must be an integer or one of ['CRITICAL', 'DEBUG', 'ERROR', 'INFO', 'NOTSET', 'WARN', 'WARNING']

  property newline

    Line ending used for Tubes by default.

    This configures the newline emitted by e.g. `sendline` or that is used as a delimiter for e.g. `recvline`.

  property noptrace

    Disable all actions which rely on ptrace.

    This is useful for switching between local exploitation with a debugger, and remote exploitation (without a debugger).

    This option can be set with the `NOPTRACE` command-line argument.

  property os

    Operating system of the target machine.

    The default value is `linux`.

    Allowed values are listed in `pwnlib.context.ContextType.oses`.

    Side Effects:

    > If an os is specified some attributes will be set on the context if a user has not already set a value.

    > The following property may be modified:

    > - `newline`

    Raises:

      AttributeError – An invalid os was specified

    Examples

        >>> context.clear()
        >>> context.os == 'linux' # Default os
        True

        >>> context.os = 'freebsd'
        >>> context.os == 'freebsd'
        True

        >>> context.os = 'foobar'
        Traceback (most recent call last):
        ...
        AttributeError: os must be one of ['android', 'baremetal', 'cgc', 'freebsd', 'linux', 'windows']

        >>> context.clear()
        >>> context.newline == b'\n' # Default value
        True
        >>> context.os = 'windows'
        >>> context.newline == b'\r\n' # New value
        True

    Note that expressly setting `newline` means that we use that value instead of the default

        >>> context.clear()
        >>> context.newline = b'\n'
        >>> context.os = 'windows'
        >>> context.newline == b'\n'
        True

    Setting the os can override the default for `newline`

        >>> context.clear()
        >>> context.os = 'windows'
        >>> vars(context) == {'os': 'windows', 'newline': b'\r\n'}
        True

  oses = {'android': {'newline': b'\n'}, 'baremetal': {'newline': b'\n'}, 'cgc': {'newline': b'\n'}, 'darwin': {'newline': b'\n'}, 'freebsd': {'newline': b'\n'}, 'linux': {'newline': b'\n'}, 'windows': {'newline': b'\r\n'}}

    Keys are valid values for `pwnlib.context.ContextType.os()`

  property proxy

    Default proxy for all socket connections.

    Accepts either a string (hostname or IP address) for a SOCKS5 proxy on the default port, or a `tuple` passed to `socks.set_default_proxy`, e.g. `(socks.SOCKS4, 'localhost', 1234)`.

        >>> context.proxy = 'localhost'
        >>> r=remote('google.com', 80)
        Traceback (most recent call last):
        ...
        ProxyConnectionError: Error connecting to SOCKS5 proxy localhost:1080: [Errno 111] Connection refused

        >>> context.proxy = None
        >>> r=remote('google.com', 80, level='error')

  property quiet

    Disables all non-error logging within the enclosed scope, unless the debugging level is set to ‘debug’ or lower.

    Example

    Let’s assume the normal situation, where log_level is INFO.

        >>> context.clear(log_level='info')

    Note that only the log levels below ERROR do not print anything.

        >>> with context.quiet:
        ...     log.debug("DEBUG")
        ...     log.info("INFO")
        ...     log.warn("WARN")

    Next let’s try with the debugging level set to ‘debug’ before we enter the context handler:

        >>> with context.local(log_level='debug'):
        ...     with context.quiet:
        ...         log.debug("DEBUG")
        ...         log.info("INFO")
        ...         log.warn("WARN")
        [DEBUG] DEBUG
        [*] INFO
        [!] WARN

  property randomize

    Global flag that lots of things should be randomized.

  property rename_corefiles

    Whether pwntools automatically renames corefiles.

    This is useful for two things:

    - Prevent corefiles from being overwritten, if `kernel.core_pattern` is something simple like `"core"`.

    - Ensure corefiles are generated, if `kernel.core_pattern` uses `apport`, which refuses to overwrite any existing files.

    This only affects corefiles accessed via `process.corefile`.

    Default value is `True`.

  property sign

    Alias for `signed`

  property signed

    Signed-ness for packing operation when it’s not explicitly set.

    Can be set to any non-string truthy value, or the specific string values `'signed'` or `'unsigned'` which are converted into `True` and `False` correspondingly.

    Examples

        >>> context.signed
        False
        >>> context.signed = 1
        >>> context.signed
        True
        >>> context.signed = 'signed'
        >>> context.signed
        True
        >>> context.signed = 'unsigned'
        >>> context.signed
        False
        >>> context.signed = 'foobar'
        Traceback (most recent call last):
        ...
        AttributeError: signed must be one of ['no', 'signed', 'unsigned', 'yes'] or a non-string truthy value

  property signedness

    Alias for `signed`

  signednesses = {'no': False, 'signed': True, 'unsigned': False, 'yes': True}

    Valid string values for `signed`

  property silent

    Disable all non-error logging within the enclosed scope.

  property terminal

    Default terminal used by `pwnlib.util.misc.run_in_new_terminal()`. Can be a string or an iterable of strings. In the latter case the first entry is the terminal and the rest are default arguments.

  property throw_eof_on_incomplete_line

    Whether to raise an `EOFError` if an EOF is received before a newline in `tube.recvline`.

    Controls if an `EOFError` is treated as newline in `tube.recvline` and similar functions and whether a warning should be logged about it.

    Possible values are:

    - `True`: Raise an `EOFError` if an EOF is received before a newline.

    - `False`: Return the data received so far if an EOF is received before a newline without logging a warning.

    - `None`: Return the data received so far if an EOF is received before a newline and log a warning.

    Default value is `None`.

  property timeout

    Default amount of time to wait for a blocking operation before it times out, specified in seconds.

    The default value is to have an infinite timeout.

    See `pwnlib.timeout.Timeout` for additional information on valid values.

  property verbose

    Enable all logging within the enclosed scope.

    This is the opposite of `quiet` and functionally equivalent to:

        with context.local(log_level='debug'):
            ...

    Example

    Note that the function does not emit any information by default

        >>> context.clear()
        >>> def func(): log.debug("Hello")
        >>> func()

    But if we put it inside a `verbose` context manager, the information is printed.

        >>> with context.verbose: func()
        [DEBUG] Hello

  property word_size

    Alias for `bits`

class pwnlib.context.Thread(*args, **kwargs)

  Instantiates a context-aware thread, which inherit its context when it is instantiated. The class can be accessed both on the context module as pwnlib.context.Thread and on the context singleton object inside the context module as pwnlib.context.context.Thread.

  Threads created by using the native :class`threading`.Thread` will have a clean (default) context.

  Regardless of the mechanism used to create any thread, the context is de-coupled from the parent thread, so changes do not cascade to child or parent.

  Saves a copy of the context when instantiated (at `__init__`) and updates the new thread’s context before passing control to the user code via `run` or `target=`.

  Examples

      >>> context.clear()
      >>> context.update(arch='arm')
      >>> def p():
      ...     print(context.arch)
      ...     context.arch = 'mips'
      ...     print(context.arch)
      >>> # Note that a normal Thread starts with a clean context
      >>> # (i386 is the default architecture)
      >>> t = threading.Thread(target=p)
      >>> _=(t.start(), t.join())
      i386
      mips
      >>> # Note that the main Thread's context is unchanged
      >>> print(context.arch)
      arm
      >>> # Note that a context-aware Thread receives a copy of the context
      >>> t = pwnlib.context.Thread(target=p)
      >>> _=(t.start(), t.join())
      arm
      mips
      >>> # Again, the main thread is unchanged
      >>> print(context.arch)
      arm

  Implementation Details:

  > This class implemented by hooking the private function `threading.Thread._Thread_bootstrap()`, which is called before passing control to `threading.Thread.run()`.

  > This could be done by overriding `run` itself, but we would have to ensure that all uses of the class would only ever use the keyword `target=` for `__init__`, or that all subclasses invoke `super(Subclass.self).set_up_context()` or similar.

  This constructor should always be called with keyword arguments. Arguments are:

  group should be None; reserved for future extension when a ThreadGroup class is implemented.

  target is the callable object to be invoked by the run() method. Defaults to None, meaning nothing is called.

  name is the thread name. By default, a unique name is constructed of the form “Thread-N” where N is a small decimal number.

  args is a list or tuple of arguments for the target invocation. Defaults to ().

  kwargs is a dictionary of keyword arguments for the target invocation. Defaults to {}.

  If a subclass overrides the constructor, it must make sure to invoke the base class constructor (Thread.__init__()) before doing anything else to the thread.

  __bootstrap()
    Implementation Details:

      This only works because the class is named `Thread`. If its name is changed, we have to implement this hook differently.

  __init__(*args, **kwargs)

    This constructor should always be called with keyword arguments. Arguments are:

    group should be None; reserved for future extension when a ThreadGroup class is implemented.

    target is the callable object to be invoked by the run() method. Defaults to None, meaning nothing is called.

    name is the thread name. By default, a unique name is constructed of the form “Thread-N” where N is a small decimal number.

    args is a list or tuple of arguments for the target invocation. Defaults to ().

    kwargs is a dictionary of keyword arguments for the target invocation. Defaults to {}.

    If a subclass overrides the constructor, it must make sure to invoke the base class constructor (Thread.__init__()) before doing anything else to the thread.

  _bootstrap()
    Implementation Details:

      This only works because the class is named `Thread`. If its name is changed, we have to implement this hook differently.

pwnlib.context.context = ContextType()

  Global `ContextType` object, used to store commonly-used pwntools settings.

  In most cases, the context is used to infer default variables values. For example, `asm()` can take an `arch` parameter as a keyword argument.

  If it is not supplied, the `arch` specified by `context` is used instead.

  Consider it a shorthand to passing `os=` and `arch=` to every single function call.