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
from __future__ import print_function
import argparse
import re
import string
import sys
import pwnlib.args
pwnlib.args.free_form = False
from pwn import *
from pwnlib.commandline import common
parser = common.parser_commands.add_parser(
'disasm',
help = 'Disassemble bytes into text format',
description = 'Disassemble bytes into text format'
)
parser.add_argument(
'hex',
metavar = 'hex',
nargs = '*',
help = 'Hex-string to disassemble. If none are supplied, then it uses stdin in non-hex mode.'
)
parser.add_argument(
'-c', '--context',
metavar = 'arch_or_os',
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(
"-a","--address",
metavar='address',
help="Base address",
type=str,
default='0'
)
parser.add_argument(
'--color',
help="Color output",
action='store_true',
default=sys.stdout.isatty()
)
parser.add_argument(
'--no-color',
help="Disable color output",
action='store_false',
dest='color'
)
def main(args):
if len(args.hex) > 0:
dat = ''.join(args.hex).encode('utf-8', 'surrogateescape')
dat = dat.translate(None, string.whitespace.encode('ascii'))
if not set(string.hexdigits.encode('ascii')) >= set(dat):
print("This is not a hex string")
exit(-1)
dat = unhex(dat)
else:
dat = getattr(sys.stdin, 'buffer', sys.stdin).read()
if args.color:
from pygments import highlight
from pygments.formatters import TerminalFormatter
from pwnlib.lexer import PwntoolsLexer
dis = disasm(dat, vma=safeeval.const(args.address))
# Note: those patterns are copied from disasm function
pattern = '^( *[0-9a-f]+: *)((?:[0-9a-f]+ )+ *)(.*)'
lines = []
for line in dis.splitlines():
match = re.search(pattern, line)
if not match:
# Append as one element tuple
lines.append((line,))
continue
groups = match.groups()
o, b, i = groups
lines.append((o, b, i))
highlight_bytes = lambda t: ''.join(map(lambda x: x.replace('00', text.red('00')).replace('0a', text.red('0a')), group(2, t)))
for line in lines:
if len(line) == 3:
o, b, i = line
b = ' '.join(highlight_bytes(bb) for bb in b.split(' '))
i = highlight(i.strip(), PwntoolsLexer(), TerminalFormatter()).strip()
i = i.replace(',',', ')
print(o,b,i)
else:
print(line[0])
return
print(disasm(dat, vma=safeeval.const(args.address)))
if __name__ == '__main__':
pwnlib.commandline.common.main(__file__, main)
|