File: scramble.py

package info (click to toggle)
pwntools 4.15.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 18,508 kB
  • sloc: python: 59,870; ansic: 48,351; asm: 45,047; sh: 396; makefile: 256
file content (113 lines) | stat: -rw-r--r-- 2,660 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
from __future__ import absolute_import
from __future__ import division

import argparse
import sys

import pwnlib.args
pwnlib.args.free_form = False

from pwn import *
from pwnlib.commandline import common

parser = common.parser_commands.add_parser(
    'scramble',
    help = 'Shellcode encoder',
    description = 'Shellcode encoder'
)

parser.add_argument(
    "-f", "--format",
    help="Output format (defaults to hex for ttys, otherwise raw)",
    choices=['raw', 'hex', 'string', 'elf']
)

parser.add_argument(
    "-o","--output",
    metavar='file',
    help="Output file (defaults to stdout)",
    type=argparse.FileType('wb'),
    default=getattr(sys.stdout, 'buffer', sys.stdout)
)

parser.add_argument(
    '-c', '--context',
    metavar = 'context',
    action = 'append',
    type   = common.context_arg,
    choices = common.choices,
    help = 'The os/architecture/endianness/bits the shellcode will run in (default: linux/i386), choose from: %s' % common.choices,
)

parser.add_argument(
    '-p', '--alphanumeric',
    action='store_true',
    help = 'Encode the shellcode with an alphanumeric encoder'
)

parser.add_argument(
    '-v', '--avoid',
    action='append',
    help = 'Encode the shellcode to avoid the listed bytes'
)

parser.add_argument(
    '-n', '--newline',
    dest='avoid',
    action='append_const',
    const='\n',
    help = 'Encode the shellcode to avoid newlines'
)

parser.add_argument(
    '-z', '--zero',
    dest='avoid',
    action='append_const',
    const='\x00',
    help = 'Encode the shellcode to avoid NULL bytes'
)

parser.add_argument(
    '-d',
    '--debug',
    help='Debug the shellcode with GDB',
    action='store_true'
)

def main(args):
    tty    = args.output.isatty()

    if sys.stdin.isatty():
        parser.print_usage()
        sys.exit(0)

    stdin_buffer = getattr(sys.stdin, 'buffer', sys.stdin)
    output = stdin_buffer.read()
    fmt    = args.format or ('hex' if tty else 'raw')
    formatters = {'r':bytes, 'h':enhex, 's':repr}

    if args.alphanumeric:
        output = alphanumeric(output)

    if args.avoid:
        output = avoid(output, ''.join(args.avoid))

    if args.debug:
        proc = gdb.debug_shellcode(output, arch=context.arch)
        proc.interactive()
        sys.exit(0)

    if fmt[0] == 'e':
        sys.stdout.write(make_elf(output))
    else:
        output = formatters[fmt[0]](output)
        if not hasattr(output, 'decode'):
            output = output.encode('ascii')
        args.output.write(output)

    if tty and fmt != 'raw':
        args.output.write(b'\n')


if __name__ == '__main__':
    pwnlib.commandline.common.main(__file__, main)