mirror of https://github.com/pwndbg/pwndbg
Fix disable_colors formatting & test ctx disasm showing fds
This commit adds a test for context disasm showing of file descriptors file paths in syscalls like read() or close(). It also fixes a small issue when Pwndbg is run with PWNDBG_DISABLE_COLORS=1 This issue was that executing: ``` pi '{a:2}'.format(a=pwndbg.color.context.prefix(pwndbg.config.code_prefix)) ``` Failed when Pwndbg was run with disabled colors. It failed because our generate color functions in pwndbg/color/* ended up not processing the input argument -- which here is a Pwndbg config Paramater object -- so that we got a very non obvious exception: ``` Exception occurred: context: unsupported format string passed to Parameter.__format__ (<class 'TypeError'>) ``` This issue could hypothetically also exist if our config value would be empty I think. So with the fix in this commit, where we do str(x) over the color funciton argument should fix this issue in all cases.
This commit is contained in:
parent
21794a6ec4
commit
b209ada229
|
@ -131,7 +131,12 @@ def generateColorFunctionInner(old, new):
|
||||||
|
|
||||||
|
|
||||||
def generateColorFunction(config):
|
def generateColorFunction(config):
|
||||||
function = lambda x: x
|
# the `x` here may be a config Parameter object
|
||||||
|
# and if we run with disable_colors or if the config value
|
||||||
|
# is empty, we need to ensure we cast it to string
|
||||||
|
# so it can be properly formatted e.g. with:
|
||||||
|
# "{config_param:5}".format(config_param=some_config_parameter)
|
||||||
|
function = lambda x: str(x)
|
||||||
|
|
||||||
if disable_colors:
|
if disable_colors:
|
||||||
return function
|
return function
|
||||||
|
|
|
@ -655,7 +655,7 @@ def get_filename_and_formatted_source():
|
||||||
source = source[start:end]
|
source = source[start:end]
|
||||||
|
|
||||||
# Compute the prefix_sign length
|
# Compute the prefix_sign length
|
||||||
prefix_sign = pwndbg.config.code_prefix
|
prefix_sign = C.prefix(str(pwndbg.config.code_prefix))
|
||||||
prefix_width = len(prefix_sign)
|
prefix_width = len(prefix_sign)
|
||||||
|
|
||||||
# Format the output
|
# Format the output
|
||||||
|
@ -666,7 +666,7 @@ def get_filename_and_formatted_source():
|
||||||
fmt = C.highlight(fmt)
|
fmt = C.highlight(fmt)
|
||||||
|
|
||||||
line = fmt.format(
|
line = fmt.format(
|
||||||
prefix_sign=C.prefix(prefix_sign) if line_number == closest_line else "",
|
prefix_sign=prefix_sign if line_number == closest_line else "",
|
||||||
prefix_width=prefix_width,
|
prefix_width=prefix_width,
|
||||||
line_number=line_number,
|
line_number=line_number,
|
||||||
num_width=num_width,
|
num_width=num_width,
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
char buf[16] = {0};
|
||||||
|
|
||||||
|
// read 0 bytes so it won't block
|
||||||
|
read(STDOUT_FILENO, buf, 0);
|
||||||
|
|
||||||
|
int fd = open(argv[0], 0);
|
||||||
|
|
||||||
|
read(fd, buf, sizeof(buf));
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
import re
|
||||||
|
|
||||||
|
import gdb
|
||||||
|
|
||||||
|
import pwndbg.commands
|
||||||
|
import tests
|
||||||
|
|
||||||
|
USE_FDS_BINARY = tests.binaries.get("use-fds.out")
|
||||||
|
|
||||||
|
|
||||||
|
def test_context_disasm_show_fd_filepath(start_binary):
|
||||||
|
"""
|
||||||
|
Tests context disasm command and whether it shows properly opened fd filepath
|
||||||
|
"""
|
||||||
|
start_binary(USE_FDS_BINARY)
|
||||||
|
|
||||||
|
# Run until main
|
||||||
|
gdb.execute("break main")
|
||||||
|
gdb.execute("continue")
|
||||||
|
|
||||||
|
# Stop on read(0, ...) -> should show /dev/pts/X
|
||||||
|
gdb.execute("nextcall")
|
||||||
|
|
||||||
|
out = pwndbg.commands.context.context_disasm()
|
||||||
|
assert "[ DISASM / x86-64 / set emulate on ]" in out[0] # Sanity check
|
||||||
|
|
||||||
|
call_read_line_idx = out.index(next(line for line in out if "<read@plt>" in line))
|
||||||
|
lines_after_call_read = out[call_read_line_idx:]
|
||||||
|
|
||||||
|
line_call_read, line_fd, line_buf, line_nbytes, *_rest = lines_after_call_read
|
||||||
|
|
||||||
|
assert "call read@plt" in line_call_read
|
||||||
|
|
||||||
|
line_fd = line_fd.strip()
|
||||||
|
assert re.match(r"fd:\s+0x1 \(/dev/pts/\d+\)", line_fd)
|
||||||
|
|
||||||
|
line_buf = line_buf.strip()
|
||||||
|
assert re.match(r"buf:\s+0x[0-9a-f]+ ◂— 0x0", line_buf)
|
||||||
|
|
||||||
|
line_nbytes = line_nbytes.strip()
|
||||||
|
assert re.match(r"nbytes:\s+0x0", line_nbytes)
|
||||||
|
|
||||||
|
# Stop on open(...)
|
||||||
|
gdb.execute("nextcall")
|
||||||
|
# Stop on read(...) -> should show use-fds.out
|
||||||
|
gdb.execute("nextcall")
|
||||||
|
|
||||||
|
out = pwndbg.commands.context.context_disasm()
|
||||||
|
assert "[ DISASM / x86-64 / set emulate on ]" in out[0] # Sanity check
|
||||||
|
|
||||||
|
call_read_line_idx = out.index(next(line for line in out if "<read@plt>" in line))
|
||||||
|
lines_after_call_read = out[call_read_line_idx:]
|
||||||
|
|
||||||
|
line_call_read, line_fd, line_buf, line_nbytes, *_rest = lines_after_call_read
|
||||||
|
|
||||||
|
line_fd = line_fd.strip()
|
||||||
|
assert re.match(r"fd:\s+0x3 \([a-z/]*pwndbg/tests/binaries/use-fds.out\)", line_fd)
|
||||||
|
|
||||||
|
line_buf = line_buf.strip()
|
||||||
|
assert re.match(r"buf:\s+0x[0-9a-f]+ ◂— 0x0", line_buf)
|
||||||
|
|
||||||
|
line_nbytes = line_nbytes.strip()
|
||||||
|
assert re.match(r"nbytes:\s+0x10", line_nbytes)
|
Loading…
Reference in New Issue