From 64826905f8cbcc67cc7cca4be42347900f4fc7c4 Mon Sep 17 00:00:00 2001 From: hugsy Date: Wed, 9 Jun 2021 00:02:08 -0700 Subject: [PATCH] * improved command argparsing * ported a few functions to use it * updated unit tests to reflect the syntax change --- gef.py | 259 ++++++++++++++++++++-------------------------- tests/runtests.py | 8 +- 2 files changed, 114 insertions(+), 153 deletions(-) diff --git a/gef.py b/gef.py index b543303b5..5d4ce60d3 100644 --- a/gef.py +++ b/gef.py @@ -2594,46 +2594,72 @@ def inner_f(*args, **kwargs): return wrapper +def FakeExit(*args, **kwargs): + raise RuntimeWarning + +sys.exit = FakeExit + def parse_arguments(required_arguments, optional_arguments): """Argument parsing decorator.""" + def int_wrapper(x): return int(x, 0) + def decorator(f): def wrapper(*args, **kwargs): - parser = argparse.ArgumentParser(add_help=False, argument_default=argparse.SUPPRESS) - + parser = argparse.ArgumentParser(prog="gef", add_help=False) for argname in required_arguments: argvalue = required_arguments[argname] argtype = type(argvalue) + if argtype == int: + argtype = int_wrapper + if argname.startswith("-"): + # optional args if argtype == bool: - action = "store_true" if argvalue else "store_false" - parser.add_argument(argname, action=action, help="Help for {}".format(argname), required=True, default=argvalue) + parser.add_argument(argname, action="store_true" if argvalue else "store_false") else: - parser.add_argument(argname, type=argtype, help="Help for {}".format(argname), required=True, default=argvalue) + parser.add_argument(argname, type=argtype, required=True, default=argvalue) else: - parser.add_argument(argname, type=argtype, help="Help for {}".format(argname), default=argvalue) + # positional args + parser.add_argument(argname, type=argtype, default=argvalue, nargs='?') for argname in optional_arguments: if not argname.startswith("-"): continue - argvalue = optional_arguments[argname] argtype = type(argvalue) + if argtype == int: + argtype = int_wrapper if argtype == bool: - action = "store_true" if argvalue else "store_false" - parser.add_argument(argname, action=action, help="Help for {}".format(argname), required=False, default=argvalue) + parser.add_argument(argname, action="store_true" if argvalue else "store_false") else: - parser.add_argument(argname, type=argtype, help="Help for {}".format(argname), required=False, default=argvalue) + parser.add_argument(argname, type=argtype, default=argvalue) obj, cmd_args = args[0], args[1:] parsed_args = parser.parse_args(*cmd_args) kwargs["arguments"] = parsed_args - info("executing {}".format(f.__name__)) return f(*args, **kwargs) return wrapper return decorator +def copy_to_clipboard(data): + """Helper function to submit data to the clipboard""" + if sys.platform == "linux": + xclip = which("xclip") + prog = [xclip, "-selection", "clipboard", "-i"] + elif sys.platform == "darwin": + pbcopy = which("pbcopy") + prog = [pbcopy] + else: + raise NotImplementedError("Unsupported OS") + + p = subprocess.Popen(prog, stdin=subprocess.PIPE) + p.stdin.write(data) + p.stdin.close() + p.wait() + return + def use_stdtype(): if is_32bit(): return "uint32_t" @@ -4293,111 +4319,75 @@ def do_invoke(self, argv): class PrintFormatCommand(GenericCommand): """Print bytes format in high level languages.""" + format_matrix = { + 8: (endian_str() + "B", "char", "db"), + 16: (endian_str() + "H", "short", "dw"), + 32: (endian_str() + "I", "int", "dd"), + 64: (endian_str() + "Q", "long long", "dq"), + } + + valid_formats = ["py", "c", "js", "asm"] + _cmdline_ = "print-format" - _syntax_ = "{:s} [-f FORMAT] [-b BITSIZE] [-l LENGTH] [-c] [-h] LOCATION".format(_cmdline_) _aliases_ = ["pf",] - _example_ = "{0:s} -f py -b 8 -l 256 $rsp".format(_cmdline_) + _syntax_ = """{} [--lang LANG] [--bitlen SIZE] [--length LENGTH] [--clip] LOCATION +\t--lang LANG specifies the output format for programming language (available: {}, default 'py'). +\t--bitlen SIZE specifies size of bit (possible values: {}, default is 8). +\t--length LENGTH specifies length of array (default is 256). +\t--clip The output data will be copied to clipboard +\tLOCATION specifies where the address of bytes is stored.""".format(_cmdline_, str(valid_formats), str(format_matrix.keys())) + _example_ = "{} --lang py -l 16 $rsp".format(_cmdline_) - bitformat = {8: "