• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Gallopsled / pwntools / 5501444272

pending completion
5501444272

Pull #2221

github-actions

web-flow
Merge b6d25b636 into 9c83fa109
Pull Request #2221: Add shellcraft.sleep template wrapping SYS_nanosleep

3702 of 6659 branches covered (55.59%)

11579 of 16977 relevant lines covered (68.2%)

0.68 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

67.72
/pwnlib/args.py
1
"""
2
Pwntools exposes several magic command-line arguments and environment
3
variables when operating in `from pwn import *` mode.
4

5
The arguments extracted from the command-line and removed from ``sys.argv``.
6

7
Arguments can be set by appending them to the command-line, or setting
8
them in the environment prefixed by ``PWNLIB_``.
9

10
The easiest example is to enable more verbose debugging.  Just set ``DEBUG``.
11

12
.. code-block:: bash
13

14
    $ PWNLIB_DEBUG=1 python exploit.py
15
    $ python exploit.py DEBUG
16

17
These arguments are automatically extracted, regardless of their name, and
18
exposed via :mod:`pwnlib.args.args`, which is exposed as the global variable
19
:data:`args`.  Arguments which ``pwntools`` reserves internally are not exposed
20
this way.
21

22
.. code-block:: bash
23

24
    $ python -c 'from pwn import *; print(args)' A=1 B=Hello HOST=1.2.3.4 DEBUG
25
    defaultdict(<type 'str'>, {'A': '1', 'HOST': '1.2.3.4', 'B': 'Hello'})
26

27
This is very useful for conditional code, for example determining whether to
28
run an exploit locally or to connect to a remote server.  Arguments which are
29
not specified evaluate to an empty string.
30

31
.. code-block:: python
32

33
    if args['REMOTE']:
34
        io = remote('exploitme.com', 4141)
35
    else:
36
        io = process('./pwnable')
37

38
Arguments can also be accessed directly with the dot operator, e.g.:
39

40
.. code-block:: python
41

42
    if args.REMOTE:
43
        ...
44

45
Any undefined arguments evaluate to an empty string, ``''``.
46

47
The full list of supported "magic arguments" and their effects are listed
48
below.
49

50
"""
51
from __future__ import absolute_import
1✔
52
from __future__ import division
1✔
53

54
import collections
1✔
55
import logging
1✔
56
import os
1✔
57
import string
1✔
58
import sys
1✔
59

60
from pwnlib import term
1✔
61
from pwnlib.context import context
1✔
62

63
class PwnlibArgs(collections.defaultdict):
1✔
64
    def __getattr__(self, attr):
1✔
65
        if attr.startswith('_'):
1✔
66
            raise AttributeError(attr)
1✔
67
        return self[attr]
1✔
68

69
args = PwnlibArgs(str)
1✔
70
term_mode  = True
1✔
71
env_prefix = 'PWNLIB_'
1✔
72
free_form  = True
1✔
73

74
# Check to see if we were invoked as one of the 'pwn xxx' scripts.
75
# If so, we don't want to remove e.g. "SYS_" from the end of the command
76
# line, as this breaks things like constgrep.
77
import pwnlib.commandline
1✔
78
basename = os.path.basename(sys.argv[0])
1✔
79

80
if basename == 'pwn' or basename in pwnlib.commandline.__all__:
1!
81
    free_form = False
×
82

83

84
def isident(s):
1✔
85
    """
86
    Helper function to check whether a string is a valid identifier,
87
    as passed in on the command-line.
88
    """
89
    first = string.ascii_uppercase + '_'
1✔
90
    body = string.digits + first
1✔
91
    if not s:
1!
92
        return False
×
93
    if s[0] not in first:
1!
94
        return False
1✔
95
    if not all(c in body for c in s[1:]):
×
96
        return False
×
97
    return True
×
98

99
def asbool(s):
1✔
100
    """
101
    Convert a string to its boolean value
102
    """
103
    if   s.lower() == 'true':
1!
104
        return True
×
105
    elif s.lower() == 'false':
1!
106
        return False
×
107
    elif s.isdigit():
1!
108
        return bool(int(s))
1✔
109
    else:
110
        raise ValueError('must be integer or boolean: %r' % s)
×
111

112
def LOG_LEVEL(x):
1✔
113
    """Sets the logging verbosity used via ``context.log_level``,
114
    e.g. ``LOG_LEVEL=debug``.
115
    """
116
    with context.local(log_level=x):
×
117
        context.defaults['log_level']=context.log_level
×
118

119
def LOG_FILE(x):
1✔
120
    """Sets a log file to be used via ``context.log_file``, e.g.
121
    ``LOG_FILE=./log.txt``"""
122
    context.log_file=x
×
123

124
def SILENT(x):
1✔
125
    """Sets the logging verbosity to ``error`` which silences most
126
    output."""
127
    LOG_LEVEL('error')
×
128

129
def DEBUG(x):
1✔
130
    """Sets the logging verbosity to ``debug`` which displays much
131
    more information, including logging each byte sent by tubes."""
132
    LOG_LEVEL('debug')
×
133

134
def NOTERM(v):
1✔
135
    """Disables pretty terminal settings and animations."""
136
    if asbool(v):
1!
137
        global term_mode
138
        term_mode = False
1✔
139

140
def TIMEOUT(v):
1✔
141
    """Sets a timeout for tube operations (in seconds) via
142
    ``context.timeout``, e.g. ``TIMEOUT=30``"""
143
    context.defaults['timeout'] = int(v)
×
144

145
def RANDOMIZE(v):
1✔
146
    """Enables randomization of various pieces via ``context.randomize``"""
147
    context.defaults['randomize'] = asbool(v)
×
148

149
def NOASLR(v):
1✔
150
    """Disables ASLR via ``context.aslr``"""
151
    context.defaults['aslr'] = not asbool(v)
×
152

153
def NOPTRACE(v):
1✔
154
    """Disables facilities which require ``ptrace`` such as ``gdb.attach()``
155
    statements, via ``context.noptrace``."""
156
    context.defaults['noptrace'] = asbool(v)
×
157

158
def STDERR(v):
1✔
159
    """Sends logging to ``stderr`` by default, instead of ``stdout``"""
160
    context.log_console = sys.stderr
×
161

162
hooks = {
1✔
163
    'LOG_LEVEL': LOG_LEVEL,
164
    'LOG_FILE': LOG_FILE,
165
    'DEBUG': DEBUG,
166
    'NOTERM': NOTERM,
167
    'SILENT': SILENT,
168
    'RANDOMIZE': RANDOMIZE,
169
    'TIMEOUT': TIMEOUT,
170
    'NOASLR': NOASLR,
171
    'NOPTRACE': NOPTRACE,
172
    'STDERR': STDERR,
173
}
174

175
def initialize():
1✔
176
    global args, term_mode
177

178
    # Hack for readthedocs.org
179
    if 'READTHEDOCS' in os.environ:
1!
180
        os.environ['PWNLIB_NOTERM'] = '1'
×
181

182
    for k, v in os.environ.items():
1✔
183
        if not k.startswith(env_prefix):
1✔
184
            continue
1✔
185
        k = k[len(env_prefix):]
1✔
186

187
        if k in hooks:
1!
188
            hooks[k](v)
1✔
189
        elif isident(k):
×
190
            args[k] = v
×
191

192
    argv = sys.argv[:]
1✔
193
    for arg in sys.argv[:]:
1✔
194
        orig  = arg
1✔
195
        value = 'True'
1✔
196

197
        if '=' in arg:
1✔
198
            arg, value = arg.split('=', 1)
1✔
199

200
        if arg in hooks:
1!
201
            sys.argv.remove(orig)
×
202
            hooks[arg](value)
×
203

204
        elif free_form and isident(arg):
1!
205
            sys.argv.remove(orig)
×
206
            args[arg] = value
×
207

208
    if term_mode:
1✔
209
        term.init()
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc