Skip to content

Commit

Permalink
Wrap docs (#962)
Browse files Browse the repository at this point in the history
* Wrap docs to 100 columns

* Add editorconfig for markdown
  • Loading branch information
Grazfather authored Jul 18, 2023
1 parent ca7418c commit 7fd94ab
Show file tree
Hide file tree
Showing 58 changed files with 725 additions and 682 deletions.
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@ indent_style = tab
[*.yml]
indent_style = space
indent_size = 2

[*.md]
max_line_length=100
93 changes: 51 additions & 42 deletions docs/api.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
# Extending GEF

`GEF` intends to provide a battery-included, quickly installable and crazy fast
debugging environment sitting on top of GDB.
`GEF` intends to provide a battery-included, quickly installable and crazy fast debugging
environment sitting on top of GDB.

But it most importantly provides all the primitives required to allow hackers to
quickly create their own commands. This page intends to summarize how to
create advanced GDB commands in moments using `GEF` as a library.
But it most importantly provides all the primitives required to allow hackers to quickly create
their own commands. This page intends to summarize how to create advanced GDB commands in moments
using `GEF` as a library.

A [dedicated repository](https://github.com/hugsy/gef-extras) was born to host
[external scripts](https://github.com/hugsy/gef-extras/tree/main/scripts). This
repo is open to all for contributions, no restrictions and the most valuable
ones will be integrated into `gef.py`.
A [dedicated repository](https://github.com/hugsy/gef-extras) was born to host [external
scripts](https://github.com/hugsy/gef-extras/tree/main/scripts). This repo is open to all for
contributions, no restrictions and the most valuable ones will be integrated into `gef.py`.

## Quick start

Expand Down Expand Up @@ -51,17 +50,15 @@ Yes, that's it! Check out [the complete API](api/gef.md) to see what else GEF of

## Detailed explanation

Our new command must be a class that inherits from GEF's `GenericCommand`. The
*only* requirements are:
Our new command must be a class that inherits from GEF's `GenericCommand`. The *only* requirements are:

* a `_cmdline_` attribute (the command to type on the GDB prompt).
* a `_syntax_` attribute, which GEF will use to auto-generate the help menu.
* a method `do_invoke(self, args)` which will be executed when the command
is invoked. `args` is a list of the command line args provided when invoked.
* a `_cmdline_` attribute (the command to type on the GDB prompt).
* a `_syntax_` attribute, which GEF will use to auto-generate the help menu.
* a method `do_invoke(self, args)` which will be executed when the command is invoked. `args` is a
list of the command line args provided when invoked.

We make GEF aware of this new command by registering it in the `__main__`
section of the script, by invoking the global function
`register_external_command()`.
We make GEF aware of this new command by registering it in the `__main__` section of the script, by
invoking the global function `register_external_command()`.

Now you have a new GEF command which you can load, either from cli:
```bash
Expand All @@ -75,9 +72,8 @@ $ echo source /path/to/newcmd.py >> ~/.gdbinit

## Customizing context panes

Sometimes you want something similar to a command to run on each break-like
event and display itself as a part of the GEF context. Here is a simple example
of how to make a custom context pane:
Sometimes you want something similar to a command to run on each break-like event and display itself
as a part of the GEF context. Here is a simple example of how to make a custom context pane:

```python
__start_time__ = int(time.time())
Expand All @@ -96,26 +92,25 @@ Loading it in `GEF` is as easy as loading a command
gef➤ source /path/to/custom_context_pane.py
```

It can even be included in the same file as a Command.
Now on each break you will notice a new pane near the bottom of the context.
The order can be modified in the `GEF` context config.
It can even be included in the same file as a Command. Now on each break you will notice a new pane
near the bottom of the context. The order can be modified in the `GEF` context config.

### Context Pane API

The API demonstrated above requires very specific argument types:
`register_external_context_pane(pane_name, display_pane_function, pane_title_function)`

-`pane_name`: a string that will be used as the panes setting name
-`display_pane_function`: a function that uses `gef_print()` to print content
in the pane
-`pane_title_function`: a function that returns the title string or None to hide the title
* `pane_name`: a string that will be used as the panes setting name
* `display_pane_function`: a function that uses `gef_print()` to print content in the pane
* `pane_title_function`: a function that returns the title string or None to hide the title

## API

Some of the most important parts of the API for creating new commands are
mentioned (but not limited to) below. To see the full help of a function, open
GDB and GEF, and use the embedded Python interpreter's `help` command. For
example:
Some of the most important parts of the API for creating new commands are mentioned (but not limited
to) below. To see the full help of a function, open GDB and GEF, and use the embedded Python
interpreter's `help` command.

For example:

```bash
gef➤ pi help(Architecture)
Expand All @@ -130,14 +125,14 @@ $ gdb -q -ex 'pi help(hexdump)' -ex quit
The GEF API aims to provide a simpler and more Pythonic approach to GDB's.

Some basic examples:
- read the memory
- read the memory
```python
gef ➤ pi print(hexdump( gef.memory.read(parse_address("$pc"), length=0x20 )))
0x0000000000000000 f3 0f 1e fa 31 ed 49 89 d1 5e 48 89 e2 48 83 e4 ....1.I..^H..H..
0x0000000000000010 f0 50 54 4c 8d 05 66 0d 01 00 48 8d 0d ef 0c 01 .PTL..f...H.....
```

- get access to the memory layout
- get access to the memory layout
```
gef ➤ pi print('\n'.join([ f"{x.page_start:#x} -> {x.page_end:#x}" for x in gef.memory.maps]))
0x555555554000 -> 0x555555558000
Expand All @@ -155,9 +150,9 @@ gef ➤ pi print('\n'.join([ f"{x.page_start:#x} -> {x.page_end:#x}" for x in ge


The API also offers a number of decorators to simplify the creation of new/existing commands, such as:
- `@only_if_gdb_running` to execute only if a GDB session is running.
- `@only_if_gdb_target_local` to check if the target is local i.e. not debugging using GDB `remote`.
- and many more...
- `@only_if_gdb_running` to execute only if a GDB session is running.
- `@only_if_gdb_target_local` to check if the target is local i.e. not debugging using GDB `remote`.
- and many more...


### Reference
Expand All @@ -171,9 +166,18 @@ For a complete reference of the API offered by GEF, visit [`docs/api/gef.md`](ap
@parse_arguments( {"required_argument_1": DefaultValue1, ...}, {"--optional-argument-1": DefaultValue1, ...} )
```

This decorator aims to facilitate the argument passing to a command. If added, it will use the `argparse` module to parse arguments, and will store them in the `kwargs["arguments"]` of the calling function (therefore the function **must** have `*args, **kwargs` added to its signature). Argument type is inferred directly from the default value **except** for boolean, where a value of `True` corresponds to `argparse`'s `store_true` action. For more details on `argparse`, refer to its Python documentation.
This decorator aims to facilitate the argument passing to a command. If added, it will use the
`argparse` module to parse arguments, and will store them in the `kwargs["arguments"]` of the
calling function (therefore the function **must** have `*args, **kwargs` added to its signature).
Argument type is inferred directly from the default value **except** for boolean, where a value of
`True` corresponds to `argparse`'s `store_true` action. For more details on `argparse`, refer to its
Python documentation.

Values given for the parameters also allow list of arguments being past. This can be useful in the case where the number of exact option values is known in advance. This can be achieved simply by using a type of `tuple` or `list` for the default value. `parse_arguments` will determine the type of what to expect based on the first default value of the iterable, so make sure it's not empty. For instance:
Values given for the parameters also allow list of arguments being past. This can be useful in the
case where the number of exact option values is known in advance. This can be achieved simply by
using a type of `tuple` or `list` for the default value. `parse_arguments` will determine the type
of what to expect based on the first default value of the iterable, so make sure it's not empty. For
instance:


```python
Expand Down Expand Up @@ -216,16 +220,21 @@ args.blah --> True # set to True because user input declared the option (would h

### Adding new architectures

Support for new architectures can be added by inheriting from the `Architecture` class. To register the new architecture with gef, the decorator `@register_architecture` has to be added to the class. Examples can be found in [gef-extras](https://github.com/hugsy/gef-extras/tree/dev/archs).
Support for new architectures can be added by inheriting from the `Architecture` class. Examples can
be found in [gef-extras](https://github.com/hugsy/gef-extras/tree/dev/archs).

Sometimes architectures can more precisely determine whether they apply to the current target by looking at the architecture determined by gdb. For these cases the custom architecture may implement the `supports_gdb_arch()` static function to signal that they should be used instead of the default. The function receives only one argument:
Sometimes architectures can more precisely determine whether they apply to the current target by
looking at the architecture determined by gdb. For these cases the custom architecture may implement
the `supports_gdb_arch()` static function to signal that they should be used instead of the default.
The function receives only one argument:
- `gdb_str` (of type `str`) which is the architecture name as reported by GDB.

The function **must** return:
- `True` if the current `Architecture` class supports the target binary; `False` otherwise.
- `None` to simply ignore this check and let GEF try to determine the architecture.

One example is the ARM Cortex-M architecture which in some cases should rather be used than the generic ARM one:
One example is the ARM Cortex-M architecture which in some cases should be used over the generic ARM
one:

```python
@staticmethod
Expand Down
26 changes: 12 additions & 14 deletions docs/commands/aliases.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ aliases (add|rm|list)

### Adding/Removing Aliases

`GEF` defines its own aliasing mechanism which overrides the traditional
alias that GDB provides through the built-in command `alias`. To add a new alias,
simply use the `aliases add` command. The "command" parameter may contain spaces.
`GEF` defines its own aliasing mechanism which overrides the traditional alias that GDB provides
through the built-in command `alias`. To add a new alias, simply use the `aliases add` command. The
"command" parameter may contain spaces.

```
aliases add [alias] [command]
Expand All @@ -25,8 +25,8 @@ aliases rm [alias]

### Listing Aliases

One can list aliases by using the `aliases ls` command. Some sample output of this
command is seen below.
One can list aliases by using the `aliases ls` command. Some sample output of this command is seen
below.

```
[+] Aliases defined:
Expand All @@ -46,9 +46,8 @@ ps → process-search

### Using the Configuration File

Users can also create/modify/delete aliases by editing the `GEF` configuration file,
by default located at `~/.gef.rc`. The aliases must be in the `aliases` section
of the configuration file.
Users can also create/modify/delete aliases by editing the `GEF` configuration file, by default
located at `~/.gef.rc`. The aliases must be in the `aliases` section of the configuration file.

Creating a new alias is as simple as creating a new entry in this section:

Expand All @@ -61,8 +60,8 @@ my-new-alias = gdb-or-gef-command <arg1> <arg2> <etc...>

#### Bringing some PEDA and WinDBG flavours into GEF

For example, for those (like me) who use WinDBG and like its bindings, they can
be integrated into GDB via GEF aliases like this:
For example, for those (like me) who use WinDBG and like its bindings, they can be integrated into
GDB via GEF aliases like this:

```
$ nano ~/.gef.rc
Expand Down Expand Up @@ -90,8 +89,7 @@ g = gef run
uf = disassemble
```

Or here are some `PEDA` aliases for people used to using `PEDA` who made the
smart move to `GEF`.
Or here are some `PEDA` aliases for people used to using `PEDA` who made the smart move to `GEF`.

```
# some peda aliases
Expand All @@ -103,8 +101,8 @@ kp = info stack
findmem = search-pattern
```

The aliases will be loaded next time you load GDB (and `GEF`). Or you can force
`GEF` to reload the settings with the command:
The aliases will be loaded next time you load GDB (and `GEF`). Or you can force `GEF` to reload the
settings with the command:

```
gef➤ gef restore
Expand Down
6 changes: 3 additions & 3 deletions docs/commands/aslr.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ gef➤ aslr off
[+] Disabling ASLR
```

**Note**: This command cannot affect a process that has already been loaded, to
which GDB attached to later. The only way to disable this randomization is by
setting the kernel setting `/proc/sys/kernel/randomize_va_space` to 0..
**Note**: This command cannot affect a process that has already been loaded, to which GDB attached
to later. The only way to disable this randomization is by setting the kernel setting
`/proc/sys/kernel/randomize_va_space` to 0..
7 changes: 3 additions & 4 deletions docs/commands/canary.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
## Command `canary`

If the currently debugged process was compiled with the Smash Stack Protector
(SSP) - i.e. the `-fstack-protector` flag was passed to the compiler, this
command will display the value of the canary. This makes it convenient to avoid
manually searching for this value in memory.
If the currently debugged process was compiled with the Smash Stack Protector (SSP) - i.e. the
`-fstack-protector` flag was passed to the compiler, this command will display the value of the
canary. This makes it convenient to avoid manually searching for this value in memory.

The command `canary` does not take any arguments.
```
Expand Down
5 changes: 2 additions & 3 deletions docs/commands/checksec.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
## Command `checksec` ##

The `checksec` command is inspired from
[`checksec.sh`](https://www.trapkit.de/tools/checksec.html). It provides a
convenient way to determine which security protections are enabled in a binary.
The `checksec` command is inspired from [`checksec.sh`](https://www.trapkit.de/tools/checksec.html).
It provides a convenient way to determine which security protections are enabled in a binary.

You can use the command on the currently debugged process:
```
Expand Down
21 changes: 10 additions & 11 deletions docs/commands/config.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
## Command `gef config` ##

`gef` reads its config from a file which is by default located at `~/.gef.rc`, but which
can also be specified via the `GEF_RC` environment variable. In addition, `gef` can also
be configured at runtime with the `gef config` command.
`gef` reads its config from a file which is by default located at `~/.gef.rc`, but which can also be
specified via the `GEF_RC` environment variable. In addition, `gef` can also be configured at
runtime with the `gef config` command.

To view all settings for all commands loaded:
```
Expand All @@ -15,27 +15,26 @@ Or to get one setting value:
gef➤ gef config pcustom.struct_path
```

Of course you can edit the values. For example, if you want the screen to be
cleared before displaying the current context when reaching a breakpoing:
Of course you can edit the values. For example, if you want the screen to be cleared before
displaying the current context when reaching a breakpoing:
```
gef➤ gef config context.clear_screen 1
```

To save the current settings for `GEF` to the file system to have those options
persist across all your future `GEF` sessions, simply run:
To save the current settings for `GEF` to the file system to have those options persist across all
your future `GEF` sessions, simply run:
```
gef➤ gef save
[+] Configuration saved to '/home/vagrant/.gef.rc'
```

Upon startup, if `$GEF_RC` points to an existing file, or otherwise if
`${HOME}/.gef.rc` exists, `gef` will automatically load its values.
Upon startup, if `$GEF_RC` points to an existing file, or otherwise if `${HOME}/.gef.rc` exists,
`gef` will automatically load its values.

To reload the settings during the session, just run:
```
gef➤ gef restore
[+] Configuration from '/home/hugsy/.gef.rc' restored
```

You can tweak this configuration file outside your `gdb` session to suit your
needs.
You can tweak this configuration file outside your `gdb` session to suit your needs.
Loading

0 comments on commit 7fd94ab

Please sign in to comment.