mirror of https://github.com/pwndbg/pwndbg
fix errno command (#1112)
* fix errno command * fix isort * try to fix CI * Update test_command_errno.py
This commit is contained in:
parent
9755a40d7b
commit
42f32d7cc7
|
@ -339,7 +339,7 @@ class _ArgparsedCommand(Command):
|
||||||
class ArgparsedCommand:
|
class ArgparsedCommand:
|
||||||
"""Adds documentation and offloads parsing for a Command via argparse"""
|
"""Adds documentation and offloads parsing for a Command via argparse"""
|
||||||
|
|
||||||
def __init__(self, parser_or_desc, aliases=[]):
|
def __init__(self, parser_or_desc, aliases=[], command_name=None):
|
||||||
"""
|
"""
|
||||||
:param parser_or_desc: `argparse.ArgumentParser` instance or `str`
|
:param parser_or_desc: `argparse.ArgumentParser` instance or `str`
|
||||||
"""
|
"""
|
||||||
|
@ -348,6 +348,8 @@ class ArgparsedCommand:
|
||||||
else:
|
else:
|
||||||
self.parser = parser_or_desc
|
self.parser = parser_or_desc
|
||||||
self.aliases = aliases
|
self.aliases = aliases
|
||||||
|
self._command_name = command_name
|
||||||
|
|
||||||
# We want to run all integer and otherwise-unspecified arguments
|
# We want to run all integer and otherwise-unspecified arguments
|
||||||
# through fix() so that GDB parses it.
|
# through fix() so that GDB parses it.
|
||||||
for action in self.parser._actions:
|
for action in self.parser._actions:
|
||||||
|
@ -360,8 +362,8 @@ class ArgparsedCommand:
|
||||||
|
|
||||||
def __call__(self, function):
|
def __call__(self, function):
|
||||||
for alias in self.aliases:
|
for alias in self.aliases:
|
||||||
_ArgparsedCommand(self.parser, function, alias)
|
_ArgparsedCommand(self.parser, function, command_name=alias)
|
||||||
return _ArgparsedCommand(self.parser, function)
|
return _ArgparsedCommand(self.parser, function, command_name=self._command_name)
|
||||||
|
|
||||||
|
|
||||||
# We use a 64-bit max value literal here instead of pwndbg.arch.current
|
# We use a 64-bit max value literal here instead of pwndbg.arch.current
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import argparse
|
import argparse
|
||||||
import errno as _errno
|
import errno
|
||||||
|
|
||||||
|
import gdb
|
||||||
|
|
||||||
import pwndbg as _pwndbg
|
|
||||||
import pwndbg.arch as _arch
|
|
||||||
import pwndbg.auxv
|
import pwndbg.auxv
|
||||||
import pwndbg.commands
|
import pwndbg.commands
|
||||||
import pwndbg.regs
|
import pwndbg.regs
|
||||||
import pwndbg.symbol
|
import pwndbg.symbol
|
||||||
|
|
||||||
_errno.errorcode[0] = "OK"
|
errno.errorcode[0] = "OK"
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="""
|
description="""
|
||||||
|
@ -24,24 +24,25 @@ parser.add_argument(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@_pwndbg.commands.ArgparsedCommand(parser)
|
@pwndbg.commands.ArgparsedCommand(parser, command_name="errno")
|
||||||
@pwndbg.commands.OnlyWhenRunning
|
@pwndbg.commands.OnlyWhenRunning
|
||||||
def errno(err):
|
def errno_(err):
|
||||||
if err is None:
|
if err is None:
|
||||||
# Dont ask.
|
# Try to get the `errno` variable value
|
||||||
errno_location = pwndbg.symbol.get("__errno_location")
|
# if it does not exist, get the errno variable from its location
|
||||||
err = pwndbg.memory.int(errno_location)
|
try:
|
||||||
# err = int(gdb.parse_and_eval('*((int *(*) (void)) __errno_location) ()'))
|
err = int(gdb.parse_and_eval("errno"))
|
||||||
|
except gdb.error:
|
||||||
|
try:
|
||||||
|
err = int(gdb.parse_and_eval("*((int *(*) (void)) __errno_location) ()"))
|
||||||
|
except gdb.error:
|
||||||
|
print(
|
||||||
|
"Could not determine error code automatically: neither `errno` nor `__errno_location` symbols were provided (was libc.so loaded already?)"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
err = abs(int(err))
|
msg = errno.errorcode.get(int(err), "Unknown error code")
|
||||||
|
print("Errno %s: %s" % (err, msg))
|
||||||
if err >> 63:
|
|
||||||
err -= 1 << 64
|
|
||||||
elif err >> 31:
|
|
||||||
err -= 1 << 32
|
|
||||||
|
|
||||||
msg = _errno.errorcode.get(int(err), "Unknown error code")
|
|
||||||
print("Errno %i: %s" % (err, msg))
|
|
||||||
|
|
||||||
|
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
|
@ -58,8 +59,8 @@ parser.add_argument(
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@_pwndbg.commands.ArgparsedCommand(parser)
|
@pwndbg.commands.ArgparsedCommand(parser, command_name="pwndbg")
|
||||||
def pwndbg(filter_pattern):
|
def pwndbg_(filter_pattern):
|
||||||
for name, docs in list_and_filter_commands(filter_pattern):
|
for name, docs in list_and_filter_commands(filter_pattern):
|
||||||
print("%-20s %s" % (name, docs))
|
print("%-20s %s" % (name, docs))
|
||||||
|
|
||||||
|
@ -69,19 +70,19 @@ parser.add_argument("a", type=int, help="The first address.")
|
||||||
parser.add_argument("b", type=int, help="The second address.")
|
parser.add_argument("b", type=int, help="The second address.")
|
||||||
|
|
||||||
|
|
||||||
@_pwndbg.commands.ArgparsedCommand(parser)
|
@pwndbg.commands.ArgparsedCommand(parser)
|
||||||
def distance(a, b):
|
def distance(a, b):
|
||||||
"""Print the distance between the two arguments"""
|
"""Print the distance between the two arguments"""
|
||||||
a = int(a) & _arch.ptrmask
|
a = int(a) & pwndbg.arch.ptrmask
|
||||||
b = int(b) & _arch.ptrmask
|
b = int(b) & pwndbg.arch.ptrmask
|
||||||
|
|
||||||
distance = b - a
|
distance = b - a
|
||||||
|
|
||||||
print("%#x->%#x is %#x bytes (%#x words)" % (a, b, distance, distance // _arch.ptrsize))
|
print("%#x->%#x is %#x bytes (%#x words)" % (a, b, distance, distance // pwndbg.arch.ptrsize))
|
||||||
|
|
||||||
|
|
||||||
def list_and_filter_commands(filter_str):
|
def list_and_filter_commands(filter_str):
|
||||||
sorted_commands = list(_pwndbg.commands.commands)
|
sorted_commands = list(pwndbg.commands.commands)
|
||||||
sorted_commands.sort(key=lambda x: x.__name__)
|
sorted_commands.sort(key=lambda x: x.__name__)
|
||||||
|
|
||||||
if filter_str:
|
if filter_str:
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
import gdb
|
||||||
|
|
||||||
|
import pwndbg
|
||||||
|
import pwndbg.memory
|
||||||
|
import pwndbg.regs
|
||||||
|
import tests
|
||||||
|
|
||||||
|
# We use the heap_vis binary as it enforces pthreads and so will have TLS on all distros
|
||||||
|
REFERENCE_BINARY = tests.binaries.get("heap_vis.out")
|
||||||
|
|
||||||
|
|
||||||
|
def test_command_errno(start_binary):
|
||||||
|
"""
|
||||||
|
Tests the errno command display
|
||||||
|
"""
|
||||||
|
start_binary(REFERENCE_BINARY)
|
||||||
|
|
||||||
|
# Since start_binary does 'starti' which stops on the very first instruction
|
||||||
|
# the errno is not yet an available symbol, because the libc library it is
|
||||||
|
# defined in is not yet loaded
|
||||||
|
result = "".join(gdb.execute("errno", to_string=True).splitlines())
|
||||||
|
assert (
|
||||||
|
result
|
||||||
|
== "Could not determine error code automatically: neither `errno` nor `__errno_location` symbols were provided (was libc.so loaded already?)"
|
||||||
|
)
|
||||||
|
|
||||||
|
gdb.execute("break main")
|
||||||
|
gdb.execute("continue")
|
||||||
|
|
||||||
|
result = gdb.execute("errno", to_string=True)
|
||||||
|
assert result == "Errno 0: OK\n"
|
||||||
|
|
||||||
|
gdb.execute("set *(int*)&errno=11")
|
||||||
|
result = gdb.execute("errno", to_string=True)
|
||||||
|
assert result == "Errno 11: EAGAIN\n"
|
||||||
|
|
||||||
|
gdb.execute("set *(int*)&errno=111")
|
||||||
|
result = gdb.execute("errno", to_string=True)
|
||||||
|
assert result == "Errno 111: ECONNREFUSED\n"
|
||||||
|
|
||||||
|
result = gdb.execute("errno 8", to_string=True)
|
||||||
|
assert result == "Errno 8: ENOEXEC\n"
|
||||||
|
|
||||||
|
result = gdb.execute("errno 123", to_string=True)
|
||||||
|
assert result == "Errno 123: ENOMEDIUM\n"
|
||||||
|
|
||||||
|
result = gdb.execute("errno 250", to_string=True)
|
||||||
|
assert result == "Errno 250: Unknown error code\n"
|
Loading…
Reference in New Issue