Rename module to pwndbg

This commit is contained in:
Zach Riggle 2015-03-09 19:55:33 -07:00
parent 2c844f2dd7
commit 27180e0dfa
46 changed files with 496 additions and 343 deletions

View File

@ -10,4 +10,33 @@ Currently it works on GDB with Python3.
\* Lots of use of `gdb.event` to manage cache lifetimes.
\*\* Automatic exploration of process maps when you're doing e.g. remote debugging
of a QEMU user stub and `/proc/$$/pids` is broken for `${reasons}`.
of a QEMU user stub and `/proc/$$/pids` is broken for `${reasons}`.
Snazzy features which may not work:
### Type Printing
Hurray windbg. This works without any loaded symbols, and is architecture-appropriate.
```
geef> show arch
The target architecture is set automatically (currently i386:x86-64)
geef> dt hostent
hostent
+0x0000 h_name : char *
+0x0008 h_aliases : char **
+0x0010 h_addrtype : int
+0x0014 h_length : int
+0x0018 h_addr_list : char **
geef> dt passwd
passwd
+0x0000 pw_name : char *
+0x0008 pw_passwd : char *
+0x0010 pw_uid : __uid_t
+0x0014 pw_gid : __gid_t
+0x0018 pw_gecos : char *
+0x0020 pw_dir : char *
+0x0028 pw_shell : char *
```

View File

@ -7,5 +7,5 @@ directory = path.abspath(directory)
sys.path.append(directory)
import gef
import pwndbg

View File

@ -1,10 +0,0 @@
import gdb
import gef.vmmap
import gef.commands
import gef.color
import gef.dt
@gef.commands.ParsedCommand
@gef.commands.OnlyWhenRunning
def dt(typename, address=None):
print(gef.dt.dt(typename, addr=address))

View File

@ -1,19 +0,0 @@
import gef.regs
import gef.commands
import gef.memory
import gef.hexdump
@gef.commands.ParsedCommand
@gef.commands.OnlyWhenRunning
def hexdump(address=None, count=64):
"""Hexdumps some data"""
if address is None:
address = gef.regs.sp
int(address)
data = gef.memory.read(address, count)
for line in gef.hexdump.hexdump(data, address=address):
print(line)

View File

@ -1,5 +0,0 @@
import gdb
import gef.commands
@gef.commands.ParsedCommand
@gef.commands.OnlyWhenRunning

View File

@ -1,18 +1,18 @@
import gdb
import gef.arch
import gef.vmmap
import gef.dt
import gef.memory
import gef.elf
import gef.proc
import gef.regs
import gef.stack
import gef.commands
import gef.commands.hexdump
import gef.commands.context
import gef.commands.telescope
import gef.commands.vmmap
import gef.commands.dt
import pwndbg.arch
import pwndbg.vmmap
import pwndbg.dt
import pwndbg.memory
import pwndbg.elf
import pwndbg.proc
import pwndbg.regs
import pwndbg.stack
import pwndbg.commands
import pwndbg.commands.hexdump
import pwndbg.commands.context
import pwndbg.commands.telescope
import pwndbg.commands.vmmap
import pwndbg.commands.dt
pre_commands = """

View File

@ -1,23 +1,23 @@
import struct
import sys
import gdb
import gef.memoize
import gef.events
import gef.types
import pwndbg.memoize
import pwndbg.events
import pwndbg.types
current = None
ptrmask = 0xfffffffff
endian = 'little'
ptrsize = gef.types.ptrsize
ptrsize = pwndbg.types.ptrsize
fmt = '=i'
@gef.events.stop
@pwndbg.events.stop
def update():
m = sys.modules[__name__]
m.current = gdb.selected_frame().architecture().name()
m.ptrsize = gef.types.ptrsize
m.ptrmask = (1 << 8*gef.types.ptrsize)-1
m.ptrsize = pwndbg.types.ptrsize
m.ptrmask = (1 << 8*pwndbg.types.ptrsize)-1
if 'little' in gdb.execute('show endian', to_string=True):
m.endian = 'little'

View File

@ -1,9 +1,9 @@
import gdb
import gef.events
import gef.info
import gef.regs
import gef.types
import pwndbg.events
import pwndbg.info
import pwndbg.regs
import pwndbg.types
example_info_auxv_linux = """
33 AT_SYSINFO_EHDR System-supplied DSO's ELF header 0x7ffff7ffa000
@ -69,7 +69,7 @@ class AUXV(object):
name = AT_CONSTANTS.get(const, "AT_UNKNOWN%i" % const)
if name in ['AT_EXECFN', 'AT_PLATFORM']:
value = gdb.Value(value).cast(gef.types.pchar).string()
value = gdb.Value(value).cast(pwndbg.types.pchar).string()
setattr(self, name, value)
def __str__(self):
@ -80,7 +80,7 @@ class AUXV(object):
rv[attr] = value
return str(rv)
@gef.memoize.reset_on_objfile
@pwndbg.memoize.reset_on_objfile
def get():
return use_info_auxv() or walk_stack() or AUXV()
@ -107,7 +107,7 @@ def use_info_auxv():
0 AT_NULL End of vector 0x0
"""
lines = gef.info.auxv().splitlines()
lines = pwndbg.info.auxv().splitlines()
if not lines:
return None
@ -126,15 +126,15 @@ def use_info_auxv():
def walk_stack():
sp = gef.regs.sp
sp = pwndbg.regs.sp
print("BAD SP")
if not sp:
return None
end = gef.memory.find_upper_boundary(sp)
p = gdb.Value(end).cast(gef.types.ulong.pointer())
end = pwndbg.memory.find_upper_boundary(sp)
p = gdb.Value(end).cast(pwndbg.types.ulong.pointer())
# So we don't walk off the end of the stack
p -= 2

View File

@ -1,9 +1,9 @@
import gdb
import gef.color
import gef.enhance
import gef.memory
import gef.types
import gef.vmmap
import pwndbg.color
import pwndbg.enhance
import pwndbg.memory
import pwndbg.types
import pwndbg.vmmap
def get(address, limit=5):
@ -17,7 +17,7 @@ def get(address, limit=5):
for i in range(limit):
result.append(address)
try:
address = int(gef.memory.poi(gef.types.ppvoid, address))
address = int(pwndbg.memory.poi(pwndbg.types.ppvoid, address))
except gdb.MemoryError:
break
@ -28,9 +28,9 @@ def format(value):
chain = get(value)
# Enhance the last entry
end = [gef.enhance.enhance(chain[-1])]
end = [pwndbg.enhance.enhance(chain[-1])]
# Colorize the rest
rest = list(map(gef.color.get, chain[:-1]))
rest = list(map(pwndbg.color.get, chain[:-1]))
return ' --> '.join(rest + end)

View File

@ -1,5 +1,5 @@
import gdb
import gef.vmmap
import pwndbg.vmmap
NORMAL = "\x1b[0m"
BLACK = "\x1b[30m"
@ -36,7 +36,7 @@ def get(address, text = None):
text(str): Optional text to use in place of the address
in the return value string.
"""
page = gef.vmmap.find(int(address))
page = pwndbg.vmmap.find(int(address))
if page is None: color = NORMAL
elif '[stack' in page.objfile: color = STACK

View File

@ -1,15 +1,15 @@
import traceback
import gdb
import gef.regs
import gef.memory
import gef.hexdump
import gef.color
import gef.chain
import gef.enhance
import gef.symbol
import gef.ui
import gef.proc
import pwndbg.regs
import pwndbg.memory
import pwndbg.hexdump
import pwndbg.color
import pwndbg.chain
import pwndbg.enhance
import pwndbg.symbol
import pwndbg.ui
import pwndbg.proc
debug = True
@ -29,7 +29,7 @@ class ParsedCommand(gdb.Command):
pass
try:
arg = gef.regs.fix(arg)
arg = pwndbg.regs.fix(arg)
argv[i] = gdb.parse_and_eval(arg)
except Exception:
pass
@ -46,7 +46,7 @@ class ParsedCommand(gdb.Command):
def OnlyWhenRunning(func):
def wrapper(*a):
func.__doc__
if not gef.proc.alive:
if not pwndbg.proc.alive:
pass
else:
func(*a)
@ -61,7 +61,7 @@ def searchmem(searchfor):
if isinstance(searchfor, gdb.Value):
try:
searchfor = gef.memory.read(searchfor.address, searchfor.sizeof)
searchfor = pwndbg.memory.read(searchfor.address, searchfor.sizeof)
except:
searchfor = 0
print(searchfor)

View File

@ -1,52 +1,52 @@
import gdb
import gef.commands
import gef.color
import gef.vmmap
import gef.symbol
import gef.regs
import gef.ui
import gef.disasm
import gef.chain
import gef.commands.telescope
import gef.events
import pwndbg.commands
import pwndbg.color
import pwndbg.vmmap
import pwndbg.symbol
import pwndbg.regs
import pwndbg.ui
import pwndbg.disasm
import pwndbg.chain
import pwndbg.commands.telescope
import pwndbg.events
@gef.commands.ParsedCommand
@gef.commands.OnlyWhenRunning
@gef.events.stop
@pwndbg.commands.ParsedCommand
@pwndbg.commands.OnlyWhenRunning
@pwndbg.events.stop
def context(*args):
if len(args) == 0:
args = ['reg','code','stack','backtrace']
args = [a[0] for a in args]
print(gef.color.legend())
print(pwndbg.color.legend())
if 'r' in args: context_regs()
if 'c' in args: context_code()
if 's' in args: context_stack()
if 'b' in args: context_backtrace()
def context_regs():
print(gef.color.blue(gef.ui.banner("registers")))
for reg in gef.regs.gpr + (gef.regs.frame, gef.regs.stack, '$pc'):
print(pwndbg.color.blue(pwndbg.ui.banner("registers")))
for reg in pwndbg.regs.gpr + (pwndbg.regs.frame, pwndbg.regs.stack, '$pc'):
if reg is None:
continue
value = gef.regs[reg]
value = pwndbg.regs[reg]
# Make the register stand out
regname = gef.color.bold(reg.ljust(4).upper())
regname = pwndbg.color.bold(reg.ljust(4).upper())
print("%s %s" % (regname, gef.chain.format(value)))
print("%s %s" % (regname, pwndbg.chain.format(value)))
def context_code():
print(gef.color.blue(gef.ui.banner("code")))
pc = gef.regs.pc
instructions = gef.disasm.near(gef.regs.pc, 5)
print(pwndbg.color.blue(pwndbg.ui.banner("code")))
pc = pwndbg.regs.pc
instructions = pwndbg.disasm.near(pwndbg.regs.pc, 5)
# In case $pc is in a new map we don't know about,
# this will trigger an exploratory search.
gef.vmmap.find(pc)
pwndbg.vmmap.find(pc)
# Ensure screen data is always at the same spot
for i in range(11 - len(instructions)):
@ -55,7 +55,7 @@ def context_code():
# Find all of the symbols for the addresses
symbols = []
for i in instructions:
symbol = gef.symbol.get(i.address)
symbol = pwndbg.symbol.get(i.address)
if symbol:
symbol = '<%s> ' % symbol
symbols.append(symbol)
@ -69,18 +69,18 @@ def context_code():
# Print out each instruction
for i,s in zip(instructions, symbols):
asm = gef.disasm.color(i)
asm = pwndbg.disasm.color(i)
prefix = ' =>' if i.address == pc else ' '
print(prefix, s + hex(i.address), asm)
def context_stack():
print(gef.color.blue(gef.ui.banner("stack")))
gef.commands.telescope.telescope(gef.regs.sp)
print(pwndbg.color.blue(pwndbg.ui.banner("stack")))
pwndbg.commands.telescope.telescope(pwndbg.regs.sp)
def context_backtrace():
print(gef.color.blue(gef.ui.banner("backtrace")))
print(pwndbg.color.blue(pwndbg.ui.banner("backtrace")))
frame = gdb.selected_frame()
for i in range(0,10):
if frame:
print(gef.ui.addrsz(frame.pc()), frame.name() or '???')
print(pwndbg.ui.addrsz(frame.pc()), frame.name() or '???')
frame = frame.older()

10
pwndbg/commands/dt.py Normal file
View File

@ -0,0 +1,10 @@
import gdb
import pwndbg.vmmap
import pwndbg.commands
import pwndbg.color
import pwndbg.dt
@pwndbg.commands.ParsedCommand
@pwndbg.commands.OnlyWhenRunning
def dt(typename, address=None):
print(pwndbg.dt.dt(typename, addr=address))

View File

@ -0,0 +1,19 @@
import pwndbg.regs
import pwndbg.commands
import pwndbg.memory
import pwndbg.hexdump
@pwndbg.commands.ParsedCommand
@pwndbg.commands.OnlyWhenRunning
def hexdump(address=None, count=64):
"""Hexdumps some data"""
if address is None:
address = pwndbg.regs.sp
int(address)
data = pwndbg.memory.read(address, count)
for line in pwndbg.hexdump.hexdump(data, address=address):
print(line)

View File

@ -1,8 +1,8 @@
import gdb
import gef.commands
import pwndbg.commands
@gef.commands.ParsedCommand
@gef.commands.OnlyWhenRunning
@pwndbg.commands.ParsedCommand
@pwndbg.commands.OnlyWhenRunning
def start():
entries = ["main"]

View File

@ -1,25 +1,25 @@
import gef.memory
import gef.regs
import gef.types
import gef.commands
import gef.chain
import pwndbg.memory
import pwndbg.regs
import pwndbg.types
import pwndbg.commands
import pwndbg.chain
@gef.commands.ParsedCommand
@gef.commands.OnlyWhenRunning
@pwndbg.commands.ParsedCommand
@pwndbg.commands.OnlyWhenRunning
def telescope(address=None, count=8):
if address is None:
address = gef.regs.sp
address = pwndbg.regs.sp
if address < 100:
count = address
address = gef.regs.sp
address = pwndbg.regs.sp
address = int(address)
count = int(count)
reg_values = {r:v for (r,v) in gef.regs.items()}
# address = gef.memory.poi(gef.types.ppvoid, address)
ptrsize = gef.types.ptrsize
reg_values = {r:v for (r,v) in pwndbg.regs.items()}
# address = pwndbg.memory.poi(pwndbg.types.ppvoid, address)
ptrsize = pwndbg.types.ptrsize
start = address
stop = address + (count*ptrsize)
@ -41,4 +41,4 @@ def telescope(address=None, count=8):
for i,addr in enumerate(range(start, stop, step)):
print("%02i:%04i|" % (i, addr-start),
regs[addr].ljust(longest_regs),
gef.chain.format(addr))
pwndbg.chain.format(addr))

View File

@ -1,10 +1,10 @@
import gdb
import gef.vmmap
import gef.commands
import gef.color
import pwndbg.vmmap
import pwndbg.commands
import pwndbg.color
@gef.commands.ParsedCommand
@gef.commands.OnlyWhenRunning
@pwndbg.commands.ParsedCommand
@pwndbg.commands.OnlyWhenRunning
def vmmap(map=None):
int_map = None
str_map = None
@ -14,11 +14,11 @@ def vmmap(map=None):
int_map = int(map)
for page in gef.vmmap.get():
for page in pwndbg.vmmap.get():
if str_map and str_map not in page.objfile:
continue
if int_map and int_map not in page:
continue
print(gef.color.get(page.vaddr, text=str(page)))
print(gef.color.legend())
print(pwndbg.color.get(page.vaddr, text=str(page)))
print(pwndbg.color.legend())

View File

@ -0,0 +1,5 @@
import gdb
import pwndbg.commands
@pwndbg.commands.ParsedCommand
@pwndbg.commands.OnlyWhenRunning

View File

@ -1,6 +1,6 @@
import gdb
import collections
import gef.color
import pwndbg.color
Instruction = collections.namedtuple('Instruction', ['address', 'length', 'asm'])
@ -16,7 +16,7 @@ def near(address, instructions=1):
# Find out how far back we can go without having a page fault
distance = instructions * 8
for start in range(address-distance, address):
if gef.memory.peek(start):
if pwndbg.memory.peek(start):
break
# Disassemble more than we expect to need, move forward until we have
@ -72,6 +72,6 @@ branches = set([
def color(ins):
asm = ins.asm
if asm.split()[0] in branches:
asm = gef.color.yellow(asm)
asm = pwndbg.color.yellow(asm)
asm += '\n'
return asm

View File

@ -7,8 +7,8 @@ import re
import subprocess
import tempfile
import gef.memory
import gef.types
import pwndbg.memory
import pwndbg.types
def get_type(v):
t = v.type
@ -79,7 +79,7 @@ def dt(name='', addr=None, obj = None):
# Lookup the type name specified by the user
else:
t = gef.types.load(name)
t = pwndbg.types.load(name)
# If it's not a struct (e.g. int or char*), bail
if t.code not in (gdb.TYPE_CODE_STRUCT, gdb.TYPE_CODE_TYPEDEF):
@ -88,7 +88,7 @@ def dt(name='', addr=None, obj = None):
# If an address was specified, create a Value of the
# specified type at that address.
if addr is not None:
obj = gef.memory.poi(t, addr)
obj = pwndbg.memory.poi(t, addr)
# Header, optionally include the name
header = name
@ -110,8 +110,8 @@ def dt(name='', addr=None, obj = None):
if ftype.code == gdb.TYPE_CODE_INT:
v = hex(int(v))
if ftype.code in (gdb.TYPE_CODE_PTR, gdb.TYPE_CODE_ARRAY) \
and ftype.target() == gef.types.uchar:
data = gef.memory.read(v.address, ftype.sizeof)
and ftype.target() == pwndbg.types.uchar:
data = pwndbg.memory.read(v.address, ftype.sizeof)
v = ' '.join('%02x' % b for b in data)
extra = v

122
pwndbg/dt_backup.txt Normal file
View File

@ -0,0 +1,122 @@
def get_type(v):
t = v.type
while not t.name:
if t.code == gdb.TYPE_CODE_PTR:
t = t.target()
return t.name
def get_typename(t):
n = ''
o = t
p = ''
if t.code == gdb.TYPE_CODE_ARRAY:
t = t.target()
while t.code == gdb.TYPE_CODE_PTR:
t = t.target()
p += '*'
name = t.name
if not p:
return name
return name + ' ' + p
def get_arrsize(f):
t = f.type
if t.code != gdb.TYPE_CODE_ARRAY:
return 0
t2 = t.target()
s = t2.sizeof
return int(t.sizeof / t2.sizeof)
def get_field_by_name(obj, field):
# Dereference once
if obj.type.code == gdb.TYPE_CODE_PTR:
obj = obj.dereference()
for f in re.split('(->|\.|\[\d+\])', field):
if not f: continue
if f == '->':
obj = obj.dereference()
elif f == '.':
pass
elif f.startswith('['):
n = int(f.strip('[]'))
obj = obj.cast(obj.dereference().type.pointer())
obj += n
obj = obj.dereference()
else:
obj = obj[f]
return obj
def happy(typename):
prefix = ''
if 'unsigned' in typename:
prefix = 'u'
typename = typename.replace('unsigned ', '')
return prefix + {
'char': 'char',
'short int': 'short',
'long int': 'long',
'int': 'int',
'long long': 'longlong',
'float': 'float',
'double': 'double'
}[typename]
def dt(name, addr=None, obj = None, field=None):
"""
Dump out a structure type Windbg style.
"""
# Return value is a list of strings.of
# We concatenate at the end.
rv = []
# Lookup the type name specified by the user
t = gdb.lookup_type(name)
# If it's not a struct (e.g. int or char*), bail
if t.code not in (gdb.TYPE_CODE_STRUCT, gdb.TYPE_CODE_TYPEDEF):
raise Exception("Not a structure: %s" % t)
# If an address was specified, create a Value of the
# specified type at that address.
if addr is not None:
obj = gdb.Value(addr).cast(t.pointer()).dereference()
# Header, optionally include the name
header = name
if obj: header = "%s @ %s" (header, str(obj.address))
rv.append(name)
for name, field in t.items():
# Get the actual name of the type, e.g. char***
t = get_typename(field.type.strip_typedefs())
# How many entries are in the array, if any
n = get_arrsize(field) or ''
if n: n = '[%i]' % n
# Offset into the parent structure
o = field.bitpos/8
line = " +0x%04x %-20s" (o, name)
if obj is None:
line ='%s: %s' % (line, str(field.type))
if obj:
# Get the actual field Value out of the object
v = obj[name]
# Strip off whatever typedef crap it has
vt = v.type
if vt.code == gdb.TYPE_CODE_TYPEDEF:
vt = vt.strip_typedefs()
if vt.code == gdb.TYPE_CODE_INT:
v = hex(int(v))
print(" +0x%04x %-20s : %s" % (o, name, v))
rv.append(field)
if obj is None: print("}")

View File

@ -14,12 +14,12 @@ import re
import subprocess
import tempfile
import gef.events
import gef.info
import gef.memory
import gef.memoize
import gef.stack
import gef.auxv
import pwndbg.events
import pwndbg.info
import pwndbg.memory
import pwndbg.memoize
import pwndbg.stack
import pwndbg.auxv
# ELF constants
PF_X, PF_W, PF_R = 1,2,4
@ -33,7 +33,7 @@ ET_EXEC, ET_DYN = 2,3
# since we don't declare any functions, and load the object file at
# address zero.
tempdir = tempfile.gettempdir()
gef_elf = os.path.join(tempdir, 'gef-elf')
gef_elf = os.path.join(tempdir, 'pwndbg-elf')
with open(gef_elf + '.c', 'w+') as f:
f.write('''#include <elf.h>
Elf32_Ehdr a;
@ -45,7 +45,7 @@ Elf64_Phdr f;
subprocess.check_output('gcc -c -g %s.c -o %s.o' % (gef_elf, gef_elf), shell=True)
@gef.memoize.reset_on_exit
@pwndbg.memoize.reset_on_exit
def exe():
"""
Return a loaded ELF header object pointing to the Ehdr of the
@ -55,18 +55,18 @@ def exe():
ptr = entry()
return load(ptr)
@gef.memoize.reset_on_exit
@pwndbg.memoize.reset_on_exit
def entry():
"""
Return the address of the entry point for the main executable.
"""
entry = gef.auxv.get().AT_ENTRY
entry = pwndbg.auxv.get().AT_ENTRY
if entry:
return entry
# Looking for this line:
# Entry point: 0x400090
for line in gef.info.files().splitlines():
for line in pwndbg.info.files().splitlines():
if "Entry point" in line:
return int(line.split()[-1], 16)
@ -95,11 +95,11 @@ def get_ehdr(pointer):
Example:
>>> gef.elf.load(gdb.parse_and_eval('$pc'))
>>> pwndbg.elf.load(gdb.parse_and_eval('$pc'))
[Page('400000-4ef000 r-xp 0'),
Page('6ef000-6f0000 r--p ef000'),
Page('6f0000-6ff000 rw-p f0000')]
>>> gef.elf.load(0x7ffff77a2000)
>>> pwndbg.elf.load(0x7ffff77a2000)
[Page('7ffff75e7000-7ffff77a2000 r-xp 0x1bb000 0'),
Page('7ffff77a2000-7ffff79a2000 ---p 0x200000 1bb000'),
Page('7ffff79a2000-7ffff79a6000 r--p 0x4000 1bb000'),
@ -112,22 +112,22 @@ def get_ehdr(pointer):
# Align down to a page boundary, and scan until we find
# the ELF header.
base = gef.memory.page_align(pointer)
data = gef.memory.read(base, 4)
base = pwndbg.memory.page_align(pointer)
data = pwndbg.memory.read(base, 4)
try:
while data != b'\x7FELF':
base -= gef.memory.PAGE_SIZE
data = gef.memory.read(base, 4)
base -= pwndbg.memory.PAGE_SIZE
data = pwndbg.memory.read(base, 4)
except gdb.MemoryError:
return None, None
# Determine whether it's 32- or 64-bit
ei_class = gef.memory.byte(base+4)
ei_class = pwndbg.memory.byte(base+4)
# Find out where the section headers start
EhdrType = { 1: Elf32_Ehdr, 2: Elf64_Ehdr }[ei_class]
Elfhdr = gef.memory.poi(EhdrType, base)
Elfhdr = pwndbg.memory.poi(EhdrType, base)
return ei_class, Elfhdr
def get_phdrs(pointer):
@ -149,7 +149,7 @@ def get_phdrs(pointer):
phoff = int(Elfhdr['e_phoff'])
phentsize = int(Elfhdr['e_phentsize'])
x = (phnum, phentsize, gef.memory.poi(PhdrType, int(Elfhdr.address) + phoff))
x = (phnum, phentsize, pwndbg.memory.poi(PhdrType, int(Elfhdr.address) + phoff))
return x
def iter_phdrs(ehdr):
@ -163,25 +163,25 @@ def iter_phdrs(ehdr):
for i in range(0, phnum):
p_phdr = int(first_phdr + (i*phentsize))
p_phdr = gef.memory.poi(PhdrType, p_phdr)
p_phdr = pwndbg.memory.poi(PhdrType, p_phdr)
yield p_phdr
@gef.memoize.reset_on_stop
@pwndbg.memoize.reset_on_stop
def map(pointer, objfile=''):
"""
Given a pointer into an ELF module, return a list of all loaded
sections in the ELF.
Returns:
A sorted list of gef.memory.Page objects
A sorted list of pwndbg.memory.Page objects
Example:
>>> gef.elf.load(gdb.parse_and_eval('$pc'))
>>> pwndbg.elf.load(gdb.parse_and_eval('$pc'))
[Page('400000-4ef000 r-xp 0'),
Page('6ef000-6f0000 r--p ef000'),
Page('6f0000-6ff000 rw-p f0000')]
>>> gef.elf.load(0x7ffff77a2000)
>>> pwndbg.elf.load(0x7ffff77a2000)
[Page('7ffff75e7000-7ffff77a2000 r-xp 0x1bb000 0'),
Page('7ffff77a2000-7ffff79a2000 ---p 0x200000 1bb000'),
Page('7ffff79a2000-7ffff79a6000 r--p 0x4000 1bb000'),
@ -208,13 +208,13 @@ def map(pointer, objfile=''):
flags = int(phdr['p_flags'])
ptype = int(phdr['p_type'])
memsz += gef.memory.page_offset(vaddr)
memsz = gef.memory.page_size_align(memsz)
vaddr = gef.memory.page_align(vaddr)
offset = gef.memory.page_align(offset)
memsz += pwndbg.memory.page_offset(vaddr)
memsz = pwndbg.memory.page_size_align(memsz)
vaddr = pwndbg.memory.page_align(vaddr)
offset = pwndbg.memory.page_align(offset)
# For each page described by this program header
for page_addr in range(vaddr, vaddr+memsz, gef.memory.PAGE_SIZE):
for page_addr in range(vaddr, vaddr+memsz, pwndbg.memory.PAGE_SIZE):
if page_addr in pages:
page = pages[pages.index(page_addr)]
@ -224,7 +224,7 @@ def map(pointer, objfile=''):
if page.flags & PF_X: flags |= PF_X
page.flags = flags
else:
page = gef.memory.Page(page_addr, gef.memory.PAGE_SIZE, flags, offset + (page_addr-vaddr))
page = pwndbg.memory.Page(page_addr, pwndbg.memory.PAGE_SIZE, flags, offset + (page_addr-vaddr))
pages.append(page)
# Adjust against the base address that we discovered
@ -251,7 +251,7 @@ def map(pointer, objfile=''):
a_end = (a.vaddr + a.memsz)
b_begin = b.vaddr
if a_end != b_begin:
gaps.append(gef.memory.Page(a_end, b_begin-a_end, 0, b.offset))
gaps.append(pwndbg.memory.Page(a_end, b_begin-a_end, 0, b.offset))
pages.extend(gaps)
@ -260,7 +260,7 @@ def map(pointer, objfile=''):
return tuple(sorted(pages))
@gef.events.stop
@pwndbg.events.stop
def update_main_exe():
addr = int(exe().address)
map(addr)

View File

@ -1,33 +1,33 @@
import gdb
import string
import gef.symbol
import gef.memory
import gef.color
import gef.types
import gef.strings
import gef.disasm
import gef.memoize
import gef.arch
import pwndbg.symbol
import pwndbg.memory
import pwndbg.color
import pwndbg.types
import pwndbg.strings
import pwndbg.disasm
import pwndbg.memoize
import pwndbg.arch
import string
@gef.memoize.reset_on_stop
@pwndbg.memoize.reset_on_stop
def enhance(value):
value = int(value)
name = gef.symbol.get(value) or None
page = gef.vmmap.find(value)
name = pwndbg.symbol.get(value) or None
page = pwndbg.vmmap.find(value)
# If it's not in a page we know about, try to dereference
# it anyway just to test.
can_read = True
if not page and None == gef.memory.peek(value):
if not page and None == pwndbg.memory.peek(value):
can_read = False
if not can_read:
retval = hex(int(value))
# Try to unpack the value as a string
packed = gef.arch.pack(int(value))
packed = pwndbg.arch.pack(int(value))
if all(c in string.printable.encode('utf-8') for c in packed):
retval = '%s (%r)' % (retval, packed.decode())
@ -38,29 +38,29 @@ def enhance(value):
# Try to find out if it's a string.
data = None
if page and page.execute:
data = gef.disasm.get(value, 1)[0].asm
data = pwndbg.disasm.get(value, 1)[0].asm
# However, if it contains bad instructions, bail
if '.byte' in data or '.long' in data:
data = None
if data is None:
data = gef.strings.get(value) or None
data = pwndbg.strings.get(value) or None
if data:
data = repr(data)
if data is None:
data = gef.memory.poi(gef.types.pvoid, value)
data = pwndbg.memory.poi(pwndbg.types.pvoid, value)
# Try to unpack the value as a string
try:
packed = gef.arch.pack(int(data))
packed = pwndbg.arch.pack(int(data))
if all(c in string.printable.encode('utf-8') for c in packed):
data = repr(packed.decode())
except:
data = str(data)
colored = gef.color.get(value)
colored = pwndbg.color.get(value)
if data and name: return "%s (%s: %s)" % (colored, name, data)
elif name: return "%s (%s)" % (colored, name)

2
pwndbg/events Normal file
View File

@ -0,0 +1,2 @@
import gdb

View File

@ -1,7 +1,7 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import gdb
import gef.remote
import pwndbg.remote
import tempfile
def get(path):
@ -14,7 +14,7 @@ def get(path):
"""
local_path = path
if gef.remote.is_remote():
if pwndbg.remote.is_remote():
local_path = tempfile.mktemp()
error = gdb.execute('remote get %s %s' % (path, local_path),
to_string=True)

0
pwndbg/gef.py Normal file
View File

View File

@ -1,6 +1,6 @@
import copy
import string
import gef.color
import pwndbg.color
def groupby(array, count, fill=None):
@ -13,13 +13,13 @@ def groupby(array, count, fill=None):
#
# We want to colorize the hex characters
#
color_scheme = {i:gef.color.normal("%02x" % i) for i in range(256)}
color_scheme = {i:pwndbg.color.normal("%02x" % i) for i in range(256)}
for c in (string.ascii_letters + string.digits + string.punctuation).encode('utf-8'):
color_scheme[c] = gef.color.bold("%02x" % c)
color_scheme[c] = pwndbg.color.bold("%02x" % c)
for c in bytearray(b'\x00\xff'):
color_scheme[c] = gef.color.red("%02x" % c)
color_scheme[c] = pwndbg.color.red("%02x" % c)
color_scheme[-1] = ' '

View File

@ -1,22 +1,22 @@
import gdb
import gef.memoize
import pwndbg.memoize
@gef.memoize.reset_on_exit
@pwndbg.memoize.reset_on_exit
def proc_mapping():
try:
return gdb.execute('info proc mapping', to_string=True)
except gdb.error:
return ''
@gef.memoize.reset_on_exit
@pwndbg.memoize.reset_on_exit
def auxv():
try:
return gdb.execute('info auxv', to_string=True)
except gdb.error:
return ''
@gef.memoize.reset_on_stop
@pwndbg.memoize.reset_on_stop
def files():
try:
return gdb.execute('info files', to_string=True)

View File

@ -4,7 +4,7 @@ import gdb
import functools
import sys
import gef.events
import pwndbg.events
class memoize(object):
def __call__(self, *args):
@ -43,7 +43,7 @@ class reset_on_stop(memoize):
self.caches.append(self)
@staticmethod
@gef.events.stop
@pwndbg.events.stop
def __reset():
for obj in reset_on_stop.caches:
obj.cache.clear()
@ -59,7 +59,7 @@ class reset_on_exit(memoize):
self.__module__ = func.__module__
@staticmethod
@gef.events.exit
@pwndbg.events.exit
def __reset():
for obj in reset_on_exit.caches:
obj.clear()
@ -75,7 +75,7 @@ class reset_on_objfile(memoize):
self.__module__ = func.__module__
@staticmethod
@gef.events.new_objfile
@pwndbg.events.new_objfile
def __reset():
for obj in reset_on_objfile.caches:
obj.clear()

View File

@ -1,8 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import gdb
import gef.compat
import gef.types
import pwndbg.compat
import pwndbg.types
PAGE_SIZE = 0x1000
MMAP_MIN_ADDR = 0x10000
@ -10,7 +10,7 @@ MMAP_MIN_ADDR = 0x10000
def read(addr, count):
result = gdb.selected_inferior().read_memory(addr, count)
if gef.compat.python3:
if pwndbg.compat.python3:
result = result.tobytes()
return bytearray(result)
@ -33,20 +33,20 @@ def poke(address):
except: return False
return True
def byte(addr): return readtype(gef.types.uchar, addr)
def uchar(addr): return readtype(gef.types.uchar, addr)
def ushort(addr): return readtype(gef.types.ushort, addr)
def uint(addr): return readtype(gef.types.uint, addr)
def byte(addr): return readtype(pwndbg.types.uchar, addr)
def uchar(addr): return readtype(pwndbg.types.uchar, addr)
def ushort(addr): return readtype(pwndbg.types.ushort, addr)
def uint(addr): return readtype(pwndbg.types.uint, addr)
def u8(addr): return readtype(gef.types.uint8_t, addr)
def u16(addr): return readtype(gef.types.uint16_t, addr)
def u32(addr): return readtype(gef.types.uint32_t, addr)
def u64(addr): return readtype(gef.types.uint64_t, addr)
def u8(addr): return readtype(pwndbg.types.uint8_t, addr)
def u16(addr): return readtype(pwndbg.types.uint16_t, addr)
def u32(addr): return readtype(pwndbg.types.uint32_t, addr)
def u64(addr): return readtype(pwndbg.types.uint64_t, addr)
def s8(addr): return readtype(gef.types.int8_t, addr)
def s16(addr): return readtype(gef.types.int16_t, addr)
def s32(addr): return readtype(gef.types.int32_t, addr)
def s64(addr): return readtype(gef.types.int64_t, addr)
def s8(addr): return readtype(pwndbg.types.int8_t, addr)
def s16(addr): return readtype(pwndbg.types.int16_t, addr)
def s32(addr): return readtype(pwndbg.types.int32_t, addr)
def s64(addr): return readtype(pwndbg.types.int64_t, addr)
def write(addr, data):
gdb.selected_inferior().write_memory(addr, data)
@ -67,21 +67,21 @@ assert round_down(0xdeadbeef, 0x1000) == 0xdeadb000
assert round_up(0xdeadbeef, 0x1000) == 0xdeadc000
def find_upper_boundary(addr):
addr = gef.memory.page_align(int(addr))
addr = pwndbg.memory.page_align(int(addr))
try:
while True:
gef.memory.read(addr, 1)
addr += gef.memory.PAGE_SIZE
pwndbg.memory.read(addr, 1)
addr += pwndbg.memory.PAGE_SIZE
except gdb.MemoryError:
pass
return addr
def find_lower_boundary(addr):
addr = gef.memory.page_align(int(addr))
addr = pwndbg.memory.page_align(int(addr))
try:
while True:
gef.memory.read(addr, 1)
addr -= gef.memory.PAGE_SIZE
pwndbg.memory.read(addr, 1)
addr -= pwndbg.memory.PAGE_SIZE
except gdb.MemoryError:
pass
return addr
@ -125,7 +125,7 @@ class Page(object):
'x' if flags & 1 else '-',
'p'])
def __str__(self):
width = 2 + 2*gef.types.ptrsize
width = 2 + 2*pwndbg.types.ptrsize
fmt_string = "%#{}x %#{}x %s %8x %-6x %s"
fmt_string = fmt_string.format(width, width)
return fmt_string % (self.vaddr,

View File

@ -23,7 +23,7 @@
#
# Tested on gdb 7.x / python 2.6 & 2.7 & 3.x
#
# To start: in gdb, type `source /path/to/gef.py`
# To start: in gdb, type `source /path/to/pwndbg.py`
#
#
# ToDo:
@ -49,10 +49,10 @@ import binascii
import gdb
# Relative imports
import gef.vmmap
import gef.dt
import gef.memory
import gef.elf
import pwndbg.vmmap
import pwndbg.dt
import pwndbg.memory
import pwndbg.elf
'''
if sys.version_info.major == 2:
@ -534,7 +534,7 @@ def get_process_maps():
mapping = gdb.execute('info proc mapping', to_string=True)
# Format looks like this:
# gef> info proc mapping
# pwndbg> info proc mapping
# process 47863
# Mapped address spaces:
#
@ -1011,7 +1011,7 @@ class DumpMemoryCommand(GenericCommand):
class AliasCommand(GenericCommand):
"""GEF defined aliases"""
_cmdline_ = "gef-alias"
_cmdline_ = "pwndbg-alias"
_syntax_ = "%s (set|show|do|unset)" % _cmdline_
def do_invoke(self, argv):
@ -1023,7 +1023,7 @@ class AliasCommand(GenericCommand):
class AliasSetCommand(GenericCommand):
"""GEF add alias command"""
_cmdline_ = "gef-alias set"
_cmdline_ = "pwndbg-alias set"
_syntax_ = "%s" % _cmdline_
def do_invoke(self, argv):
@ -1042,7 +1042,7 @@ class AliasSetCommand(GenericCommand):
class AliasUnsetCommand(GenericCommand):
"""GEF remove alias command"""
_cmdline_ = "gef-alias unset"
_cmdline_ = "pwndbg-alias unset"
_syntax_ = "%s" % _cmdline_
def do_invoke(self, argv):
@ -1057,7 +1057,7 @@ class AliasUnsetCommand(GenericCommand):
class AliasShowCommand(GenericCommand):
"""GEF show alias command"""
_cmdline_ = "gef-alias show"
_cmdline_ = "pwndbg-alias show"
_syntax_ = "%s" % _cmdline_
def do_invoke(self, argv):
@ -1067,7 +1067,7 @@ class AliasShowCommand(GenericCommand):
class AliasDoCommand(GenericCommand):
"""GEF do alias command"""
_cmdline_ = "gef-alias do"
_cmdline_ = "pwndbg-alias do"
_syntax_ = "%s" % _cmdline_
def do_invoke(self, argv):
@ -2014,7 +2014,7 @@ class TraceRunCommand(GenericCommand):
def __init__(self):
super(TraceRunCommand, self).__init__(self._cmdline_, complete=gdb.COMPLETE_LOCATION)
self.add_setting("max_tracing_recursion", 1)
self.add_setting("tracefile_prefix", "./gef-trace-")
self.add_setting("tracefile_prefix", "./pwndbg-trace-")
return
@ -2336,7 +2336,7 @@ class FormatStringSearchCommand(GenericCommand):
class GEFCommand(gdb.Command):
"""GEF Control Center"""
_cmdline_ = "gef"
_cmdline_ = "pwndbg"
_syntax_ = "%s (load/help)" % _cmdline_
def __init__(self):
@ -2387,7 +2387,7 @@ class GEFCommand(gdb.Command):
def invoke(self, args, from_tty):
argv = gdb.string_to_argv(args)
if len(argv) < 1 :
err("Missing command for gef -- `gef help` for help -- `gef config` for configuring")
err("Missing command for pwndbg -- `gef help` for help -- `gef config` for configuring")
return
cmd = argv[0]
@ -2396,7 +2396,7 @@ class GEFCommand(gdb.Command):
elif cmd == "config":
self.config(*argv[1:])
else:
err("Invalid command '%s' for gef -- type `gef help' for help" % ' '.join(argv))
err("Invalid command '%s' for pwndbg -- type `gef help' for help" % ' '.join(argv))
return
@ -2409,9 +2409,9 @@ class GEFCommand(gdb.Command):
except Exception as e:
err("Failed to load `%s`: %s" % (cmd, e))
print(("%s, `%s' to start, `%s' to configure" % (Color.greenify("gef loaded"),
Color.redify("gef help"),
Color.redify("gef config"))))
print(("%s, `%s' to start, `%s' to configure" % (Color.greenify("pwndbg loaded"),
Color.redify("pwndbg help"),
Color.redify("pwndbg config"))))
ver = "%d.%d" % (sys.version_info.major, sys.version_info.minor)
nb_cmds = sum([1 for x in self.loaded_command_names if " " not in x])
@ -2487,7 +2487,7 @@ class GEFCommand(gdb.Command):
def main():
GEF_PROMPT = Color.boldify(Color.redify("gef> "))
GEF_PROMPT = Color.boldify(Color.redify("pwndbg> "))
# setup config
gdb.execute("set confirm off")

View File

@ -2,7 +2,7 @@ import gdb
import sys
from types import ModuleType
import gef.memoize
import pwndbg.memoize
class module(ModuleType):
@property

View File

@ -3,8 +3,8 @@ import sys
import re
from types import ModuleType
import gef.memoize
import gef.arch
import pwndbg.memoize
import pwndbg.arch
class RegisterSet(object):
def __init__(self, pc, stack, frame, retaddr, flags, gpr, misc, args):
self.pc = pc
@ -149,7 +149,7 @@ class module(ModuleType):
def __getattr__(self, attr):
try:
value = int(gdb.parse_and_eval('$' + attr.lstrip('$')))
return value & gef.arch.ptrmask
return value & pwndbg.arch.ptrmask
except gdb.error:
return None
@ -158,23 +158,23 @@ class module(ModuleType):
@property
def gpr(self):
return arch_to_regs[gef.arch.current].gpr
return arch_to_regs[pwndbg.arch.current].gpr
@property
def frame(self):
return arch_to_regs[gef.arch.current].frame
return arch_to_regs[pwndbg.arch.current].frame
@property
def retaddr(self):
return arch_to_regs[gef.arch.current].retaddr
return arch_to_regs[pwndbg.arch.current].retaddr
@property
def stack(self):
return arch_to_regs[gef.arch.current].stack
return arch_to_regs[pwndbg.arch.current].stack
@property
def all(self):
regs = arch_to_regs[gef.arch.current]
regs = arch_to_regs[pwndbg.arch.current]
retval = []
for regset in (regs.pc, regs.stack, regs.frame, regs.retaddr, regs.flags, regs.gpr, regs.misc):
if regset is None:
@ -197,7 +197,7 @@ class module(ModuleType):
@property
def arguments(self):
argnames = arch_to_regs[gef.arch.current].args
argnames = arch_to_regs[pwndbg.arch.current].args
retval = []
for arg in argnames:
val = self[arg]

View File

@ -1,12 +1,12 @@
import gdb
import gef.events
import gef.memory
import gef.memoize
import pwndbg.events
import pwndbg.memory
import pwndbg.memoize
# Dictionary of stack ranges.
# Key is the gdb thread ptid
# Value is a gef.memory.Page object
# Value is a pwndbg.memory.Page object
stacks = {}
# Whether the stack is protected by NX.
@ -15,14 +15,14 @@ nx = False
def find(address):
"""
Returns a gef.memory.Page object which corresponds to the
Returns a pwndbg.memory.Page object which corresponds to the
currently-loaded stack.
"""
for stack in stacks:
if address in stack:
return stack
@gef.events.stop
@pwndbg.events.stop
def update():
"""
For each running thread, updates the known address range
@ -33,21 +33,21 @@ def update():
try:
for thread in gdb.selected_inferior().threads():
thread.switch()
sp = gef.regs.sp
sp = pwndbg.regs.sp
# If we don't already know about this thread, create
# a new Page mapping for it.
page = stacks.get(thread.ptid, None)
if page is None:
start = gef.memory.find_lower_boundary(sp)
stop = gef.memory.find_upper_boundary(sp)
page = gef.memory.Page(start, stop-start, 6 if not is_executable() else 7, 0, '[stack]')
start = pwndbg.memory.find_lower_boundary(sp)
stop = pwndbg.memory.find_upper_boundary(sp)
page = pwndbg.memory.Page(start, stop-start, 6 if not is_executable() else 7, 0, '[stack]')
stacks[thread.ptid] = page
continue
# If we *DO* already know about this thread, just
# udpate the lower boundary.
low = gef.memory.find_lower_boundary(page.vaddr)
low = pwndbg.memory.find_lower_boundary(page.vaddr)
if low != page.vaddr:
page.memsz += (page.vaddr - low)
page.vaddr = low
@ -55,14 +55,14 @@ def update():
curr_thread.switch()
@gef.memoize.reset_on_stop
@pwndbg.memoize.reset_on_stop
def current():
"""
Returns the bounds for the stack for the current thread.
"""
return find(gef.regs.sp)
return find(pwndbg.regs.sp)
@gef.events.exit
@pwndbg.events.exit
def clear():
"""
Clears everything we know about any stack memory ranges.
@ -73,15 +73,15 @@ def clear():
global nx
nx = False
@gef.events.stop
@gef.memoize.reset_on_exit
@pwndbg.events.stop
@pwndbg.memoize.reset_on_exit
def is_executable():
global nx
nx = False
PT_GNU_STACK = 0x6474e551
ehdr = gef.elf.exe()
for phdr in gef.elf.iter_phdrs(ehdr):
ehdr = pwndbg.elf.exe()
for phdr in pwndbg.elf.iter_phdrs(ehdr):
p_type = int(phdr['p_type'])
if p_type == PT_GNU_STACK:
nx = True

0
pwndbg/string.pu Normal file
View File

View File

@ -1,10 +1,10 @@
import gdb
import string
import gef.types
import pwndbg.types
def get(address):
try:
sz = gdb.Value(address).cast(gef.types.pchar).string()
sz = gdb.Value(address).cast(pwndbg.types.pchar).string()
except Exception as e:
return None

View File

@ -1,13 +1,13 @@
import gdb
import gef.memoize
import gef.memory
@gef.memoize.reset_on_objfile
import pwndbg.memoize
import pwndbg.memory
@pwndbg.memoize.reset_on_objfile
def get(address):
"""
Retrieve the textual name for a symbol
"""
# Fast path
if address < gef.memory.MMAP_MIN_ADDR:
if address < pwndbg.memory.MMAP_MIN_ADDR:
return ''
# This sucks, but there's not a GDB API for this.

View File

@ -5,14 +5,14 @@ import glob
import tempfile
import subprocess
import gef.events
import gef.memoize
import pwndbg.events
import pwndbg.memoize
module = sys.modules[__name__]
@gef.events.new_objfile
@gef.memoize.reset_on_exit
@pwndbg.events.new_objfile
@pwndbg.memoize.reset_on_exit
def update():
module.char = gdb.lookup_type('char')
module.ulong = gdb.lookup_type('unsigned long')
@ -47,7 +47,7 @@ update()
update.clear()
tempdir = tempfile.gettempdir() + '/gef'
tempdir = tempfile.gettempdir() + '/pwndbg'
if not os.path.exists(tempdir):
os.mkdir(tempdir)
@ -67,7 +67,7 @@ def load(name):
# s, _ = gdb.lookup_symbol(name)
# Try to find an architecture-specific include path
arch = gef.arch.current.split(':')[0]
arch = pwndbg.arch.current.split(':')[0]
include_dir = glob.glob('/usr/%s*/include' % arch)

View File

@ -1,5 +1,5 @@
import struct, termios, fcntl, sys
import gef.arch
import pwndbg.arch
def banner(title):
title = title.upper()
@ -11,5 +11,5 @@ def banner(title):
return ("[{:-^%ss}]" % width).format(title)
def addrsz(address):
address = int(address) & gef.arch.ptrmask
return "%{}x".format(2*gef.arch.ptrsize) % address
address = int(address) & pwndbg.arch.ptrmask
return "%{}x".format(2*pwndbg.arch.ptrsize) % address

View File

@ -10,16 +10,16 @@ system has /proc/$$/maps, which backs 'info proc mapping'.
import gdb
import sys
import gef.remote
import gef.memory
import gef.types
import gef.file
import gef.proc
import gef.compat
import gef.memoize
import gef.stack
import gef.events
import gef.regs
import pwndbg.remote
import pwndbg.memory
import pwndbg.types
import pwndbg.file
import pwndbg.proc
import pwndbg.compat
import pwndbg.memoize
import pwndbg.stack
import pwndbg.events
import pwndbg.regs
# List of manually-explored pages which were discovered
# by analyzing the stack or register context.
@ -35,15 +35,15 @@ def get():
if pages: pages.extend(info_sharedlibrary())
else: pages.extend(info_files())
pages.extend(gef.stack.stacks.values())
pages.extend(pwndbg.stack.stacks.values())
pages.extend(explored_pages)
pages.sort()
return pages
@gef.memoize.reset_on_stop
@pwndbg.memoize.reset_on_stop
def find(address):
if address < gef.memory.MMAP_MIN_ADDR:
if address < pwndbg.memory.MMAP_MIN_ADDR:
return None
for page in get():
@ -66,15 +66,15 @@ def explore(address_maybe):
Also assumes the entire contiguous section has the same permission.
"""
address_maybe = gef.memory.page_align(address_maybe)
address_maybe = pwndbg.memory.page_align(address_maybe)
flags = 4 if gef.memory.peek(address_maybe) else 0
flags = 4 if pwndbg.memory.peek(address_maybe) else 0
if not flags:
return None
flags |= 2 if gef.memory.poke(address_maybe) else 0
flags |= 1 if not gef.stack.nx else 0
flags |= 2 if pwndbg.memory.poke(address_maybe) else 0
flags |= 1 if not pwndbg.stack.nx else 0
page = find_boundaries(address_maybe)
page.flags = flags
@ -84,24 +84,24 @@ def explore(address_maybe):
return page
# Automatically ensure that all registers are explored on each stop
@gef.events.stop
@pwndbg.events.stop
def explore_registers():
for regname in gef.regs.all:
find(gef.regs[regname])
for regname in pwndbg.regs.all:
find(pwndbg.regs[regname])
@gef.events.exit
@pwndbg.events.exit
def clear_explored_pages():
while explored_pages:
explored_pages.pop()
@gef.memoize.reset_on_stop
@pwndbg.memoize.reset_on_stop
def proc_pid_maps():
"""
Parse the contents of /proc/$PID/maps on the server.
Returns:
A list of gef.memory.Page objects.
A list of pwndbg.memory.Page objects.
"""
example_proc_pid_maps = """
@ -127,21 +127,21 @@ def proc_pid_maps():
"""
locations = [
'/proc/%s/maps' % gef.proc.pid,
'/proc/%s/map' % gef.proc.pid,
'/usr/compat/linux/proc/%s/maps' % gef.proc.pid,
'/proc/%s/maps' % pwndbg.proc.pid,
'/proc/%s/map' % pwndbg.proc.pid,
'/usr/compat/linux/proc/%s/maps' % pwndbg.proc.pid,
]
for location in locations:
try:
data = gef.file.get(location)
data = pwndbg.file.get(location)
break
except (OSError, gdb.error):
continue
else:
return []
if gef.compat.python3:
if pwndbg.compat.python3:
data = data.decode()
pages = []
@ -163,13 +163,13 @@ def proc_pid_maps():
if 'w' in perm: flags |= 2
if 'x' in perm: flags |= 1
page = gef.memory.Page(start, size, flags, offset, objfile)
page = pwndbg.memory.Page(start, size, flags, offset, objfile)
pages.append(page)
return tuple(pages)
@gef.memoize.reset_on_objfile
@pwndbg.memoize.reset_on_objfile
def info_sharedlibrary():
"""
Parses the output of `info sharedlibrary`.
@ -181,7 +181,7 @@ def info_sharedlibrary():
page permissions for every mapped page in the ELF.
Returns:
A list of gef.memory.Page objects.
A list of pwndbg.memory.Page objects.
"""
exmaple_info_sharedlibrary_freebsd = """
@ -210,11 +210,11 @@ def info_sharedlibrary():
text = int(tokens[0], 16)
obj = tokens[-1]
pages.extend(gef.elf.map(text, obj))
pages.extend(pwndbg.elf.map(text, obj))
return sorted(pages)
@gef.memoize.reset_on_objfile
@pwndbg.memoize.reset_on_objfile
def info_files():
example_info_files_linues = """
@ -267,13 +267,13 @@ def info_files():
else:
seen_files.add(objfile)
pages.extend(gef.elf.map(vaddr, objfile))
pages.extend(pwndbg.elf.map(vaddr, objfile))
return tuple(pages)
@gef.memoize.reset_on_exit
@pwndbg.memoize.reset_on_exit
def info_auxv(skip_exe=False):
"""
Extracts the name of the executable from the output of the command
@ -283,9 +283,9 @@ def info_auxv(skip_exe=False):
skip_exe(bool): Do not return any mappings that belong to the exe.
Returns:
A list of gef.memory.Page objects.
A list of pwndbg.memory.Page objects.
"""
auxv = gef.auxv.get()
auxv = pwndbg.auxv.get()
if not auxv:
return []
@ -297,7 +297,7 @@ def info_auxv(skip_exe=False):
phdr = auxv.AT_PHDR
if not skip_exe and (entry or phdr):
pages.extend(gef.elf.map(entry or phdr, exe_name))
pages.extend(pwndbg.elf.map(entry or phdr, exe_name))
if vdso:
pages.append(find_boundaries(vdso, '[vdso]'))
@ -310,14 +310,14 @@ def find_boundaries(addr, name=''):
Given a single address, find all contiguous pages
which are mapped.
"""
start = gef.memory.find_lower_boundary(addr)
end = gef.memory.find_upper_boundary(addr)
return gef.memory.Page(start, end-start, 4, 0, name)
start = pwndbg.memory.find_lower_boundary(addr)
end = pwndbg.memory.find_upper_boundary(addr)
return pwndbg.memory.Page(start, end-start, 4, 0, name)
aslr = False
@gef.events.stop
@gef.memoize.reset_on_exit
@pwndbg.events.stop
@pwndbg.memoize.reset_on_exit
def check_aslr():
vmmap = sys.modules[__name__]
vmmap.aslr = False