Dumpargs add --force to show all possible register arguments (#326)

* Added --all flag to dumpargs command

This gives possibility to dump all register argument even
if we failed to resolve arguments from metadatas.

* Display info when dumpargs not resolved call args

* Dumpargs: changed --all to --force

* Revert telescope changes as it fails when we are not on call instruction.

* Fix isort
pull/334/head
Disconnect3d 8 years ago committed by GitHub
parent 783f9bb6cf
commit ceb3ff67cc

@ -52,8 +52,9 @@ ida_replacements = {
'__userpurge': '',
}
def get_syscall_name(instruction):
if not CS_GRP_INT in instruction.groups:
if CS_GRP_INT not in instruction.groups:
return None
try:
@ -65,6 +66,7 @@ def get_syscall_name(instruction):
except:
return None
def get(instruction):
"""
Returns an array containing the arguments to the current function,
@ -109,7 +111,6 @@ def get(instruction):
return []
result = []
args = []
name = name or ''
sym = gdb.lookup_symbol(name)
@ -128,7 +129,6 @@ def get(instruction):
except TypeError:
pass
# Try to grab the data out of IDA
if not func and target:
typename = pwndbg.ida.GetType(target)
@ -139,17 +139,17 @@ def get(instruction):
# GetType() does not include the name.
typename = typename.replace('(', ' function_name(', 1)
for k,v in ida_replacements.items():
typename = typename.replace(k,v)
for k, v in ida_replacements.items():
typename = typename.replace(k, v)
func = pwndbg.funcparser.ExtractFuncDeclFromSource(typename + ';')
func = pwndbg.funcparser.ExtractFuncDeclFromSource(typename + ';')
if func:
args = func.args
else:
args = [pwndbg.functions.Argument('int',0,argname(i, abi)) for i in range(n_args_default)]
args = [pwndbg.functions.Argument('int', 0, argname(i, abi)) for i in range(n_args_default)]
for i,arg in enumerate(args):
for i, arg in enumerate(args):
result.append((arg, argument(i, abi)))
return result
@ -164,6 +164,7 @@ def argname(n, abi=None):
return 'arg[%i]' % n
def argument(n, abi=None):
"""
Returns the nth argument, as if $pc were a 'call' or 'bl' type
@ -180,3 +181,14 @@ def argument(n, abi=None):
sp = pwndbg.regs.sp + (n * pwndbg.arch.ptrsize)
return int(pwndbg.memory.poi(pwndbg.typeinfo.ppvoid, sp))
def arguments(abi=None):
"""
Yields (arg_name, arg_value) tuples for arguments from a given ABI.
"""
abi = abi or pwndbg.abi.ABI.default()
regs = abi.register_arguments
for i in range(len(regs)):
yield argname(i, abi), argument(i, abi)

@ -5,24 +5,60 @@ from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import argparse
import pwndbg.arguments
import pwndbg.chain
import pwndbg.commands
import pwndbg.commands.telescope
import pwndbg.disasm
parser = argparse.ArgumentParser(
description='Prints determined arguments for call instruction. Pass --all to see all possible arguments.'
)
parser.add_argument('--force', action='store_true', help='Force displaying of all arguments.')
@pwndbg.commands.Command
@pwndbg.commands.ArgparsedCommand(parser)
@pwndbg.commands.OnlyWhenRunning
def dumpargs(*a):
def dumpargs(force=False):
force_text = "Use `%s --force` to force the display." % dumpargs.__name__
if not pwndbg.disasm.is_call() and not force:
print("Cannot dump args as current instruction is not a call.\n" + force_text)
return
args = all_args() if force else call_args()
if args:
print('\n'.join(args))
else:
print("Couldn't resolve call arguments. Maybe the function doesn\'t take any?\n" + force_text)
def call_args():
"""
If the current instruction is a call instruction, print that arguments.
Returns list of resolved call argument strings for display.
Attempts to resolve the target and determine the number of arguments.
Should be used only when being on a call instruction.
"""
result = []
results = []
# For call instructions, attempt to resolve the target and
# determine the number of arguments.
for arg, value in pwndbg.arguments.get(pwndbg.disasm.one()):
code = False if arg.type == 'char' else True
pretty = pwndbg.chain.format(value, code=code)
result.append('%8s%-10s %s' % ('',arg.name+':', pretty))
results.append(' %-10s %s' % (arg.name+':', pretty))
return results
def all_args():
"""
Returns list of all argument strings for display.
"""
results = []
for name, value in pwndbg.arguments.arguments():
results.append('%4s = %s' % (name, pwndbg.chain.format(value)))
print('\n'.join(result))
return results

@ -235,3 +235,10 @@ def near(address, instructions=1, emulate=False):
del insns[-1]
return insns
def is_call(address=None):
"""
Returns whether a given address contains call instruction.
"""
return capstone.CS_GRP_CALL in one(address).groups

Loading…
Cancel
Save