Add documentation, eventually for ReadTheDocs (#169)

* First-pass for documentation, and mocking

* Add some example commands

* Add a bunch of API documentation
This commit is contained in:
Zach Riggle 2017-03-06 11:36:27 -06:00 committed by GitHub
parent 12ad874d0f
commit 4a96004003
57 changed files with 876 additions and 23 deletions

1
docs/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
build

20
docs/Makefile Normal file
View File

@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
SPHINXPROJ = pwndbg
SOURCEDIR = source
BUILDDIR = build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

213
docs/gdb/__init__.py Normal file
View File

@ -0,0 +1,213 @@
# This mocks the GDB module for test generation
import types as _types
ARCH_FRAME = 5
class Architecture(object): pass
BP_ACCESS_WATCHPOINT = 9
BP_BREAKPOINT = 1
BP_HARDWARE_WATCHPOINT = 7
BP_NONE = 0
BP_READ_WATCHPOINT = 8
BP_WATCHPOINT = 6
class Block(object): pass
class BlockIterator(object): pass
class Breakpoint(object): pass
class BreakpointEvent(object): pass
COMMAND_BREAKPOINTS = 6
COMMAND_DATA = 1
COMMAND_FILES = 3
COMMAND_MAINTENANCE = 11
COMMAND_NONE = -1
COMMAND_OBSCURE = 10
COMMAND_RUNNING = 0
COMMAND_STACK = 2
COMMAND_STATUS = 5
COMMAND_SUPPORT = 4
COMMAND_TRACEPOINTS = 7
COMMAND_USER = 14
COMPLETE_COMMAND = 3
COMPLETE_EXPRESSION = 5
COMPLETE_FILENAME = 1
COMPLETE_LOCATION = 2
COMPLETE_NONE = 0
COMPLETE_SYMBOL = 4
class ClearObjFilesEvent(object): pass
class Command(object): pass
class ContinueEvent(object): pass
DUMMY_FRAME = 1
class Event(object): pass
class EventRegistry(object): pass
class ExitedEvent(object): pass
FRAME_UNWIND_INNER_ID = 4
FRAME_UNWIND_MEMORY_ERROR = 7
FRAME_UNWIND_NO_REASON = 0
FRAME_UNWIND_NO_SAVED_PC = 6
FRAME_UNWIND_NULL_ID = 1
FRAME_UNWIND_OUTERMOST = 2
FRAME_UNWIND_SAME_ID = 5
FRAME_UNWIND_UNAVAILABLE = 3
class Field(object): pass
class FinishBreakpoint(object): pass
class Frame(object): pass
FrameDecorator = object() # module 'gdb.FrameDecorator' from '/usr/local/Cellar/gdb/7.12_1/share/gdb/python/gdb/FrameDecorator.pyc'>
FrameIterator = object() # module 'gdb.FrameIterator' from '/usr/local/Cellar/gdb/7.12_1/share/gdb/python/gdb/FrameIterator.pyc'>
class Function(object): pass
class GdbError(object): pass
class GdbOutputErrorFile(object): pass
class GdbOutputFile(object): pass
def GdbSetPythonDirectory(*a, **kw): pass
HOST_CONFIG = 'x86_64-apple-darwin16.3.0'
INLINE_FRAME = 2
class Inferior(object): pass
class InferiorCallPostEvent(object): pass
class InferiorCallPreEvent(object): pass
class InferiorThread(object): pass
class LineTable(object): pass
class LineTableEntry(object): pass
class LineTableIterator(object): pass
class Membuf(object): pass
class MemoryChangedEvent(object): pass
class MemoryError(object): pass
NORMAL_FRAME = 0
class NewObjFileEvent(object): pass
class Objfile(object): pass
PARAM_AUTO_BOOLEAN = 1
PARAM_BOOLEAN = 0
PARAM_ENUM = 11
PARAM_FILENAME = 7
PARAM_INTEGER = 3
PARAM_OPTIONAL_FILENAME = 6
PARAM_STRING = 4
PARAM_STRING_NOESCAPE = 5
PARAM_UINTEGER = 2
PARAM_ZINTEGER = 8
PYTHONDIR = '/usr/local/Cellar/gdb/7.12_1/share/gdb/python'
class Parameter(object): pass
class PendingFrame(object): pass
class Progspace(object): pass
class RegisterChangedEvent(object): pass
SENTINEL_FRAME = 6
SIGTRAMP_FRAME = 4
STDERR = 1
STDLOG = 2
STDOUT = 0
SYMBOL_FUNCTIONS_DOMAIN = 1
SYMBOL_LABEL_DOMAIN = 4
SYMBOL_LOC_ARG = 4
SYMBOL_LOC_BLOCK = 10
SYMBOL_LOC_COMPUTED = 14
SYMBOL_LOC_CONST = 1
SYMBOL_LOC_CONST_BYTES = 11
SYMBOL_LOC_LABEL = 9
SYMBOL_LOC_LOCAL = 7
SYMBOL_LOC_OPTIMIZED_OUT = 13
SYMBOL_LOC_REF_ARG = 5
SYMBOL_LOC_REGISTER = 3
SYMBOL_LOC_REGPARM_ADDR = 6
SYMBOL_LOC_STATIC = 2
SYMBOL_LOC_TYPEDEF = 8
SYMBOL_LOC_UNDEF = 0
SYMBOL_LOC_UNRESOLVED = 12
SYMBOL_STRUCT_DOMAIN = 2
SYMBOL_TYPES_DOMAIN = 2
SYMBOL_UNDEF_DOMAIN = 0
SYMBOL_VARIABLES_DOMAIN = 0
SYMBOL_VAR_DOMAIN = 1
class SignalEvent(object): pass
class StopEvent(object): pass
class Symbol(object): pass
class Symtab(object): pass
class Symtab_and_line(object): pass
TAILCALL_FRAME = 3
TARGET_CONFIG = 'x86_64-apple-darwin16.3.0'
TYPE_CODE_ARRAY = 2
TYPE_CODE_BITSTRING = -1
TYPE_CODE_BOOL = 20
TYPE_CODE_CHAR = 19
TYPE_CODE_COMPLEX = 21
TYPE_CODE_DECFLOAT = 24
TYPE_CODE_ENUM = 5
TYPE_CODE_ERROR = 14
TYPE_CODE_FLAGS = 6
TYPE_CODE_FLT = 9
TYPE_CODE_FUNC = 7
TYPE_CODE_INT = 8
TYPE_CODE_INTERNAL_FUNCTION = 26
TYPE_CODE_MEMBERPTR = 17
TYPE_CODE_METHOD = 15
TYPE_CODE_METHODPTR = 16
TYPE_CODE_NAMESPACE = 23
TYPE_CODE_PTR = 1
TYPE_CODE_RANGE = 12
TYPE_CODE_REF = 18
TYPE_CODE_SET = 11
TYPE_CODE_STRING = 13
TYPE_CODE_STRUCT = 3
TYPE_CODE_TYPEDEF = 22
TYPE_CODE_UNION = 4
TYPE_CODE_VOID = 10
class ThreadEvent(object): pass
class Type(object): pass
class TypeIterator(object): pass
class UnwindInfo(object): pass
VERSION = '7.12'
class Value(object): pass
WP_ACCESS = 2
WP_READ = 1
WP_WRITE = 0
class _GdbFile(object): pass
__doc__ = None
__file__ = '/usr/local/Cellar/gdb/7.12_1/share/gdb/python/gdb/__init__.pyc'
__name__ = 'gdb'
__package__ = 'gdb'
__path__ = ['/usr/local/Cellar/gdb/7.12_1/share/gdb/python/gdb']
def auto_load_packages(*a, **kw): pass
command = object() # module 'gdb.command' from '/usr/local/Cellar/gdb/7.12_1/share/gdb/python/gdb/command/__init__.pyc'>
class error(object): pass
def execute_unwinders(*a, **kw): pass
frame_filters = {}
frame_unwinders = []
frames = object() # module 'gdb.frames' from '/usr/local/Cellar/gdb/7.12_1/share/gdb/python/gdb/frames.pyc'>
function = object() # module 'gdb.function' from '/usr/local/Cellar/gdb/7.12_1/share/gdb/python/gdb/function/__init__.pyc'>
os = object() # module 'os' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/os.pyc'>
printer = object() # module 'gdb.printer' from '/usr/local/Cellar/gdb/7.12_1/share/gdb/python/gdb/printer/__init__.pyc'>
printing = object() # module 'gdb.printing' from '/usr/local/Cellar/gdb/7.12_1/share/gdb/python/gdb/printing.pyc'>
prompt = object() # module 'gdb.prompt' from '/usr/local/Cellar/gdb/7.12_1/share/gdb/python/gdb/prompt.pyc'>
def prompt_hook(*a, **kw): pass
traceback = object() # module 'traceback' from '/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/traceback.pyc'>
type_printers = []
types = object() # module 'gdb.types' from '/usr/local/Cellar/gdb/7.12_1/share/gdb/python/gdb/types.pyc'>
# ===================================
class Command(object):
def __init__(self, *a, **kw):
pass
class Parameter(object):
def __init__(self, *a, **kw):
pass
class _event(object):
def connect(*a, **kw): pass
class _events(_types.ModuleType):
exited = _event()
cont = _event()
new_objfile = _event()
stop = _event()
events = _events('events')
class _type():
sizeof = 4
def pointer(*a, **kw): return _type()
def lookup_type(*a, **kw): return _type()
class Value(object):
def __init__(*a, **kw): pass
def cast(*a, **kw): return Value()
def execute(*a, **kw): return ''
class Function(object):
def __init__(*a, **kw): pass
def selected_inferior(): pass
def selected_thread(): pass

10
docs/source/api.rst Normal file
View File

@ -0,0 +1,10 @@
API
========
``pwndbg`` provides a very rich programmatic API for interaction.
.. toctree::
:maxdepth: 3
:glob:
api/*

5
docs/source/api/abi.rst Normal file
View File

@ -0,0 +1,5 @@
:mod:`pwndbg.abi` --- ABI Agnosticity
=============================================
.. automodule:: pwndbg.abi
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.android` --- pwndbg.android
=============================================
.. automodule:: pwndbg.android
:members:

5
docs/source/api/arch.rst Normal file
View File

@ -0,0 +1,5 @@
:mod:`pwndbg.arch` --- pwndbg.arch
=============================================
.. automodule:: pwndbg.arch
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.arguments` --- pwndbg.arguments
=============================================
.. automodule:: pwndbg.arguments
:members:

5
docs/source/api/argv.rst Normal file
View File

@ -0,0 +1,5 @@
:mod:`pwndbg.argv` --- pwndbg.argv
=============================================
.. automodule:: pwndbg.argv
:members:

5
docs/source/api/auxv.rst Normal file
View File

@ -0,0 +1,5 @@
:mod:`pwndbg.auxv` --- pwndbg.auxv
=============================================
.. automodule:: pwndbg.auxv
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.chain` --- pwndbg.chain
=============================================
.. automodule:: pwndbg.chain
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.compat` --- pwndbg.compat
=============================================
.. automodule:: pwndbg.compat
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.config` --- pwndbg.config
=============================================
.. automodule:: pwndbg.config
:members:

5
docs/source/api/dt.rst Normal file
View File

@ -0,0 +1,5 @@
:mod:`pwndbg.dt` --- pwndbg.dt
=============================================
.. automodule:: pwndbg.dt
:members:

5
docs/source/api/elf.rst Normal file
View File

@ -0,0 +1,5 @@
:mod:`pwndbg.elf` --- pwndbg.elf
=============================================
.. automodule:: pwndbg.elf
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.elftypes` --- pwndbg.elftypes
=============================================
.. automodule:: pwndbg.elftypes
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.enhance` --- pwndbg.enhance
=============================================
.. automodule:: pwndbg.enhance
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.events` --- pwndbg.events
=============================================
.. automodule:: pwndbg.events
:members:

5
docs/source/api/file.rst Normal file
View File

@ -0,0 +1,5 @@
:mod:`pwndbg.file` --- pwndbg.file
=============================================
.. automodule:: pwndbg.file
:members:

5
docs/source/api/gcc.rst Normal file
View File

@ -0,0 +1,5 @@
:mod:`pwndbg.gcc` --- pwndbg.gcc
=============================================
.. automodule:: pwndbg.gcc
:members:

9
docs/source/api/generate.sh Executable file
View File

@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -ex
cat > $1.rst <<EOF
:mod:\`pwndbg.$1\` --- pwndbg.$1
=============================================
.. automodule:: pwndbg.$1
:members:
EOF

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.gitver` --- pwndbg.gitver
=============================================
.. automodule:: pwndbg.gitver
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.hexdump` --- pwndbg.hexdump
=============================================
.. automodule:: pwndbg.hexdump
:members:

5
docs/source/api/ida.rst Normal file
View File

@ -0,0 +1,5 @@
:mod:`pwndbg.ida` --- pwndbg.ida
=============================================
.. automodule:: pwndbg.ida
:members:

5
docs/source/api/info.rst Normal file
View File

@ -0,0 +1,5 @@
:mod:`pwndbg.info` --- pwndbg.info
=============================================
.. automodule:: pwndbg.info
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.inthook` --- pwndbg.inthook
=============================================
.. automodule:: pwndbg.inthook
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.linkmap` --- pwndbg.linkmap
=============================================
.. automodule:: pwndbg.linkmap
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.malloc` --- pwndbg.malloc
=============================================
.. automodule:: pwndbg.malloc
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.memoize` --- pwndbg.memoize
=============================================
.. automodule:: pwndbg.memoize
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.memory` --- Memory Manipulation
=============================================
.. automodule:: pwndbg.memory
:members:

5
docs/source/api/net.rst Normal file
View File

@ -0,0 +1,5 @@
:mod:`pwndbg.net` --- pwndbg.net
=============================================
.. automodule:: pwndbg.net
:members:

5
docs/source/api/next.rst Normal file
View File

@ -0,0 +1,5 @@
:mod:`pwndbg.next` --- pwndbg.next
=============================================
.. automodule:: pwndbg.next
:members:

5
docs/source/api/proc.rst Normal file
View File

@ -0,0 +1,5 @@
:mod:`pwndbg.proc` --- pwndbg.proc
=============================================
.. automodule:: pwndbg.proc
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.prompt` --- pwndbg.prompt
=============================================
.. automodule:: pwndbg.prompt
:members:

5
docs/source/api/qemu.rst Normal file
View File

@ -0,0 +1,5 @@
:mod:`pwndbg.qemu` --- pwndbg.qemu
=============================================
.. automodule:: pwndbg.qemu
:members:

5
docs/source/api/regs.rst Normal file
View File

@ -0,0 +1,5 @@
:mod:`pwndbg.regs` --- pwndbg.regs
=============================================
.. automodule:: pwndbg.regs
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.remote` --- pwndbg.remote
=============================================
.. automodule:: pwndbg.remote
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.search` --- pwndbg.search
=============================================
.. automodule:: pwndbg.search
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.stack` --- pwndbg.stack
=============================================
.. automodule:: pwndbg.stack
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.stdio` --- pwndbg.stdio
=============================================
.. automodule:: pwndbg.stdio
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.strings` --- pwndbg.strings
=============================================
.. automodule:: pwndbg.strings
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.symbol` --- pwndbg.symbol
=============================================
.. automodule:: pwndbg.symbol
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.typeinfo` --- pwndbg.typeinfo
=============================================
.. automodule:: pwndbg.typeinfo
:members:

5
docs/source/api/ui.rst Normal file
View File

@ -0,0 +1,5 @@
:mod:`pwndbg.ui` --- pwndbg.ui
=============================================
.. automodule:: pwndbg.ui
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.vmmap` --- pwndbg.vmmap
=============================================
.. automodule:: pwndbg.vmmap
:members:

View File

@ -0,0 +1,5 @@
:mod:`pwndbg.which` --- pwndbg.which
=============================================
.. automodule:: pwndbg.which
:members:

12
docs/source/commands.rst Normal file
View File

@ -0,0 +1,12 @@
Commands
========
``pwndbg`` provides a very rich command API for interaction.
Some of the commands are listed here.
.. toctree::
:maxdepth: 3
:glob:
commands/*

View File

@ -0,0 +1,2 @@
.. autoprogram:: pwndbg.commands.aslr:parser
:prog: aslr

View File

@ -0,0 +1,2 @@
.. autoprogram:: pwndbg.commands.hexdump:parser
:prog: hexdump

View File

@ -0,0 +1,2 @@
.. autoprogram:: pwndbg.commands.search:parser
:prog: search

View File

@ -0,0 +1,2 @@
.. autoprogram:: pwndbg.commands.stack:p
:prog: stack

View File

@ -0,0 +1,2 @@
.. autoprogram:: pwndbg.commands.telescope:parser
:prog: telescope

172
docs/source/conf.py Normal file
View File

@ -0,0 +1,172 @@
# -*- coding: utf-8 -*-
#
# pwndbg documentation build configuration file, created by
# sphinx-quickstart on Tue Feb 28 14:36:07 2017.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import subprocess
import sys
# These paths are relative to the 'source' directory
os.environ['SPHINX'] = '1'
sys.path.insert(0, os.path.abspath('..')) # <-- For 'gdb'
sys.path.insert(0, os.path.abspath('../..')) # <-- For 'pwndbg'
import pwndbg
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.intersphinx',
'sphinx.ext.todo',
'sphinx.ext.viewcode',
'sphinxcontrib.autoprogram',
'sphinxcontrib.napoleon'
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = '.rst'
# The master toctree document.
master_doc = 'index'
# General information about the project.
project = u'pwndbg'
copyright = u'2017, Zach Riggle'
author = u'Zach Riggle'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = u'2017.02.01'
# The full version, including alpha/beta/rc tags.
release = u'2017.02.01'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = []
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'alabaster'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'pwndbgdoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'pwndbg.tex', u'pwndbg Documentation',
u'Zach Riggle', 'manual'),
]
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'pwndbg', u'pwndbg Documentation',
[author], 1)
]
# -- Options for Texinfo output -------------------------------------------
# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'pwndbg', u'pwndbg Documentation',
author, 'pwndbg', 'One line description of project.',
'Miscellaneous'),
]
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'https://docs.python.org/': None}

27
docs/source/index.rst Normal file
View File

@ -0,0 +1,27 @@
.. pwndbg documentation master file, created by
sphinx-quickstart on Tue Feb 28 14:36:07 2017.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
pwndbg
==================================
``pwndbg`` provides an API and set of commands to extend functionality of the GNU Debugger (GDB).
It is written in Python, and designed to assist in software debugging, reverse engineering, and exploit development. It is designed to be robust and easily extensible.
.. toctree::
:maxdepth: 2
commands
api
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

View File

@ -12,9 +12,16 @@ import pwndbg.events
import pwndbg.memory
import pwndbg.regs
#: Total number of arguments
argc = None
#: Pointer to argv on the stack
argv = None
#: Pointer to envp on the stack
envp = None
#: Total number of environment variables
envc = None
@pwndbg.events.start

View File

@ -10,6 +10,7 @@ from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
import os
import sys
import gdb
@ -43,9 +44,11 @@ class xint(with_metaclass(IsAnInt, builtins.int)):
value = value.cast(pwndbg.typeinfo.ulong)
return _int(_int(value, *a, **kw))
builtins.int = xint
globals()['int'] = xint
# Do not hook 'int' if we are just generating documentation
if os.environ.get('SPHINX', None) is None:
builtins.int = xint
globals()['int'] = xint
if sys.version_info >= (3,0):
builtins.long = xint
globals()['long'] = xint
if sys.version_info >= (3,0):
builtins.long = xint
globals()['long'] = xint

View File

@ -24,6 +24,19 @@ PAGE_MASK = ~(PAGE_SIZE-1)
MMAP_MIN_ADDR = 0x8000
def read(addr, count, partial=False):
"""read(addr, count, partial=False) -> bytearray
Read memory from the program being debugged.
Arguments:
addr(int): Address to read
count(int): Number of bytes to read
partial(bool): Whether less than ``count`` bytes can be returned
Returns:
:class:`bytearray`: The memory at the specified address,
or ``None``.
"""
result = b''
try:
@ -60,17 +73,58 @@ def read(addr, count, partial=False):
return bytearray(result)
def readtype(gdb_type, addr):
"""readtype(gdb_type, addr) -> int
Reads an integer-type (e.g. ``uint64``) and returns a Python
native integer representation of the same.
Arguments:
gdb_type(gdb.Type): GDB type to read
addr(int): Address at which the value to be read resides
Returns:
:class:`int`
"""
return int(gdb.Value(addr).cast(gdb_type.pointer()).dereference())
def write(addr, data):
"""write(addr, data)
Writes data into the memory of the process being debugged.
Arguments:
addr(int): Address to write
data(str,bytes,bytearray): Data to write
"""
gdb.selected_inferior().write_memory(addr, data)
def peek(address):
"""peek(address) -> str
Read one byte from the specified address.
Arguments:
address(int): Address to read
Returns:
:class:`str`: A single byte of data, or ``None`` if the
address cannot be read.
"""
try: return read(address, 1)
except: pass
return None
def poke(address):
"""poke(address)
Checks whether an address is writable.
Arguments:
address(int): Address to check
Returns:
:class:`bool`: Whether the address is writable.
"""
c = peek(address)
if c is None: return False
try: write(address, c)
@ -95,18 +149,76 @@ def string(addr, max=4096):
return bytearray()
def byte(addr): return readtype(pwndbg.typeinfo.uchar, addr)
def uchar(addr): return readtype(pwndbg.typeinfo.uchar, addr)
def ushort(addr): return readtype(pwndbg.typeinfo.ushort, addr)
def uint(addr): return readtype(pwndbg.typeinfo.uint, addr)
def pvoid(addr): return readtype(pwndbg.typeinfo.pvoid, addr)
def byte(addr):
"""byte(addr) -> int
def u8(addr): return readtype(pwndbg.typeinfo.uint8, addr)
def u16(addr): return readtype(pwndbg.typeinfo.uint16, addr)
def u32(addr): return readtype(pwndbg.typeinfo.uint32, addr)
def u64(addr): return readtype(pwndbg.typeinfo.uint64, addr)
Read one byte at the specified address
"""
return readtype(pwndbg.typeinfo.uchar, addr)
def uchar(addr):
"""uchar(addr) -> int
Read one ``unsigned char`` at the specified address.
"""
return readtype(pwndbg.typeinfo.uchar, addr)
def ushort(addr):
"""ushort(addr) -> int
Read one ``unisgned short`` at the specified address.
"""
return readtype(pwndbg.typeinfo.ushort, addr)
def uint(addr):
"""uint(addr) -> int
Read one ``unsigned int`` at the specified address.
"""
return readtype(pwndbg.typeinfo.uint, addr)
def pvoid(addr):
"""pvoid(addr) -> int
Read one pointer from the specified address.
"""
return readtype(pwndbg.typeinfo.pvoid, addr)
def u8(addr):
"""u8(addr) -> int
Read one ``uint8_t`` from the specified address.
"""
return readtype(pwndbg.typeinfo.uint8, addr)
def u16(addr):
"""u16(addr) -> int
Read one ``uint16_t`` from the specified address.
"""
return readtype(pwndbg.typeinfo.uint16, addr)
def u32(addr):
"""u32(addr) -> int
Read one ``uint32_t`` from the specified address.
"""
return readtype(pwndbg.typeinfo.uint32, addr)
def u64(addr):
"""u64(addr) -> int
Read one ``uint64_t`` from the specified address.
"""
return readtype(pwndbg.typeinfo.uint64, addr)
def u(addr, size=None):
"""u(addr, size=None) -> int
Read one ``unsigned`` integer from the specified address,
with the bit-width specified by ``size``, which defaults
to the pointer width.
"""
if size is None:
size = pwndbg.arch.ptrsize * 8
return {
@ -116,24 +228,64 @@ def u(addr, size=None):
64: u64
}[size](addr)
def s8(addr): return readtype(pwndbg.typeinfo.int8, addr)
def s16(addr): return readtype(pwndbg.typeinfo.int16, addr)
def s32(addr): return readtype(pwndbg.typeinfo.int32, addr)
def s64(addr): return readtype(pwndbg.typeinfo.int64, addr)
def s8(addr):
"""s8(addr) -> int
def write(addr, data):
gdb.selected_inferior().write_memory(addr, data)
Read one ``int8_t`` from the specified address
"""
return readtype(pwndbg.typeinfo.int8, addr)
def poi(type, addr): return gdb.Value(addr).cast(type.pointer()).dereference()
def s16(addr):
"""s16(addr) -> int
Read one ``int16_t`` from the specified address.
"""
return readtype(pwndbg.typeinfo.int16, addr)
def s32(addr):
"""s32(addr) -> int
Read one ``int32_t`` from the specified address.
"""
return readtype(pwndbg.typeinfo.int32, addr)
def s64(addr):
"""s64(addr) -> int
Read one ``int64_t`` from the specified address.
"""
return readtype(pwndbg.typeinfo.int64, addr)
def poi(type, addr):
"""poi(addr) -> gdb.Value
Read one ``gdb.Type`` object at the specified address.
"""
return gdb.Value(addr).cast(type.pointer()).dereference()
def round_down(address, align):
"""round_down(address, align) -> int
Round down ``address`` to the nearest increment of ``align``.
"""
return address & ~(align-1)
def round_up(address, align): return (address+(align-1))&(~(align-1))
def round_up(address, align):
"""round_up(address, align) -> int
Round up ``address`` to the nearest increment of ``align``.
"""
return (address+(align-1))&(~(align-1))
align_down = round_down
align_up = round_up
def page_align(address): return round_down(address, PAGE_SIZE)
def page_align(address):
"""page_align(address) -> int
Round down ``address`` to the nearest page boundary.
"""
return round_down(address, PAGE_SIZE)
def page_size_align(address): return round_up(address, PAGE_SIZE)
def page_offset(address): return (address & (PAGE_SIZE-1))
@ -141,6 +293,12 @@ assert round_down(0xdeadbeef, 0x1000) == 0xdeadb000
assert round_up(0xdeadbeef, 0x1000) == 0xdeadc000
def find_upper_boundary(addr, max_pages=1024):
"""find_upper_boundary(addr, max_pages=1024) -> int
Brute-force search the upper boundary of a memory mapping,
by reading the first byte of each page, until an unmapped
page is found.
"""
addr = pwndbg.memory.page_align(int(addr))
try:
for i in range(max_pages):
@ -155,6 +313,12 @@ def find_upper_boundary(addr, max_pages=1024):
return addr
def find_lower_boundary(addr, max_pages=1024):
"""find_lower_boundary(addr, max_pages=1024) -> int
Brute-force search the lower boundary of a memory mapping,
by reading the first byte of each page, until an unmapped
page is found.
"""
addr = pwndbg.memory.page_align(int(addr))
try:
for i in range(max_pages):