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

Gallopsled / pwntools / 5436493948

pending completion
5436493948

push

github-actions

jasperla
add "retguard" property and display it with checksec

quoting http://undeadly.org/cgi?action=article;sid=20180606064444,
retguard is an "anti-ROP security mechanism, which uses random
per-function cookies to protect return addresses on the stack."

3968 of 6663 branches covered (59.55%)

6 of 6 new or added lines in 1 file covered. (100.0%)

12137 of 16984 relevant lines covered (71.46%)

0.71 hits per line

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

17.26
/pwnlib/term/readline.py
1
# -*- coding: utf-8 -*-
2
from __future__ import absolute_import
1✔
3
from __future__ import division
1✔
4
from __future__ import print_function
1✔
5

6
import six
1✔
7
import sys
1✔
8

9
from pwnlib.term import keyconsts as kc
1✔
10
from pwnlib.term import keymap as km
1✔
11
from pwnlib.term import term
1✔
12
from pwnlib.term import text
1✔
13

14
cursor = text.reverse
1✔
15

16
buffer_left, buffer_right = '', ''
1✔
17
saved_buffer = None
1✔
18
history = []
1✔
19
history_idx = None
1✔
20
prompt_handle = None
1✔
21
buffer_handle = None
1✔
22
suggest_handle = None
1✔
23
search_idx = None
1✔
24
search_results = []
1✔
25
startup_hook = None
1✔
26
shutdown_hook = None
1✔
27

28
delims = ' /;:.\\'
1✔
29

30
show_completion = True
1✔
31
show_suggestions = False
1✔
32

33
complete_hook = None
1✔
34
suggest_hook = None
1✔
35

36
tabs = 0
1✔
37

38
def force_to_bytes(data):
1✔
39
    if isinstance(data, bytes):
×
40
        return data
×
41
    try:
×
42
        return data.encode('utf-8')
×
43
    except Exception:
×
44
        return data.encode('latin-1')
×
45

46
def set_completer(completer):
1✔
47
    global complete_hook, suggest_hook
48
    if completer is None:
×
49
        complete_hook = None
×
50
        suggest_hook = None
×
51
    else:
52
        complete_hook = completer.complete
×
53
        suggest_hook = completer.suggest
×
54

55
def fmt_suggestions(suggestions):
1✔
56
    if suggestions:
×
57
        s = ''
×
58
        l = max(map(len, suggestions))
×
59
        columns = term.width // (l + 1)
×
60
        column_width = term.width // columns
×
61
        fmt = '%%-%ds' % column_width
×
62
        for j in range(0, len(suggestions), columns):
×
63
            for k in range(columns):
×
64
                l = j + k
×
65
                if l < len(suggestions):
×
66
                    s += fmt % suggestions[l]
×
67
            s += '\n'
×
68
    else:
69
        s = '(no completions)\n'
×
70
    return s
×
71

72
def auto_complete(*_):
1✔
73
    global show_suggestions, tabs
74
    if search_idx is not None:
×
75
        commit_search()
×
76
        tabs = 0
×
77
    elif tabs == 1:
×
78
        if complete_hook:
×
79
            ret = complete_hook(buffer_left, buffer_right)
×
80
            if ret:
×
81
                tabs = 0
×
82
                insert_text(ret)
×
83
    else:
84
        show_suggestions = not show_suggestions
×
85
        redisplay()
×
86

87
def handle_keypress(trace):
1✔
88
    global tabs
89
    k = trace[-1]
×
90
    if k == '<tab>':
×
91
        tabs += 1
×
92
    else:
93
        tabs = 0
×
94

95
def clear():
1✔
96
    global buffer_left, buffer_right, history_idx, search_idx
97
    buffer_left, buffer_right = '', ''
×
98
    history_idx = None
×
99
    search_idx = None
×
100
    redisplay()
×
101

102
def redisplay():
1✔
103
    global suggest_handle
104
    if buffer_handle:
×
105
        if show_suggestions and suggest_hook:
×
106
            suggestions = suggest_hook(buffer_left, buffer_right)
×
107
            if suggest_handle is None:
×
108
                h = prompt_handle or buffer_handle
×
109
                suggest_handle = term.output(before = h)
×
110
            s = fmt_suggestions(suggestions)
×
111
            suggest_handle.update(s)
×
112
        elif suggest_handle:
×
113
            suggest_handle.update('')
×
114
        if search_idx is None:
×
115
            s = None
×
116
            if buffer_right:
×
117
                s = buffer_left + cursor(buffer_right[0]) + buffer_right[1:]
×
118
            elif show_completion and complete_hook:
×
119
                ret = complete_hook(buffer_left, buffer_right)
×
120
                if ret:
×
121
                    s = buffer_left + \
×
122
                      text.underline(cursor(ret[0])) + \
123
                      text.underline(ret[1:])
124
            s = s or buffer_left + cursor(' ')
×
125
            buffer_handle.update(s)
×
126
        else:
127
            if search_results != []:
×
128
                idx, i, j = search_results[search_idx]
×
129
                buf = history[idx]
×
130
                a, b, c = buf[:i], buf[i:j], buf[j:]
×
131
                s = a + text.bold_green(b) + c
×
132
            else:
133
                s = text.white_on_red(buffer_left)
×
134
            buffer_handle.update('(search) ' + s)
×
135

136
def self_insert(trace):
1✔
137
    if len(trace) != 1:
×
138
        return
×
139
    k = trace[0]
×
140
    if k.type == kc.TYPE_UNICODE and k.mods == kc.MOD_NONE:
×
141
        insert_text(k.code)
×
142

143
def set_buffer(left, right):
1✔
144
    global buffer_left, buffer_right
145
    buffer_left = left
×
146
    buffer_right = right
×
147
    redisplay()
×
148

149
def cancel_search(*_):
1✔
150
    global search_idx
151
    if search_idx is not None:
×
152
        search_idx = None
×
153
        redisplay()
×
154

155
def commit_search():
1✔
156
    global search_idx
157
    if search_idx is not None and search_results:
×
158
        set_buffer(history[search_results[search_idx][0]], '')
×
159
        search_idx = None
×
160
        redisplay()
×
161

162
def update_search_results():
1✔
163
    global search_results, search_idx, show_suggestions
164
    if search_idx is None:
×
165
        return
×
166
    show_suggestions = False
×
167
    if search_results:
×
168
        hidx = search_results[search_idx][0]
×
169
    else:
170
        hidx = None
×
171
    search_results = []
×
172
    search_idx = 0
×
173
    if not buffer_left:
×
174
        return
×
175
    for idx, h in enumerate(history):
×
176
        for i in range(0, len(h) - len(buffer_left) + 1):
×
177
            if h[i:i + len(buffer_left)] == buffer_left:
×
178
                if hidx is not None and idx == hidx:
×
179
                    search_idx = len(search_results)
×
180
                search_results.append((idx, i, i + len(buffer_left)))
×
181
                break
×
182

183
def search_history(*_):
1✔
184
    global buffer_left, buffer_right, history_idx, search_idx
185
    if search_idx is None:
×
186
        buffer_left, buffer_right = buffer_left + buffer_right, ''
×
187
        history_idx = None
×
188
        search_idx = 0
×
189
        update_search_results()
×
190
    elif search_results:
×
191
        search_idx = (search_idx + 1) % len(search_results)
×
192
    redisplay()
×
193

194
def history_prev(*_):
1✔
195
    global history_idx, saved_buffer
196
    if history == []:
×
197
        return
×
198
    cancel_search()
×
199
    if history_idx is None:
×
200
        saved_buffer = (buffer_left, buffer_right)
×
201
        history_idx = -1
×
202
    if history_idx < len(history) - 1:
×
203
        history_idx += 1
×
204
        set_buffer(history[history_idx], '')
×
205

206
def history_next(*_):
1✔
207
    global history_idx, saved_buffer
208
    if history_idx is None:
×
209
        return
×
210
    cancel_search()
×
211
    if history_idx == 0:
×
212
        set_buffer(*saved_buffer)
×
213
        history_idx = None
×
214
        saved_buffer = None
×
215
    else:
216
        history_idx -= 1
×
217
        set_buffer(history[history_idx], '')
×
218

219
def backward_char(*_):
1✔
220
    global buffer_left, buffer_right
221
    commit_search()
×
222
    if buffer_left:
×
223
        buffer_right = buffer_left[-1] + buffer_right
×
224
        buffer_left = buffer_left[:-1]
×
225
    redisplay()
×
226

227
def forward_char(*_):
1✔
228
    global buffer_left, buffer_right
229
    commit_search()
×
230
    if buffer_right:
×
231
        buffer_left += buffer_right[0]
×
232
        buffer_right = buffer_right[1:]
×
233
    redisplay()
×
234

235
def insert_text(s):
1✔
236
    global history_idx, saved_buffer, buffer_left
237
    if history_idx is not None:
×
238
        history_idx = None
×
239
        saved_buffer = None
×
240
    buffer_left += s
×
241
    update_search_results()
×
242
    redisplay()
×
243

244
def submit(*_):
1✔
245
    if search_idx is not None:
×
246
        commit_search()
×
247
    else:
248
        keymap.stop()
×
249

250
def control_c(*_):
1✔
251
    global history_idx, saved_buffer
252
    if search_idx is not None:
×
253
        cancel_search()
×
254
    elif history_idx is not None:
×
255
        set_buffer(*saved_buffer)
×
256
        history_idx = None
×
257
        saved_buffer = None
×
258
    elif buffer_left or buffer_right:
×
259
        clear()
×
260
    else:
261
        raise KeyboardInterrupt
×
262

263
def control_d(*_):
1✔
264
    if buffer_left or buffer_right:
×
265
        return
×
266
    global eof
267
    eof = True
×
268
    keymap.stop()
×
269

270
def kill_to_end(*_):
1✔
271
    global buffer_right
272
    commit_search()
×
273
    buffer_right = []
×
274
    redisplay()
×
275

276
def delete_char_forward(*_):
1✔
277
    global buffer_right
278
    commit_search()
×
279
    if buffer_right:
×
280
        buffer_right = buffer_right[1:]
×
281
        redisplay()
×
282

283
def delete_char_backward(*_):
1✔
284
    global buffer_left
285
    if buffer_left:
×
286
        buffer_left = buffer_left[:-1]
×
287
        update_search_results()
×
288
        redisplay()
×
289

290
def kill_word_backward(*_):
1✔
291
    global buffer_left
292
    commit_search()
×
293
    flag = False
×
294
    while buffer_left:
×
295
        c = buffer_left[-1]
×
296
        if c[0] in delims:
×
297
            if flag:
×
298
                break
×
299
        else:
300
            flag = True
×
301
        buffer_left = buffer_left[:-1]
×
302
    redisplay()
×
303

304
def backward_word(*_):
1✔
305
    global buffer_left, buffer_right
306
    commit_search()
×
307
    flag = False
×
308
    while buffer_left:
×
309
        c = buffer_left[-1]
×
310
        if c[0] in delims:
×
311
            if flag:
×
312
                break
×
313
        else:
314
            flag = True
×
315
        buffer_right = buffer_left[-1] + buffer_right
×
316
        buffer_left = buffer_left[:-1]
×
317
    redisplay()
×
318

319
def forward_word(*_):
1✔
320
    global buffer_left, buffer_right
321
    commit_search()
×
322
    flag = False
×
323
    while buffer_right:
×
324
        c = buffer_right[0]
×
325
        if c[0] in delims:
×
326
            if flag:
×
327
                break
×
328
        else:
329
            flag = True
×
330
        buffer_left += buffer_right[0]
×
331
        buffer_right = buffer_right[1:]
×
332
    redisplay()
×
333

334
def go_beginning(*_):
1✔
335
    commit_search()
×
336
    set_buffer('', buffer_left + buffer_right)
×
337

338
def go_end(*_):
1✔
339
    commit_search()
×
340
    set_buffer(buffer_left + buffer_right, '')
×
341

342
keymap = km.Keymap({
1✔
343
    '<nomatch>'   : self_insert,
344
    '<up>'        : history_prev,
345
    '<down>'      : history_next,
346
    '<left>'      : backward_char,
347
    '<right>'     : forward_char,
348
    '<del>'       : delete_char_backward,
349
    '<delete>'    : delete_char_forward,
350
    '<enter>'     : submit,
351
    'C-j'         : submit,
352
    'C-<left>'    : backward_word,
353
    'C-<right>'   : forward_word,
354
    'M-<left>'    : backward_word,
355
    'M-<right>'   : forward_word,
356
    'C-c'         : control_c,
357
    'C-d'         : control_d,
358
    'C-k'         : kill_to_end,
359
    'C-w'         : kill_word_backward,
360
    '<backspace>' : kill_word_backward,
361
    'M-<del>'     : kill_word_backward,
362
    'C-r'         : search_history,
363
    '<escape>'    : cancel_search,
364
    'C-a'         : go_beginning,
365
    'C-e'         : go_end,
366
    '<tab>'       : auto_complete,
367
    '<any>'       : handle_keypress,
368
    })
369

370
def readline(_size=-1, prompt='', float=True, priority=10):
1✔
371
    # The argument  _size is unused, but is there for compatibility
372
    # with the existing readline
373

374
    global buffer_handle, prompt_handle, suggest_handle, eof, \
375
        show_suggestions
376

377
    # XXX circular imports
378
    from pwnlib.term import term_mode
1✔
379
    if not term_mode:
1!
380
        six.print_(prompt, end='', flush=True)
1✔
381
        return getattr(sys.stdin, 'buffer', sys.stdin).readline(_size).rstrip(b'\n')
1✔
382
    show_suggestions = False
×
383
    eof = False
×
384
    if prompt:
×
385
        prompt_handle = term.output(prompt, float = float, priority = priority)
×
386
    else:
387
        prompt_handle = None
×
388
    buffer_handle = term.output(float = float, priority = priority)
×
389
    suggest_handle = None
×
390
    clear()
×
391
    if startup_hook:
×
392
        startup_hook()
×
393
    try:
×
394
        while True:
395
            try:
×
396
                try:
×
397
                    keymap.handle_input()
×
398
                except EOFError:
×
399
                    if len(buffer_left + buffer_right) == 0:
×
400
                        return b''
×
401
                if eof:
×
402
                    return b''
×
403
                else:
404
                    buffer = (buffer_left + buffer_right)
×
405
                    if buffer:
×
406
                        history.insert(0, buffer)
×
407
                    return force_to_bytes(buffer)
×
408
            except KeyboardInterrupt:
×
409
                control_c()
×
410
    finally:
411
        line = buffer_left + buffer_right + '\n'
×
412
        buffer_handle.update(line)
×
413
        buffer_handle.freeze()
×
414
        buffer_handle = None
×
415
        if prompt_handle:
×
416
            prompt_handle.freeze()
×
417
            prompt_handle = None
×
418
        if suggest_handle:
×
419
            suggest_handle.freeze()
×
420
            suggest_handle = None
×
421
        if shutdown_hook:
×
422
            shutdown_hook()
×
423

424
def raw_input(prompt='', float=True):
1✔
425
    r"""raw_input(prompt='', float=True)
426

427
    Replacement for the built-in ``raw_input`` using ``pwnlib`` readline
428
    implementation.
429

430
    Arguments:
431
        prompt(str): The prompt to show to the user.
432
        float(bool): If set to `True`, prompt and input will float to the
433
                     bottom of the screen when `term.term_mode` is enabled.
434
    """
435
    return readline(-1, prompt, float)
1✔
436

437
def str_input(prompt='', float=True):
1✔
438
    r"""str_input(prompt='', float=True)
439

440
    Replacement for the built-in ``input`` in python3 using ``pwnlib`` readline
441
    implementation.
442

443
    Arguments:
444
        prompt(str): The prompt to show to the user.
445
        float(bool): If set to `True`, prompt and input will float to the
446
                     bottom of the screen when `term.term_mode` is enabled.
447
    """
448
    return readline(-1, prompt, float).decode()
×
449

450
def eval_input(prompt='', float=True):
1✔
451
    """eval_input(prompt='', float=True)
452

453
    Replacement for the built-in python 2 - style ``input`` using
454
    ``pwnlib`` readline implementation, and `pwnlib.util.safeeval.expr`
455
    instead of ``eval`` (!).
456

457
    Arguments:
458
        prompt(str): The prompt to show to the user.
459
        float(bool): If set to ``True``, prompt and input will float to the
460
                     bottom of the screen when `term.term_mode` is enabled.
461

462
    Example:
463

464
        >>> try:
465
        ...     saved = sys.stdin, pwnlib.term.term_mode
466
        ...     pwnlib.term.term_mode = False
467
        ...     sys.stdin = io.TextIOWrapper(io.BytesIO(b"{'a': 20}"))
468
        ...     eval_input("Favorite object? ")['a']
469
        ... finally:
470
        ...     sys.stdin, pwnlib.term.term_mode = saved
471
        Favorite object? 20
472
    """
473
    from pwnlib.util import safeeval
1✔
474
    return safeeval.const(readline(-1, prompt, float))
1✔
475

476
def init():
1✔
477
    global safeeval
478
    # defer imports until initialization
479
    import sys
1✔
480
    from six.moves import builtins
1✔
481
    from pwnlib.util import safeeval
1✔
482

483
    class Wrapper:
1✔
484
        def __init__(self, fd):
1✔
485
            self._fd = fd
1✔
486
        def readline(self, size = None):
1✔
487
            return readline(size)
×
488
        def __getattr__(self, k):
1✔
489
            return getattr(self._fd, k)
×
490
    sys.stdin = Wrapper(sys.stdin)
1✔
491

492
    if six.PY2:
1!
493
        builtins.raw_input = raw_input
×
494
        builtins.input = eval_input
×
495
    else:
496
        builtins.input = str_input
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