Better Display of varargs (#3244)

* by display of varargs by using either count or number of format specifiers

* ran lint.sh

* include non-standard format specifiers in regex pattern

Co-authored-by: k4lizen <124312252+k4lizen@users.noreply.github.com>

* change removing last argument logic in varargs handling

Co-authored-by: k4lizen <124312252+k4lizen@users.noreply.github.com>

* changed logic for popping the 'vararg' argument and removed unnecessary conversion to int

* remove extra line

* refactor pwndbg.arguments.get function to remove unnecessary branching

* files for testing got added by mistake

* replace method used on wrong var

---------

Co-authored-by: k4lizen <124312252+k4lizen@users.noreply.github.com>
pull/3248/head
akamikado 4 months ago committed by GitHub
parent 776bd079de
commit a24f5b471f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -7,6 +7,7 @@ registers and stack values.
from __future__ import annotations from __future__ import annotations
import re
from typing import List from typing import List
from typing import Tuple from typing import Tuple
@ -38,7 +39,6 @@ def get(instruction: PwndbgInstruction) -> List[Tuple[pwndbg.lib.functions.Argum
Otherwise, returns None. Otherwise, returns None.
""" """
n_args_default = 4
if instruction is None: if instruction is None:
return [] return []
@ -71,11 +71,9 @@ def get(instruction: PwndbgInstruction) -> List[Tuple[pwndbg.lib.functions.Argum
else: else:
return [] return []
result = [] original_name = name or ""
name = name or ""
sym = pwndbg.aglib.symbol.lookup_frame_symbol(name) name = original_name.replace("isoc99_", "") # __isoc99_sscanf
name = name.replace("isoc99_", "") # __isoc99_sscanf
name = name.replace("@plt", "") # getpwiod@plt name = name.replace("@plt", "") # getpwiod@plt
# If we have particular `XXX_chk` function in our database, we use it. # If we have particular `XXX_chk` function in our database, we use it.
@ -87,32 +85,43 @@ def get(instruction: PwndbgInstruction) -> List[Tuple[pwndbg.lib.functions.Argum
func = pwndbg.lib.functions.functions.get(name, None) func = pwndbg.lib.functions.functions.get(name, None)
if sym:
try:
target_type = sym.type.target()
except Exception:
target_type = sym.type
if target_type and target_type.code == pwndbg.dbg_mod.TypeCode.FUNC:
func_args = target_type.func_arguments()
if func_args is not None:
n_args_default = len(func_args)
# Try to grab the data out of IDA # Try to grab the data out of IDA
if not func and target: if not func and target:
func = pwndbg.integration.provider.get_func_type(target) func = pwndbg.integration.provider.get_func_type(target)
if func: if func:
args = func.args args = func.args
if len(args) > 1 and args[-1].name == "vararg":
format_value = pwndbg.enhance.enhance(argument(len(args) - 2, abi))
m = re.findall(
r"%[-+ #0]?(?:[0-9]+|\*)?(?:\.(?:[0-9]+|\*))?(?:hh|h|l|ll|q|L|j|z|Z|t)?[diuoxXfFeEgGaAcsCSpn]",
format_value,
)
vararg_cnt = len(m)
if vararg_cnt > 0:
args.pop()
args += [
pwndbg.lib.functions.Argument("int", 0, argname(len(args) + i, abi))
for i in range(vararg_cnt)
]
else: else:
n_args_default = 4
sym = pwndbg.aglib.symbol.lookup_frame_symbol(original_name)
if sym:
try:
target_type = sym.type.target()
except Exception:
target_type = sym.type
if target_type and target_type.code == pwndbg.dbg_mod.TypeCode.FUNC:
func_args = target_type.func_arguments()
if func_args is not None:
n_args_default = len(func_args)
args = ( args = (
pwndbg.lib.functions.Argument("int", 0, argname(i, abi)) for i in range(n_args_default) pwndbg.lib.functions.Argument("int", 0, argname(i, abi)) for i in range(n_args_default)
) )
for i, arg in enumerate(args): return [(arg, argument(i, abi)) for i, arg in enumerate(args)]
result.append((arg, argument(i, abi)))
return result
def argname(n: int, abi: pwndbg.lib.abi.ABI) -> str: def argname(n: int, abi: pwndbg.lib.abi.ABI) -> str:

Loading…
Cancel
Save