Add max-decimal-number config (#3259)

* centralize max-decimal deteminration and add config

* add comments about consistency with capstone

* fix tests

* drive-by fix
pull/3268/head
k4lizen 4 months ago committed by GitHub
parent a693fc7c7d
commit 4891cceafe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -774,6 +774,24 @@ Whether to left-pad disassembly.
---------- ----------
## **max-decimal-number**
Show all numbers greater than this in hex.
For negative numbers, their absolute value is used.
Set the parameter to 'unlimited' if you want all values in decimal.
Specially, set the parameter to zero if you want all values in hex.
The assembly instruction operands come from capstone, and are thus
not controlled by this setting. For consistency with them, leave
this setting at 9 (the default).
**Default:** 9
----------
## **max-visualize-chunk-size** ## **max-visualize-chunk-size**

@ -776,12 +776,7 @@ class DisassemblyAssistant:
# String functions assume the .before_value and .after_value have been set # String functions assume the .before_value and .after_value have been set
def _immediate_string(self, instruction, operand) -> str: def _immediate_string(self, instruction, operand) -> str:
value = operand.before_value return pwndbg.lib.pretty_print.int_to_string(operand.before_value)
if abs(value) < 0x10:
return "%i" % value
return "%#x" % value
def _register_string(self, instruction: PwndbgInstruction, operand: EnhancedOperand): def _register_string(self, instruction: PwndbgInstruction, operand: EnhancedOperand):
""" """
@ -863,7 +858,9 @@ class DisassemblyAssistant:
if (l_value := left.before_value_resolved) is not None and ( if (l_value := left.before_value_resolved) is not None and (
r_value := right.before_value_resolved r_value := right.before_value_resolved
) is not None: ) is not None:
print_left, print_right = pwndbg.enhance.format_small_int_pair(l_value, r_value) print_left, print_right = pwndbg.lib.pretty_print.int_pair_to_string(
l_value, r_value
)
# Ex: "0x7f - 0x12" or "0xdffffdea + 0x8" # Ex: "0x7f - 0x12" or "0xdffffdea + 0x8"
instruction.annotation = ( instruction.annotation = (
f"{print_left} {char_to_separate_operands} {print_right}" f"{print_left} {char_to_separate_operands} {print_right}"
@ -1043,7 +1040,7 @@ class DisassemblyAssistant:
math_string = None math_string = None
if op_one is not None and op_two is not None: if op_one is not None and op_two is not None:
print_left, print_right = pwndbg.enhance.format_small_int_pair(op_one, op_two) print_left, print_right = pwndbg.lib.pretty_print.int_pair_to_string(op_one, op_two)
math_string = f"{print_left} {char_to_separate_operands} {print_right}" math_string = f"{print_left} {char_to_separate_operands} {print_right}"

@ -106,10 +106,7 @@ def get(
color = lambda x: c.wx(old_color(x)) color = lambda x: c.wx(old_color(x))
if text is None: if text is None:
if address > 255: text = pwndbg.lib.pretty_print.int_to_string(address)
text = f"{address:#x}"
else:
text = f"{address}"
if prefix: if prefix:
# Replace first N characters with the provided prefix # Replace first N characters with the provided prefix

@ -475,10 +475,9 @@ class Emulator:
intval = 0 intval = 0
intval0 = intval intval0 = intval
if 0 <= intval < 10: intval = E.integer(
intval = E.integer(str(intval)) pwndbg.lib.pretty_print.int_to_string(intval & pwndbg.aglib.arch.ptrmask)
else: )
intval = E.integer("%#x" % int(intval & pwndbg.aglib.arch.ptrmask))
retval = [] retval = []

@ -11,7 +11,6 @@ supplemental information sources (e.g. active IDA Pro connection).
from __future__ import annotations from __future__ import annotations
import string import string
from typing import Tuple
import pwndbg import pwndbg
import pwndbg.aglib.arch import pwndbg.aglib.arch
@ -24,31 +23,15 @@ import pwndbg.color.enhance as E
import pwndbg.color.memory import pwndbg.color.memory
import pwndbg.integration import pwndbg.integration
import pwndbg.lib.cache import pwndbg.lib.cache
import pwndbg.lib.pretty_print
from pwndbg import color from pwndbg import color
def format_small_int(value: int) -> str:
if value < 10:
return str(value)
else:
return hex(value)
def format_small_int_pair(first: int, second: int) -> Tuple[str, str]:
if first < 10 and second < 10:
return (str(first), str(second))
else:
return (
hex(first),
hex(second),
)
def int_str(value: int) -> str: def int_str(value: int) -> str:
retval = format_small_int(value) retval = pwndbg.lib.pretty_print.int_to_string(value)
# Try to unpack the value as a string # Try to unpack the value as a string
packed = pwndbg.aglib.arch.pack(int(value)) packed = pwndbg.aglib.arch.pack(value)
if all(c in string.printable.encode("utf-8") for c in packed): if all(c in string.printable.encode("utf-8") for c in packed):
if len(retval) > 4: if len(retval) > 4:
retval = "{} ({!r})".format(retval, str(packed.decode("ascii", "ignore"))) retval = "{} ({!r})".format(retval, str(packed.decode("ascii", "ignore")))
@ -133,10 +116,7 @@ def enhance(
if safe_linking: if safe_linking:
intval ^= value >> 12 intval ^= value >> 12
intval0 = intval intval0 = intval
if 0 <= intval < 10: intval = E.integer(pwndbg.lib.pretty_print.int_to_string(intval & pwndbg.aglib.arch.ptrmask))
intval = E.integer(str(intval))
else:
intval = E.integer("%#x" % int(intval & pwndbg.aglib.arch.ptrmask))
retval = [] retval = []
@ -184,6 +164,6 @@ def enhance(
return E.unknown("???") return E.unknown("???")
if len(retval) == 1: if len(retval) == 1:
return retval[0] # type: ignore[return-value] return retval[0]
return retval[0] + E.comment(color.strip(f" /* {'; '.join(retval[1:])} */")) # type: ignore[arg-type] return retval[0] + E.comment(color.strip(f" /* {'; '.join(retval[1:])} */"))

@ -5,10 +5,68 @@ from typing import Any
from typing import Callable from typing import Callable
from typing import List from typing import List
from typing import Optional from typing import Optional
from typing import Tuple
import pwndbg
import pwndbg.color as color import pwndbg.color as color
from pwndbg.color import theme from pwndbg.color import theme
max_decimal_number = pwndbg.config.add_param(
"max-decimal-number",
9,
"show all numbers greater than this in hex",
param_class=pwndbg.lib.config.PARAM_ZUINTEGER_UNLIMITED,
help_docstring="""
For negative numbers, their absolute value is used.
Set the parameter to 'unlimited' if you want all values in decimal.
Specially, set the parameter to zero if you want all values in hex.
The assembly instruction operands come from capstone, and are thus
not controlled by this setting. For consistency with them, leave
this setting at 9 (the default).
""",
# We could look into also overwriting the capstone operands string, similarly
# to what is done here: https://github.com/pwndbg/pwndbg/blob/26db4533aa08d77c4bbc359b4760a0944e0c6b23/pwndbg/aglib/disasm/arch.py#L322-L331
)
def int_to_string(num: int) -> str:
"""
Converts an integer value to string.
Decides whether to format it in decimal or
hex depending on the max-decimal-number config.
"""
if max_decimal_number == -1:
return f"{num}"
elif max_decimal_number == 0:
return f"{num:#x}"
elif abs(num) > max_decimal_number:
return f"{num:#x}"
else:
return f"{num}"
def int_pair_to_string(num1: int, num2: int) -> Tuple[str, str]:
"""
Converts an integer pair to a string pair.
Decides whether to format them in decimal or
hex depending on the max-decimal-number config.
If either value should be hex, both are hex.
"""
if max_decimal_number == -1:
return f"{num1}", f"{num2}"
elif max_decimal_number == 0:
return f"{num1:#x}", f"{num2:#x}"
elif abs(num1) > max_decimal_number or abs(num2) > max_decimal_number:
return f"{num1:#x}", f"{num2:#x}"
else:
return f"{num1}", f"{num2}"
config_property_name_color = theme.add_color_param( config_property_name_color = theme.add_color_param(
"prop-name-color", "prop-name-color",
"bold", "bold",
@ -36,6 +94,7 @@ Used heavily in mallocng commands.
""" """
) )
@dataclass @dataclass
class Property: class Property:
""" """
@ -129,15 +188,10 @@ def from_properties(
# Transform prop values to string representation # Transform prop values to string representation
for prop in properties: for prop in properties:
if isinstance(prop.value, int): if isinstance(prop.value, int):
if prop.use_hex: prop.value = f"{prop.value:#x}" if prop.use_hex else f"{prop.value}"
prop.value = hex(prop.value)
else:
prop.value = str(prop.value)
if isinstance(prop.alt_value, int): if isinstance(prop.alt_value, int):
if prop.use_hex: prop.alt_value = f"{prop.alt_value:#x}" if prop.use_hex else f"{prop.alt_value}"
prop.alt_value = hex(prop.alt_value)
else:
prop.alt_value = str(prop.alt_value)
indentation_str = indent_size * " " indentation_str = indent_size * " "
extra_list_pad_str = ( extra_list_pad_str = (

@ -314,7 +314,7 @@ def test_aarch64_binary_operations(qemu_assembly_run):
" 0x101013c <_start+28> orr x5, x0, x1 X5 => 0x237 (0x7 | 0x233)\n" " 0x101013c <_start+28> orr x5, x0, x1 X5 => 0x237 (0x7 | 0x233)\n"
" 0x1010140 <_start+32> eor x6, x0, x1 X6 => 0x234 (0x7 ^ 0x233)\n" " 0x1010140 <_start+32> eor x6, x0, x1 X6 => 0x234 (0x7 ^ 0x233)\n"
" 0x1010144 <_start+36> mul x10, x0, x1 X10 => 0xf65 (0x7 * 0x233)\n" " 0x1010144 <_start+36> mul x10, x0, x1 X10 => 0xf65 (0x7 * 0x233)\n"
" 0x1010148 <_start+40> udiv x11, x1, x0 X11 => 80 (0x233 / 0x7)\n" " 0x1010148 <_start+40> udiv x11, x1, x0 X11 => 0x50 (0x233 / 0x7)\n"
"────────────────────────────────────────────────────────────────────────────────\n" "────────────────────────────────────────────────────────────────────────────────\n"
) )

@ -398,8 +398,8 @@ def test_arm_stack_pointer_check(qemu_assembly_run):
" 0x200c0 <_start+12> sub r3, r2, #2 R3 => 5 (7 - 2)\n" " 0x200c0 <_start+12> sub r3, r2, #2 R3 => 5 (7 - 2)\n"
f" 0x200c4 <_start+16> str r3, [sp, #-4]! [{hex(pwndbg.aglib.regs.sp - 4)}] <= 5\n" f" 0x200c4 <_start+16> str r3, [sp, #-4]! [{hex(pwndbg.aglib.regs.sp - 4)}] <= 5\n"
" 0x200c8 <_start+20> pop {r4}\n" " 0x200c8 <_start+20> pop {r4}\n"
" 0x200cc <_start+24> mul r4, r2, r1 R4 => 21 (7 * 3)\n" " 0x200cc <_start+24> mul r4, r2, r1 R4 => 0x15 (7 * 3)\n"
" 0x200d0 <_start+28> add r4, r4, #1 R4 => 22 (0x15 + 0x1)\n" " 0x200d0 <_start+28> add r4, r4, #1 R4 => 0x16 (0x15 + 0x1)\n"
" 0x200d4 <end> mov r0, #0 R0 => 0\n" " 0x200d4 <end> mov r0, #0 R0 => 0\n"
" 0x200d8 <end+4> mov r7, #0xf8 R7 => 0xf8\n" " 0x200d8 <end+4> mov r7, #0xf8 R7 => 0xf8\n"
" 0x200dc <end+8> svc #0 <SYS_exit_group>\n" " 0x200dc <end+8> svc #0 <SYS_exit_group>\n"

@ -128,7 +128,7 @@ def test_mips32_bnez_instruction(qemu_assembly_run, arch):
expected_1 = ( expected_1 = (
"LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA\n" "LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA\n"
"───────────────────────[ DISASM / mips / set emulate on ]───────────────────────\n" "───────────────────────[ DISASM / mips / set emulate on ]───────────────────────\n"
" ► 0x20150 <__start> addiu $t0, $zero, 0xa T0 => 10 (0x0 + 0xa)\n" " ► 0x20150 <__start> addiu $t0, $zero, 0xa T0 => 0xa (0x0 + 0xa)\n"
" 0x20154 <__start+4> ✔ bnez $t0, end <end>\n" " 0x20154 <__start+4> ✔ bnez $t0, end <end>\n"
" 0x20158 <__start+8> nop \n" " 0x20158 <__start+8> nop \n"
"\n" "\n"
@ -431,14 +431,14 @@ def test_mips32_binary_operations(qemu_assembly_run, arch):
expected = ( expected = (
"LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA\n" "LEGEND: STACK | HEAP | CODE | DATA | WX | RODATA\n"
"───────────────────────[ DISASM / mips / set emulate on ]───────────────────────\n" "───────────────────────[ DISASM / mips / set emulate on ]───────────────────────\n"
" ► 0x20150 <__start> addiu $t0, $zero, 0xa T0 => 10 (0x0 + 0xa)\n" " ► 0x20150 <__start> addiu $t0, $zero, 0xa T0 => 0xa (0x0 + 0xa)\n"
" 0x20154 <__start+4> addiu $t1, $zero, 0x14 T1 => 20 (0x0 + 0x14)\n" " 0x20154 <__start+4> addiu $t1, $zero, 0x14 T1 => 0x14 (0x0 + 0x14)\n"
" 0x20158 <__start+8> add $t2, $t0, $t1 T2 => 30 (0xa + 0x14)\n" " 0x20158 <__start+8> add $t2, $t0, $t1 T2 => 0x1e (0xa + 0x14)\n"
" 0x2015c <__start+12> sub $t3, $t1, $t0 T3 => 10 (0x14 - 0xa)\n" " 0x2015c <__start+12> sub $t3, $t1, $t0 T3 => 0xa (0x14 - 0xa)\n"
" 0x20160 <__start+16> and $t4, $t0, $t1 T4 => 0 (0xa & 0x14)\n" " 0x20160 <__start+16> and $t4, $t0, $t1 T4 => 0 (0xa & 0x14)\n"
" 0x20164 <__start+20> or $t5, $t0, $t1 T5 => 30 (0xa | 0x14)\n" " 0x20164 <__start+20> or $t5, $t0, $t1 T5 => 0x1e (0xa | 0x14)\n"
" 0x20168 <__start+24> xor $t6, $t0, $t1 T6 => 30 (0xa ^ 0x14)\n" " 0x20168 <__start+24> xor $t6, $t0, $t1 T6 => 0x1e (0xa ^ 0x14)\n"
" 0x2016c <__start+28> sll $t7, $t0, 2 T7 => 40 (0xa << 0x2)\n" " 0x2016c <__start+28> sll $t7, $t0, 2 T7 => 0x28 (0xa << 0x2)\n"
" 0x20170 <__start+32> srl $t8, $t1, 2 T8 => 5 (0x14 >> 0x2)\n" " 0x20170 <__start+32> srl $t8, $t1, 2 T8 => 5 (0x14 >> 0x2)\n"
" 0x20174 <__start+36> sllv $t8, $t1, $t8 T8 => 0x280 (0x14 << 0x5)\n" " 0x20174 <__start+36> sllv $t8, $t1, $t8 T8 => 0x280 (0x14 << 0x5)\n"
" 0x20178 <__start+40> srlv $t3, $t8, $t5 T3 => 0 (0x280 >> 0x1e)\n" " 0x20178 <__start+40> srlv $t3, $t8, $t5 T3 => 0 (0x280 >> 0x1e)\n"
@ -489,7 +489,7 @@ def test_mips32_multiple_branches_followed(qemu_assembly_run, arch):
" 0x20154 <__start+4> ✔ beq $t1, $t0, first <first>\n" " 0x20154 <__start+4> ✔ beq $t1, $t0, first <first>\n"
" 0x20158 <__start+8> nop \n" " 0x20158 <__start+8> nop \n"
"\n" "\n"
" 0x20164 <first> addiu $t0, $zero, 0xa T0 => 10 (0x0 + 0xa)\n" " 0x20164 <first> addiu $t0, $zero, 0xa T0 => 0xa (0x0 + 0xa)\n"
" 0x20168 <first+4> ✔ bnez $t0, second <second>\n" " 0x20168 <first+4> ✔ bnez $t0, second <second>\n"
" 0x2016c <first+8> nop \n" " 0x2016c <first+8> nop \n"
"\n" "\n"

@ -191,10 +191,10 @@ def test_riscv64_compressed_loads(qemu_assembly_run):
" ► 0x10011b8 <store> c.sd a0, 0(a2) [data] <= 0x1234567890abcdef\n" " ► 0x10011b8 <store> c.sd a0, 0(a2) [data] <= 0x1234567890abcdef\n"
" 0x10011ba <store+2> c.ld a1, 0(a2) A1, [data] => 0x1234567890abcdef\n" " 0x10011ba <store+2> c.ld a1, 0(a2) A1, [data] => 0x1234567890abcdef\n"
" 0x10011bc <store+4> c.li a1, 0x10 A1 => 0x10\n" " 0x10011bc <store+4> c.li a1, 0x10 A1 => 0x10\n"
" 0x10011be <store+6> addi a2, zero, 0x26 A2 => 38 (0x0 + 0x26)\n" " 0x10011be <store+6> addi a2, zero, 0x26 A2 => 0x26 (0x0 + 0x26)\n"
" 0x10011c2 <store+10> add a4, a1, a2 A4 => 54 (0x10 + 0x26)\n" " 0x10011c2 <store+10> add a4, a1, a2 A4 => 0x36 (0x10 + 0x26)\n"
" 0x10011c6 <store+14> sub a5, a1, a3 A5 => 16 (0x10 - 0x0)\n" " 0x10011c6 <store+14> sub a5, a1, a3 A5 => 0x10 (0x10 - 0x0)\n"
" 0x10011ca <store+18> xor a6, a1, a2 A6 => 54 (0x10 ^ 0x26)\n" " 0x10011ca <store+18> xor a6, a1, a2 A6 => 0x36 (0x10 ^ 0x26)\n"
" 0x10011ce <store+22> and a7, a1, a2 A7 => 0 (0x10 & 0x26)\n" " 0x10011ce <store+22> and a7, a1, a2 A7 => 0 (0x10 & 0x26)\n"
" 0x10011d2 <store+26> sll a3, a1, a2 A3 => 0x40000000000 (0x10 << 0x26)\n" " 0x10011d2 <store+26> sll a3, a1, a2 A3 => 0x40000000000 (0x10 << 0x26)\n"
" 0x10011d6 <store+30> mul a2, a1, a2 A2 => 0x260 (0x10 * 0x26)\n" " 0x10011d6 <store+30> mul a2, a1, a2 A2 => 0x260 (0x10 * 0x26)\n"
@ -271,7 +271,7 @@ def test_riscv64_jumps(qemu_assembly_run):
" 0x1001174 <fourth> ✔ blt t5, t0, 6 <end>\n" " 0x1001174 <fourth> ✔ blt t5, t0, 6 <end>\n"
"\n" "\n"
" 0x100117a <end> c.li a2, 0x1e A2 => 0x1e\n" " 0x100117a <end> c.li a2, 0x1e A2 => 0x1e\n"
" 0x100117c <end+2> addi a7, zero, 0x5d A7 => 93 (0x0 + 0x5d)\n" " 0x100117c <end+2> addi a7, zero, 0x5d A7 => 0x5d (0x0 + 0x5d)\n"
"────────────────────────────────────────────────────────────────────────────────\n" "────────────────────────────────────────────────────────────────────────────────\n"
) )
@ -301,7 +301,7 @@ def test_riscv64_jumps(qemu_assembly_run):
" 0x1001174 <fourth> ✔ blt t5, t0, 6 <end>\n" " 0x1001174 <fourth> ✔ blt t5, t0, 6 <end>\n"
"\n" "\n"
" 0x100117a <end> c.li a2, 0x1e A2 => 0x1e\n" " 0x100117a <end> c.li a2, 0x1e A2 => 0x1e\n"
" 0x100117c <end+2> addi a7, zero, 0x5d A7 => 93 (0x0 + 0x5d)\n" " 0x100117c <end+2> addi a7, zero, 0x5d A7 => 0x5d (0x0 + 0x5d)\n"
" 0x1001180 <end+6> c.li a0, 0 A0 => 0\n" " 0x1001180 <end+6> c.li a0, 0 A0 => 0\n"
"────────────────────────────────────────────────────────────────────────────────\n" "────────────────────────────────────────────────────────────────────────────────\n"
) )
@ -361,7 +361,7 @@ def test_riscv64_jump_chain(qemu_assembly_run):
" 0x1001162 <e> c.j 2 <end>\n" " 0x1001162 <e> c.j 2 <end>\n"
"\n" "\n"
" 0x1001164 <end> c.li a2, 0x1e A2 => 0x1e\n" " 0x1001164 <end> c.li a2, 0x1e A2 => 0x1e\n"
" 0x1001166 <end+2> addi a7, zero, 0x5d A7 => 93 (0x0 + 0x5d)\n" " 0x1001166 <end+2> addi a7, zero, 0x5d A7 => 0x5d (0x0 + 0x5d)\n"
" 0x100116a <end+6> c.li a0, 0 A0 => 0\n" " 0x100116a <end+6> c.li a0, 0 A0 => 0\n"
" 0x100116c <end+8> ecall <SYS_exit>\n" " 0x100116c <end+8> ecall <SYS_exit>\n"
" 0x1001170 c.li s0, 0x10 S0 => 0x10\n" " 0x1001170 c.li s0, 0x10 S0 => 0x10\n"

Loading…
Cancel
Save