mirror of https://github.com/pwndbg/pwndbg
GDB Refactor [4/N]: Split abi into lib/ and gdblib/ (#1120)
* Remove tips.py * Split android.py into lib/ and gdb/ * Split abi.py into lib/ and gdblib/
This commit is contained in:
parent
36aa539f62
commit
692c4b82f6
|
@ -6,7 +6,6 @@ import gdb
|
||||||
from capstone import CS_GRP_CALL
|
from capstone import CS_GRP_CALL
|
||||||
from capstone import CS_GRP_INT
|
from capstone import CS_GRP_INT
|
||||||
|
|
||||||
import pwndbg.abi
|
|
||||||
import pwndbg.chain
|
import pwndbg.chain
|
||||||
import pwndbg.color.nearpc as N
|
import pwndbg.color.nearpc as N
|
||||||
import pwndbg.constants
|
import pwndbg.constants
|
||||||
|
@ -14,6 +13,7 @@ import pwndbg.disasm
|
||||||
import pwndbg.gdblib.arch
|
import pwndbg.gdblib.arch
|
||||||
import pwndbg.gdblib.typeinfo
|
import pwndbg.gdblib.typeinfo
|
||||||
import pwndbg.ida
|
import pwndbg.ida
|
||||||
|
import pwndbg.lib.abi
|
||||||
import pwndbg.lib.funcparser
|
import pwndbg.lib.funcparser
|
||||||
import pwndbg.lib.functions
|
import pwndbg.lib.functions
|
||||||
import pwndbg.memory
|
import pwndbg.memory
|
||||||
|
@ -52,7 +52,7 @@ def get_syscall_name(instruction):
|
||||||
if CS_GRP_INT not in instruction.groups:
|
if CS_GRP_INT not in instruction.groups:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
syscall_register = pwndbg.abi.ABI.syscall().syscall_register
|
syscall_register = pwndbg.lib.abi.ABI.syscall().syscall_register
|
||||||
|
|
||||||
# If we are on x86/x64, return no syscall name for other instructions than syscall and int 0x80
|
# If we are on x86/x64, return no syscall name for other instructions than syscall and int 0x80
|
||||||
if syscall_register in ("eax", "rax"):
|
if syscall_register in ("eax", "rax"):
|
||||||
|
@ -81,7 +81,7 @@ def get(instruction):
|
||||||
|
|
||||||
if CS_GRP_CALL in instruction.groups:
|
if CS_GRP_CALL in instruction.groups:
|
||||||
try:
|
try:
|
||||||
abi = pwndbg.abi.ABI.default()
|
abi = pwndbg.lib.abi.ABI.default()
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ def get(instruction):
|
||||||
elif CS_GRP_INT in instruction.groups:
|
elif CS_GRP_INT in instruction.groups:
|
||||||
# Get the syscall number and name
|
# Get the syscall number and name
|
||||||
name = get_syscall_name(instruction)
|
name = get_syscall_name(instruction)
|
||||||
abi = pwndbg.abi.ABI.syscall()
|
abi = pwndbg.lib.abi.ABI.syscall()
|
||||||
target = None
|
target = None
|
||||||
|
|
||||||
if name is None:
|
if name is None:
|
||||||
|
@ -162,7 +162,7 @@ def get(instruction):
|
||||||
|
|
||||||
|
|
||||||
def argname(n, abi=None):
|
def argname(n, abi=None):
|
||||||
abi = abi or pwndbg.abi.ABI.default()
|
abi = abi or pwndbg.lib.abi.ABI.default()
|
||||||
regs = abi.register_arguments
|
regs = abi.register_arguments
|
||||||
|
|
||||||
if n < len(regs):
|
if n < len(regs):
|
||||||
|
@ -177,7 +177,7 @@ def argument(n, abi=None):
|
||||||
instruction.
|
instruction.
|
||||||
Works only for ABIs that use registers for arguments.
|
Works only for ABIs that use registers for arguments.
|
||||||
"""
|
"""
|
||||||
abi = abi or pwndbg.abi.ABI.default()
|
abi = abi or pwndbg.lib.abi.ABI.default()
|
||||||
regs = abi.register_arguments
|
regs = abi.register_arguments
|
||||||
|
|
||||||
if n < len(regs):
|
if n < len(regs):
|
||||||
|
@ -195,7 +195,7 @@ def arguments(abi=None):
|
||||||
Yields (arg_name, arg_value) tuples for arguments from a given ABI.
|
Yields (arg_name, arg_value) tuples for arguments from a given ABI.
|
||||||
Works only for ABIs that use registers for arguments.
|
Works only for ABIs that use registers for arguments.
|
||||||
"""
|
"""
|
||||||
abi = abi or pwndbg.abi.ABI.default()
|
abi = abi or pwndbg.lib.abi.ABI.default()
|
||||||
regs = abi.register_arguments
|
regs = abi.register_arguments
|
||||||
|
|
||||||
for i in range(len(regs)):
|
for i in range(len(regs)):
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import gdb
|
import gdb
|
||||||
|
|
||||||
import pwndbg.abi
|
|
||||||
import pwndbg.gdblib.arch
|
import pwndbg.gdblib.arch
|
||||||
import pwndbg.gdblib.events
|
import pwndbg.gdblib.events
|
||||||
|
import pwndbg.lib.abi
|
||||||
import pwndbg.memory
|
import pwndbg.memory
|
||||||
import pwndbg.regs
|
import pwndbg.regs
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ envc = None
|
||||||
|
|
||||||
|
|
||||||
@pwndbg.gdblib.events.start
|
@pwndbg.gdblib.events.start
|
||||||
@pwndbg.abi.LinuxOnly()
|
@pwndbg.gdblib.abi.LinuxOnly()
|
||||||
def update():
|
def update():
|
||||||
global argc
|
global argc
|
||||||
global argv
|
global argv
|
||||||
|
|
|
@ -4,7 +4,7 @@ import sys
|
||||||
|
|
||||||
import gdb
|
import gdb
|
||||||
|
|
||||||
import pwndbg.abi
|
import pwndbg.gdblib.abi
|
||||||
import pwndbg.gdblib.arch
|
import pwndbg.gdblib.arch
|
||||||
import pwndbg.gdblib.events
|
import pwndbg.gdblib.events
|
||||||
import pwndbg.gdblib.typeinfo
|
import pwndbg.gdblib.typeinfo
|
||||||
|
@ -146,7 +146,7 @@ def find_stack_boundary(addr):
|
||||||
|
|
||||||
|
|
||||||
def walk_stack():
|
def walk_stack():
|
||||||
if not pwndbg.abi.linux:
|
if not pwndbg.gdblib.abi.linux:
|
||||||
return None
|
return None
|
||||||
if pwndbg.qemu.is_qemu_kernel():
|
if pwndbg.qemu.is_qemu_kernel():
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import gdb
|
import gdb
|
||||||
|
|
||||||
import pwndbg.abi
|
|
||||||
import pwndbg.color.chain as C
|
import pwndbg.color.chain as C
|
||||||
import pwndbg.color.memory as M
|
import pwndbg.color.memory as M
|
||||||
import pwndbg.color.theme as theme
|
import pwndbg.color.theme as theme
|
||||||
import pwndbg.enhance
|
import pwndbg.enhance
|
||||||
|
import pwndbg.gdblib.abi
|
||||||
import pwndbg.gdblib.typeinfo
|
import pwndbg.gdblib.typeinfo
|
||||||
import pwndbg.memory
|
import pwndbg.memory
|
||||||
import pwndbg.symbol
|
import pwndbg.symbol
|
||||||
|
@ -56,7 +56,7 @@ def get(
|
||||||
|
|
||||||
# Avoid redundant dereferences in bare metal mode by checking
|
# Avoid redundant dereferences in bare metal mode by checking
|
||||||
# if address is in any of vmmap pages
|
# if address is in any of vmmap pages
|
||||||
if not pwndbg.abi.linux and not pwndbg.vmmap.find(address):
|
if not pwndbg.gdblib.abi.linux and not pwndbg.vmmap.find(address):
|
||||||
break
|
break
|
||||||
|
|
||||||
next_address = int(pwndbg.memory.poi(pwndbg.gdblib.typeinfo.ppvoid, address))
|
next_address = int(pwndbg.memory.poi(pwndbg.gdblib.typeinfo.ppvoid, address))
|
||||||
|
|
|
@ -15,9 +15,9 @@ import gdb
|
||||||
from elftools.elf.constants import SH_FLAGS
|
from elftools.elf.constants import SH_FLAGS
|
||||||
from elftools.elf.elffile import ELFFile
|
from elftools.elf.elffile import ELFFile
|
||||||
|
|
||||||
import pwndbg.abi
|
|
||||||
import pwndbg.auxv
|
import pwndbg.auxv
|
||||||
import pwndbg.elftypes
|
import pwndbg.elftypes
|
||||||
|
import pwndbg.gdblib.abi
|
||||||
import pwndbg.gdblib.arch
|
import pwndbg.gdblib.arch
|
||||||
import pwndbg.gdblib.events
|
import pwndbg.gdblib.events
|
||||||
import pwndbg.info
|
import pwndbg.info
|
||||||
|
@ -266,7 +266,7 @@ def get_ehdr(pointer):
|
||||||
|
|
||||||
if base is None:
|
if base is None:
|
||||||
# For non linux ABI, the ELF header may not exist at all
|
# For non linux ABI, the ELF header may not exist at all
|
||||||
if pwndbg.abi.linux:
|
if pwndbg.gdblib.abi.linux:
|
||||||
print("ERROR: Could not find ELF base!")
|
print("ERROR: Could not find ELF base!")
|
||||||
return None, None
|
return None, None
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
import functools
|
||||||
|
|
||||||
|
import gdb
|
||||||
|
|
||||||
|
import pwndbg.color.message as M
|
||||||
|
import pwndbg.gdblib.events
|
||||||
|
|
||||||
|
abi = None
|
||||||
|
linux = False
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: Maybe move this to hooks.py?
|
||||||
|
@pwndbg.gdblib.events.start
|
||||||
|
def update():
|
||||||
|
global abi
|
||||||
|
global linux
|
||||||
|
|
||||||
|
# Detect current ABI of client side by 'show osabi'
|
||||||
|
#
|
||||||
|
# Examples of strings returned by `show osabi`:
|
||||||
|
# 'The current OS ABI is "auto" (currently "GNU/Linux").\nThe default OS ABI is "GNU/Linux".\n'
|
||||||
|
# 'The current OS ABI is "GNU/Linux".\nThe default OS ABI is "GNU/Linux".\n'
|
||||||
|
# 'El actual SO ABI es «auto» (actualmente «GNU/Linux»).\nEl SO ABI predeterminado es «GNU/Linux».\n'
|
||||||
|
# 'The current OS ABI is "auto" (currently "none")'
|
||||||
|
#
|
||||||
|
# As you can see, there might be GDBs with different language versions
|
||||||
|
# and so we have to support it there too.
|
||||||
|
# Lets assume and hope that `current osabi` is returned in first line in all languages...
|
||||||
|
abi = gdb.execute("show osabi", to_string=True).split("\n")[0]
|
||||||
|
|
||||||
|
# Currently we support those osabis:
|
||||||
|
# 'GNU/Linux': linux
|
||||||
|
# 'none': bare metal
|
||||||
|
|
||||||
|
linux = "GNU/Linux" in abi
|
||||||
|
|
||||||
|
if not linux:
|
||||||
|
msg = M.warn(
|
||||||
|
"The bare metal debugging is enabled since gdb's osabi is '%s' which is not 'GNU/Linux'.\n"
|
||||||
|
"Ex. the page resolving and memory de-referencing ONLY works on known pages.\n"
|
||||||
|
"This option is based on gdb client compile arguments (by default) and will be corrected if you load an ELF with a '.note.ABI-tag' section.\n"
|
||||||
|
"If you are debugging a program that runs on the Linux ABI, please select the correct gdb client."
|
||||||
|
% abi
|
||||||
|
)
|
||||||
|
print(msg)
|
||||||
|
|
||||||
|
|
||||||
|
def LinuxOnly(default=None):
|
||||||
|
"""Create a decorator that the function will be called when ABI is Linux.
|
||||||
|
Otherwise, return `default`.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def decorator(func):
|
||||||
|
@functools.wraps(func)
|
||||||
|
def caller(*args, **kwargs):
|
||||||
|
if linux:
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
else:
|
||||||
|
return default
|
||||||
|
|
||||||
|
return caller
|
||||||
|
|
||||||
|
return decorator
|
||||||
|
|
||||||
|
|
||||||
|
# Update when starting the gdb to show warning message for non-Linux ABI user.
|
||||||
|
update()
|
|
@ -1,8 +1,3 @@
|
||||||
import functools
|
|
||||||
|
|
||||||
import gdb
|
|
||||||
|
|
||||||
import pwndbg.color.message as M
|
|
||||||
import pwndbg.gdblib.arch
|
import pwndbg.gdblib.arch
|
||||||
|
|
||||||
|
|
||||||
|
@ -114,60 +109,3 @@ linux_arm_sigreturn = SigreturnABI(["r7"], 4, 0)
|
||||||
linux_i386_srop = ABI(["eax"], 4, 0)
|
linux_i386_srop = ABI(["eax"], 4, 0)
|
||||||
linux_amd64_srop = ABI(["rax"], 4, 0)
|
linux_amd64_srop = ABI(["rax"], 4, 0)
|
||||||
linux_arm_srop = ABI(["r7"], 4, 0)
|
linux_arm_srop = ABI(["r7"], 4, 0)
|
||||||
|
|
||||||
|
|
||||||
@pwndbg.gdblib.events.start
|
|
||||||
def update():
|
|
||||||
global abi
|
|
||||||
global linux
|
|
||||||
|
|
||||||
# Detect current ABI of client side by 'show osabi'
|
|
||||||
#
|
|
||||||
# Examples of strings returned by `show osabi`:
|
|
||||||
# 'The current OS ABI is "auto" (currently "GNU/Linux").\nThe default OS ABI is "GNU/Linux".\n'
|
|
||||||
# 'The current OS ABI is "GNU/Linux".\nThe default OS ABI is "GNU/Linux".\n'
|
|
||||||
# 'El actual SO ABI es «auto» (actualmente «GNU/Linux»).\nEl SO ABI predeterminado es «GNU/Linux».\n'
|
|
||||||
# 'The current OS ABI is "auto" (currently "none")'
|
|
||||||
#
|
|
||||||
# As you can see, there might be GDBs with different language versions
|
|
||||||
# and so we have to support it there too.
|
|
||||||
# Lets assume and hope that `current osabi` is returned in first line in all languages...
|
|
||||||
abi = gdb.execute("show osabi", to_string=True).split("\n")[0]
|
|
||||||
|
|
||||||
# Currently we support those osabis:
|
|
||||||
# 'GNU/Linux': linux
|
|
||||||
# 'none': bare metal
|
|
||||||
|
|
||||||
linux = "GNU/Linux" in abi
|
|
||||||
|
|
||||||
if not linux:
|
|
||||||
msg = M.warn(
|
|
||||||
"The bare metal debugging is enabled since gdb's osabi is '%s' which is not 'GNU/Linux'.\n"
|
|
||||||
"Ex. the page resolving and memory de-referencing ONLY works on known pages.\n"
|
|
||||||
"This option is based on gdb client compile arguments (by default) and will be corrected if you load an ELF with a '.note.ABI-tag' section.\n"
|
|
||||||
"If you are debugging a program that runs on the Linux ABI, please select the correct gdb client."
|
|
||||||
% abi
|
|
||||||
)
|
|
||||||
print(msg)
|
|
||||||
|
|
||||||
|
|
||||||
def LinuxOnly(default=None):
|
|
||||||
"""Create a decorator that the function will be called when ABI is Linux.
|
|
||||||
Otherwise, return `default`.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def decorator(func):
|
|
||||||
@functools.wraps(func)
|
|
||||||
def caller(*args, **kwargs):
|
|
||||||
if linux:
|
|
||||||
return func(*args, **kwargs)
|
|
||||||
else:
|
|
||||||
return default
|
|
||||||
|
|
||||||
return caller
|
|
||||||
|
|
||||||
return decorator
|
|
||||||
|
|
||||||
|
|
||||||
# Update when starting the gdb to show warning message for non-Linux ABI user.
|
|
||||||
update()
|
|
|
@ -41,7 +41,7 @@ def find_upper_stack_boundary(stack_ptr, max_pages=1024):
|
||||||
|
|
||||||
# We can't get the stack size from stack layout and page fault on bare metal mode,
|
# We can't get the stack size from stack layout and page fault on bare metal mode,
|
||||||
# so we return current page as a walkaround.
|
# so we return current page as a walkaround.
|
||||||
if not pwndbg.abi.linux:
|
if not pwndbg.gdblib.abi.linux:
|
||||||
return stack_ptr + pwndbg.memory.PAGE_SIZE
|
return stack_ptr + pwndbg.memory.PAGE_SIZE
|
||||||
|
|
||||||
return pwndbg.memory.find_upper_boundary(stack_ptr, max_pages)
|
return pwndbg.memory.find_upper_boundary(stack_ptr, max_pages)
|
||||||
|
|
|
@ -11,9 +11,9 @@ import sys
|
||||||
|
|
||||||
import gdb
|
import gdb
|
||||||
|
|
||||||
import pwndbg.abi
|
|
||||||
import pwndbg.elf
|
import pwndbg.elf
|
||||||
import pwndbg.file
|
import pwndbg.file
|
||||||
|
import pwndbg.gdblib.abi
|
||||||
import pwndbg.gdblib.events
|
import pwndbg.gdblib.events
|
||||||
import pwndbg.gdblib.typeinfo
|
import pwndbg.gdblib.typeinfo
|
||||||
import pwndbg.lib.memoize
|
import pwndbg.lib.memoize
|
||||||
|
@ -107,7 +107,7 @@ def find(address):
|
||||||
return explore(address)
|
return explore(address)
|
||||||
|
|
||||||
|
|
||||||
@pwndbg.abi.LinuxOnly()
|
@pwndbg.gdblib.abi.LinuxOnly()
|
||||||
def explore(address_maybe):
|
def explore(address_maybe):
|
||||||
"""
|
"""
|
||||||
Given a potential address, check to see what permissions it has.
|
Given a potential address, check to see what permissions it has.
|
||||||
|
|
Loading…
Reference in New Issue