Setup pre-commit for GEF (#984)

This PR adds `pre-commit` to facilitate and unify the formatting of
everything in this project (code, test, docs, ci).

Aside from `.pre-commit-config.yml` and `docs/.markdownlint.yaml`, all
the other changes are purely cosmetic, applying markdownlint and fixing
here and there to make it pass.

It also creates a new CI job that'll simply execute `pre-commit` for new
PRs.
This commit is contained in:
crazy hugsy
2023-08-07 16:36:33 -07:00
committed by GitHub
parent 878cbf2297
commit 7c170cf6be
94 changed files with 1368 additions and 1294 deletions
+19 -14
View File
@@ -1,22 +1,27 @@
## Contributing to GEF ##
## Contributing to GEF
### License ###
## License
`gef` is placed under [MIT license](https://github.com/hugsy/gef/blob/main/LICENSE) which provides Open-Source access to the code and its use.
`gef` is placed under [MIT license](https://github.com/hugsy/gef/blob/main/LICENSE) which provides
Open-Source access to the code and its use.
By contributing to `gef` code through the _Pull Requests_ mechanism, you accept to release the code written by you under the said license.
By contributing to `gef` code through the _Pull Requests_ mechanism, you accept to release the code
written by you under the said license.
## Submitting a Patch
### Submitting a Patch ###
1. Fork `gef` repository (requires GitHub account). Sending a patch from the
1. Fork `gef` repository (requires GitHub account). Sending a patch from the
`patch` or `git diff --patch` commands is not accepted.
1. Write the changes in your local repo.
* Respect the coding style (same indentation format, explicit names as possible)
* Comment your code
* If you add a new feature/GDB command, also write the adequate
documentation (in [`docs/`](docs/))
1. Submit a pull request, make sure it is made against the `main` branch
1. The contributors will review your patch. If it is approved, the change will
1. All the packages required for testing and documenting are listed in `tests/requirements.txt`
1. Adjust your development environment to GEF's: this is achieved using
[`pre-commit`](https://pre-commit.com/), and getting setup is simply done by
1. Installing `pre-commit` PIP package (part of the `requirements.txt` file)
1. Setup `pre-commit` : `pre-commit install`
1. Write the changes in your local repo making sure to respect the coding style (same indentation
format, explicit names as possible), comment your code sufficiently so it becomes maintainable by
someone other than you. Finally if you add a new feature/GDB command, also write the adequate
documentation (in [`docs/`](docs/))
1. Submit a pull request
1. The contributors will review your patch. If it is approved, the change will
be merged via the GitHub, and you will be seen as contributors. If it needs
additional work, the repo owner will respond with useful comments.
-1
View File
@@ -1,4 +1,3 @@
# These are supported funding model platforms
github: [hugsy,]
+3 -3
View File
@@ -7,7 +7,7 @@ body:
id: md_welcome
attributes:
value: |
Complete this form is for reporting bugs in GEF. Incomplete/invalid report will simply being ignored or closed.
Complete this form is for reporting bugs in GEF. Incomplete/invalid report will simply being ignored or closed.
Also note that this is not the place to ask installation or usage problem. Use the Discord channel for that.
- type: textarea
attributes:
@@ -38,9 +38,9 @@ body:
multiple: false
options:
- "No"
- "Yes"
- "Yes"
validations:
required: true
required: true
- type: checkboxes
attributes:
label: Architecture impacted
+9 -20
View File
@@ -1,31 +1,20 @@
## Description/Motivation/Screenshots
## Description
<!-- Describe technically what your patch does. -->
<!-- Why is this change required? What problem does it solve? -->
<!-- Why is this patch will make a better world? -->
<!-- How does this look? Add a screenshot if you can -->
## Against which architecture was this tested ?
"Tested" indicates that the PR works *and* the unit test (see `docs/testing.md`) run passes without issue.
* [ ] x86-32
* [ ] x86-64
* [ ] ARM
* [ ] AARCH64
* [ ] MIPS
* [ ] POWERPC
* [ ] SPARC
* [ ] RISC-V
<!-- Annotate your PR with label proper labels (architecture impacted, type of improvement, etc.)
## Checklist
<!-- N.B.: Your patch won't be reviewed unless fulfilling the following base requirements: -->
<!--- Put an `x` in all the boxes that are complete, or that don't apply -->
- [ ] My code follows the code style of this project.
- [ ] My change includes a change to the documentation, if required.
- [ ] If my change adds new code, [adequate tests](docs/testing.md) have been added.
- [ ] I have read and agree to the **CONTRIBUTING** document.
- [ ] My code follows the code style of this project.
- [ ] My change includes a change to the documentation, if required.
- [ ] If my change adds new code, [adequate tests](docs/testing.md) have been added.
- [ ] I have read and agree to the **CONTRIBUTING** document.
+1 -1
View File
@@ -20,6 +20,6 @@ closeComment: >
complete description; or create a new issue.
Thank you for your contributions.
# Set to true to ignore issues in a milestone (defaults to false)
exemptMilestones: true
exemptMilestones: true
# Set to true to ignore issues with an assignee (defaults to false)
exemptAssignees: true
+48 -1
View File
@@ -2,13 +2,14 @@ name: CI Coverage for PR
on:
pull_request:
types: [opened, edited]
jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
fetch-depth: '0'
- name: Run test coverage
id: get_coverage
@@ -28,10 +29,14 @@ jobs:
new_score=$(cat docs/coverage/gef_py.html | grep pc_cov | sed 's?.*<span class="pc_cov">\([^%]*\)%</span>?\1?g')
diff_score=$(python -c "print(${new_score} - ${current_score})")
commit=$(git rev-parse HEAD)
include_tests=$(git diff ${{ github.event.before }} ${{ github.event.after }} --compact-summary | egrep --count '^ tests/' || true)
include_docs=$(git diff ${{ github.event.before }} ${{ github.event.after }} --compact-summary | egrep --count '^ docs/' || true)
echo "commit=${commit}" >> $GITHUB_OUTPUT
echo "new_coverage_score=${new_score}" >> $GITHUB_OUTPUT
echo "current_coverage_score=${current_score}" >> $GITHUB_OUTPUT
echo "diff_score=${diff_score}" >> $GITHUB_OUTPUT
echo "include_tests=${include_tests}" >> $GITHUB_OUTPUT
echo "include_docs=${include_docs}" >> $GITHUB_OUTPUT
- uses: actions/github-script@v6
env:
@@ -41,12 +46,54 @@ jobs:
SCORE_DIFF: ${{ steps.get_coverage.outputs.diff_score }}
with:
script: |
const tests_changes = ${{ steps.get_coverage.outputs.include_tests }};
const docs_changes = ${{ steps.get_coverage.outputs.include_docs }};
const comment = `## 🤖 Coverage Update
* Commit: ${process.env.COMMIT}
* Current Coverage: ${process.env.SCORE_OLD}%
* New Coverage: ${process.env.SCORE_NEW}%
* Diff: ${process.env.SCORE_DIFF}
To this point, this PR:
* ${(tests_changes == 0) ? "**does not** include" : "includes"} changes to tests
* ${(docs_changes == 0) ? "**does not** include" : "includes"} changes to documentation
`;
const { owner, repo, number } = context.issue;
await github.rest.issues.createComment({ owner, repo, issue_number: number, body: comment });
try {
if(docs_changes > 0) {
await github.rest.issues.addLabels({
owner: owner,
repo: repo,
issue_number: number,
labels: ['documentation']
});
} else {
await github.rest.issues.removeLabel({
owner: owner,
repo: repo,
issue_number: number,
name: 'documentation'
});
}
if(tests_changes > 0) {
await github.rest.issues.addLabels({
owner: owner,
repo: repo,
issue_number: number,
labels: ['automation/ci']
});
} else {
await github.rest.issues.removeLabel({
owner: owner,
repo: repo,
issue_number: number,
name: 'automation/ci'
});
}
} catch (err) {}
Binary file not shown.
-5
View File
@@ -67,8 +67,3 @@ jobs:
run: |
make -C tests/binaries -j ${{ env.GEF_CI_NB_CPU }}
python${{ env.PY_VER }} -m pytest --forked -n ${{ env.GEF_CI_NB_CPU }} -v -k "not benchmark" tests/
- name: Run linter
run: |
python${{ env.PY_VER }} -m pylint --rcfile=$(pwd)/.pylintrc gef.py tests/*/*.py
+31
View File
@@ -0,0 +1,31 @@
name: Validation
on:
pull_request:
branches:
- main
jobs:
pre_commit:
name: Check formatting
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v3
- uses: pre-commit/[email protected]
docs_link_check:
name: Check URLs in docs
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: checkout
uses: actions/checkout@v2
- name: Check links
uses: lycheeverse/[email protected]
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
with:
args: --exclude-mail --accept=401 --no-progress 'docs/**/*.md'
fail: false
+25
View File
@@ -0,0 +1,25 @@
default_stages: [pre-commit, pre-push]
fail_fast: false
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace
- repo: https://github.com/pycqa/pylint
rev: v3.0.0a6
hooks:
- id: pylint
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.35.0
hooks:
- id: markdownlint-docker
args:
- --config=docs/.markdownlint.yaml
- --ignore=docs/api/gef.md
- --ignore=docs/obsolete/docs/index.md
- --ignore=docs/index.md
- --ignore=README.md
- "docs/**/*.md"
+13 -18
View File
@@ -15,12 +15,11 @@ development. Application developers will also benefit from it, as GEF lifts a gr
GDB obscurity, avoiding repeating traditional commands, or bringing out the relevant information
from the debugging runtime.
## Instant Setup ##
## Instant Setup
Simply make sure you have [GDB 8.0 or higher](https://www.gnu.org/s/gdb) compiled with Python3.6+
bindings, then:
```bash
# via the install script
## using curl
@@ -44,18 +43,18 @@ You can immediately see that GEF is correctly installed by launching GDB:
A few of `GEF` features include:
* **One** single GDB script
* Entirely **architecture agnostic**, **NO** dependencies: `GEF` is battery-included and [is
* **One** single GDB script
* Entirely **architecture agnostic**, **NO** dependencies: `GEF` is battery-included and [is
installable instantly](https://hugsy.github.io/gef/#setup)
* **Fast** limiting the number of dependencies and optimizing code to make the commands as fast as
* **Fast** limiting the number of dependencies and optimizing code to make the commands as fast as
possible
* Provides a great variety of commands to drastically change your experience in GDB.
* [**Easily** extensible](https://hugsy.github.io/gef/api/) to create other commands by providing
* Provides a great variety of commands to drastically change your experience in GDB.
* [**Easily** extensible](https://hugsy.github.io/gef/api/) to create other commands by providing
d more comprehensible layout to GDB Python API.
* Full Python3 support ([Python2 support was
* Full Python3 support ([Python2 support was
dropped](https://github.com/hugsy/gef/releases/tag/2020.03) - see
[`gef-legacy`](https://github.com/hugsy/gef-legacy)).
* Built around an architecture abstraction layer, so all commands work in any GDB-supported
* Built around an architecture abstraction layer, so all commands work in any GDB-supported
architecture such as x86-32/64, ARMv5/6/7, AARCH64, SPARC, MIPS, PowerPC, etc.
* Suited for real-life apps debugging, exploit development, just as much as CTF
* And a lot more commands contributed by the community available on
@@ -64,8 +63,7 @@ d more comprehensible layout to GDB Python API.
Check out the [Screenshot page](docs/screenshots.md) for more or [try it
online](https://demo.gef.blah.cat) (user:`gef`/password:`gef-demo`)
## Documentation ##
## Documentation
Unlike other GDB plugins, GEF has an extensive and up-to-date
[documentation](https://hugsy.github.io/gef/). Users are recommended to refer to it as it may help
@@ -73,25 +71,22 @@ them in their attempts to use GEF. In particular, new users should navigate thro
[FAQ](https://hugsy.github.io/gef/faq/) for common installation problems), and the problem persists,
try to reach out for help on the Discord channel or submit an issue.
## Current status ##
## Current status
| Documentation |License | Compatibility | CI Tests (`main`) |
|:---:|:---:|:---|--|
| [![Documentation](https://github.com/hugsy/gef/actions/workflows/generate-docs.yml/badge.svg)](https://github.com/hugsy/gef/actions/workflows/generate-docs.yml) | [![MIT](https://img.shields.io/packagist/l/doctrine/orm.svg?maxAge=2592000?style=plastic)](https://github.com/hugsy/gef/blob/main/LICENSE) | [![Python 3](https://img.shields.io/badge/Python-3-green.svg)](https://github.com/hugsy/gef/) | [![CI Test for GEF](https://github.com/hugsy/gef/actions/workflows/run-tests.yml/badge.svg)](https://github.com/hugsy/gef/actions/workflows/run-tests.yml) |
## Contribute ##
## Contribute
To get involved, refer to the [Contribution
documentation](https://hugsy.github.io/gef/#contribution) and the
[guidelines](https://github.com/hugsy/gef/blob/main/.github/CONTRIBUTING.md) to start.
## Sponsors ##
## Sponsors
Another way to contribute to keeping the project alive is by sponsoring it! Check out [the
sponsoring documentation](https://hugsy.github.io/gef/#sponsors) for details so you can be part of
the list of those [awesome sponsors](https://github.com/sponsors/hugsy).
## Happy Hacking 🍻 ##
## Happy Hacking 🍻
+7 -10
View File
@@ -1,3 +1,6 @@
#
# Rules: https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md
#
# Default state for all rules
default: true
@@ -10,7 +13,7 @@ MD001: true
# MD002/first-heading-h1/first-header-h1 - First heading should be a top-level heading
MD002:
# Heading level
level: 1
level: 2
# MD003/heading-style/header-style - Heading style
MD003:
@@ -161,7 +164,7 @@ MD032: true
# MD033/no-inline-html - Inline HTML
MD033:
# Allowed elements
allowed_elements: []
allowed_elements: ["img"]
# MD034/no-bare-urls - Bare URL used
MD034: true
@@ -195,7 +198,7 @@ MD040:
# MD041/first-line-heading/first-line-h1 - First line in a file should be a top-level heading
MD041:
# Heading level
level: 1
level: 2
# RegExp for matching title in front matter
front_matter_title: "^\\s*title\\s*[:=]"
@@ -203,13 +206,7 @@ MD041:
MD042: true
# MD043/required-headings/required-headers - Required heading structure
MD043:
# List of headings
headings: []
# List of headings
headers: []
# Match case of headings
match_case: false
MD043: false
# MD044/proper-names - Proper names should have the correct capitalization
MD044:
+24 -20
View File
@@ -1,4 +1,4 @@
# Extending GEF
## Extending GEF
`GEF` intends to provide a battery-included, quickly installable and crazy fast debugging
environment sitting on top of GDB.
@@ -34,14 +34,14 @@ register_external_command(NewCommand())
Loading it in `GEF` is as easy as
```
```text
gef➤ source /path/to/newcmd.py
[+] Loading 'NewCommand'
```
We can call it:
```
```text
gef➤ newcmd
gef.arch=<__main__.X86_64 object at 0x7fd5583571c0>
gef.arch.pc=0x55555555a7d0
@@ -53,9 +53,9 @@ Yes, that's it! Check out [the complete API](api/gef.md) to see what else GEF of
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
* 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
@@ -91,7 +91,7 @@ register_external_context_pane("wasted_time_debugging", wasted_time_debugging, w
Loading it in `GEF` is as easy as loading a command
```
```text
gef➤ source /path/to/custom_context_pane.py
```
@@ -103,9 +103,9 @@ near the bottom of the context. The order can be modified in the `GEF` context c
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
@@ -128,7 +128,8 @@ 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
```text
gef ➤ pi print(hexdump( gef.memory.read(parse_address("$pc"), length=0x20 )))
@@ -136,9 +137,9 @@ gef ➤ pi print(hexdump( gef.memory.read(parse_address("$pc"), length=0x20 )))
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
```
```text
gef ➤ pi print('\n'.join([ f"{x.page_start:#x} -> {x.page_end:#x}" for x in gef.memory.maps]))
0x555555554000 -> 0x555555558000
0x555555558000 -> 0x55555556c000
@@ -154,9 +155,10 @@ 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
@@ -206,7 +208,7 @@ class MyCommand(GenericCommand):
When the user enters the following command:
```
```text
gef➤ mycommand --blah 3 14 159 2653
```
@@ -227,11 +229,13 @@ Sometimes architectures can more precisely determine whether they apply to the c
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.
* `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.
* `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 be used over the generic ARM
one:
+807 -807
View File
File diff suppressed because it is too large Load Diff
+8 -8
View File
@@ -2,7 +2,7 @@
Base command to add, remove, and list `GEF` defined aliases.
```
```text
gef➤ aliases
aliases (add|rm|list)
```
@@ -13,13 +13,13 @@ aliases (add|rm|list)
through the built-in command `alias`. To add a new alias, simply use the `aliases add` command. The
"command" parameter may contain spaces.
```
```text
aliases add [alias] [command]
```
To remove an alias, simply use the `aliases rm` command.
```
```text
aliases rm [alias]
```
@@ -28,7 +28,7 @@ aliases rm [alias]
One can list aliases by using the `aliases ls` command. Some sample output of this command is seen
below.
```
```text
[+] Aliases defined:
fmtstr-helper → format-string-helper
telescope → dereference
@@ -51,7 +51,7 @@ located at `~/.gef.rc`. The aliases must be in the `aliases` section of the conf
Creating a new alias is as simple as creating a new entry in this section:
```
```text
$ nano ~/.gef.rc
[...]
[aliases]
@@ -63,7 +63,7 @@ my-new-alias = gdb-or-gef-command <arg1> <arg2> <etc...>
For example, for those (like me) who use WinDBG and like its bindings, they can be integrated into
GDB via GEF aliases like this:
```
```text
$ nano ~/.gef.rc
[...]
[aliases]
@@ -91,7 +91,7 @@ uf = disassemble
Or here are some `PEDA` aliases for people used to using `PEDA` who made the smart move to `GEF`.
```
```text
# some peda aliases
telescope = dereference
start = entry-break
@@ -104,6 +104,6 @@ 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:
```
```text
gef➤ gef restore
```
+3 -3
View File
@@ -4,14 +4,14 @@ Easily check, enable or disable ASLR on the debugged binary.
Check the status:
```
```text
gef➤ aslr
ASLR is currently disabled
```
Activate ASLR:
```
```text
gef➤ aslr on
[+] Enabling ASLR
gef➤ aslr
@@ -20,7 +20,7 @@ ASLR is currently enabled
De-activate ASLR:
```
```text
gef➤ aslr off
[+] Disabling ASLR
```
+1 -1
View File
@@ -6,7 +6,7 @@ canary. This makes it convenient to avoid manually searching for this value in m
The command `canary` does not take any arguments.
```
```text
gef➤ canary
```
+2 -2
View File
@@ -1,11 +1,11 @@
## Command `checksec` ##
## 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.
You can use the command on the currently debugged process:
```
```text
gef➤ checksec
[+] checksec for '/vagrant/test-bin'
Canary: No
+6 -6
View File
@@ -1,4 +1,4 @@
## Command `gef config` ##
## 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
@@ -6,7 +6,7 @@ runtime with the `gef config` command.
To view all settings for all commands loaded:
```
```text
gef➤ gef config
```
@@ -14,21 +14,21 @@ gef➤ gef config
Or to get one setting value:
```
```text
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:
```
```text
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:
```
```text
gef➤ gef save
[+] Configuration saved to '/home/vagrant/.gef.rc'
```
@@ -38,7 +38,7 @@ Upon startup, if `$GEF_RC` points to an existing file, or otherwise if `${HOME}/
To reload the settings during the session, just run:
```
```text
gef➤ gef restore
[+] Configuration from '/home/hugsy/.gef.rc' restored
```
+51 -51
View File
@@ -1,19 +1,19 @@
## Command `context` ##
## Command `context`
![gef-context](https://i.imgur.com/aZiG8Yb.png)
`gef` (not unlike `PEDA` or `fG! famous gdbinit`) provides comprehensive context menu when hitting a
breakpoint.
* The register context box displays current register values. Values in red indicate that this
* The register context box displays current register values. Values in red indicate that this
register has had its value changed since the last time execution stopped. It makes it convenient
to track values. Register values can be also accessed and/or dereferenced through the `reg`
command.
* The stack context box shows the 10 (by default but can be tweaked) entries in memory pointed by
* The stack context box shows the 10 (by default but can be tweaked) entries in memory pointed by
the stack pointer register. If those values are pointers, they are successively dereferenced.
* The code context box shows the 10 (by default but can be tweaked) next instructions to be executed.
* The code context box shows the 10 (by default but can be tweaked) next instructions to be executed.
### Adding custom context panes ###
### Adding custom context panes
As well as using the built-in context panes, you can add your own custom pane that will be displayed
at each `break`-like event with all the other panes. Custom panes can be added using the API:
@@ -24,33 +24,33 @@ register_external_context_pane(pane_name, display_pane_function, pane_title_func
Check the [API](../api.md) documentation to see a full usage of the registration API.
### Editing context layout ###
### Editing context layout
`gef` allows you to configure your own setup for the display, by re-arranging the order with which
contexts will be displayed.
```
```text
gef➤ gef config context.layout
```
There are currently 6 sections that can be displayed:
* `legend` : a text explanation of the color code
* `regs` : the state of registers
* `stack` : the content of memory pointed by `$sp` register
* `code` : the code being executed
* `args` : if stopping at a function calls, print the call arguments
* `source` : if compiled with source, this will show the corresponding line of source code
* `threads` : all the threads
* `trace` : the execution call trace
* `extra` : if an automatic behavior is detected (vulnerable format string, heap vulnerability,
* `legend` : a text explanation of the color code
* `regs` : the state of registers
* `stack` : the content of memory pointed by `$sp` register
* `code` : the code being executed
* `args` : if stopping at a function calls, print the call arguments
* `source` : if compiled with source, this will show the corresponding line of source code
* `threads` : all the threads
* `trace` : the execution call trace
* `extra` : if an automatic behavior is detected (vulnerable format string, heap vulnerability,
etc.) it will be displayed in this pane
* `memory` : peek into arbitrary memory locations
* `memory` : peek into arbitrary memory locations
To hide a section, simply use the `context.layout` setting, and prepend the section name with `-` or
just omit it.
```
```text
gef➤ gef config context.layout "-legend regs stack code args -source -threads -trace extra memory"
```
@@ -59,7 +59,7 @@ This configuration will not display the `legend`, `source`, `threads`, and `trac
The `memory` pane will display the content of all locations specified by the
`memory` command. For instance,
```
```text
gef➤ memory watch $sp 0x40 byte
```
@@ -69,11 +69,11 @@ using `memory unwatch`, or altogether with `memory reset`.
The size of most sections are also customizable:
* `nb_lines_stack` configures how many lines of the stack to show.
* `nb_lines_backtrack` configures how many lines of the backtrace to show.
* `nb_lines_code` and `nb_lines_code_prev` configure how many lines to show after and before the PC,
* `nb_lines_stack` configures how many lines of the stack to show.
* `nb_lines_backtrack` configures how many lines of the backtrace to show.
* `nb_lines_code` and `nb_lines_code_prev` configure how many lines to show after and before the PC,
respectively.
* `context.nb_lines_threads` determines the number of lines to display inside the thread pane. This
* `context.nb_lines_threads` determines the number of lines to display inside the thread pane. This
is convenient when debugging heavily multi-threaded applications (apache2, firefox, etc.). It
receives an integer as value: if this value is `-1` then all threads state will be displayed.
Otherwise, if the value is set to `N`, then at most `N` thread states will be shown.
@@ -81,14 +81,14 @@ The size of most sections are also customizable:
To have the stack displayed with the largest stack addresses on top (i.e., grow the stack downward),
enable the following setting:
```
```text
gef➤ gef config context.grow_stack_down True
```
If the saved instruction pointer is not within the portion of the stack being displayed, then a
section is created that includes the saved ip and depending on the architecture the frame pointer.
```
```text
0x00007fffffffc9e8│+0x00: 0x00007ffff7a2d830 → <__main+240> mov edi, eax ($current_frame_savedip)
0x00007fffffffc9e0│+0x00: 0x00000000004008c0 → <__init+0> push r15 ← $rbp
. . . (440 bytes skipped)
@@ -102,7 +102,7 @@ section is created that includes the saved ip and depending on the architecture
0x00007fffffffc7b0│+0x00: 0x00007fffffffc7e4 → 0x0000000000000000 ← $rsp
```
### Redirecting context output to another tty/file ###
### Redirecting context output to another tty/file
By default, the `gef` context will be displayed on the current TTY. This can be overridden by
setting `context.redirect` variable to have the context sent to another section.
@@ -111,14 +111,14 @@ To do so, select the TTY/file/socket/etc. you want the context redirected to wit
Enter the command `tty` in the prompt:
```
```text
$ tty
/dev/pts/0
```
Then tell `gef` about it!
```
```text
gef➤ gef config context.redirect /dev/pts/0
```
@@ -127,77 +127,77 @@ Enjoy:
To go back to normal, remove the value:
```
```text
gef➤ gef config context.redirect ""
```
### Display individual sections ###
### Display individual sections
You can display a single section by specifying it as an argument:
```
```text
gef➤ context regs
```
Multiple sections can be provided, even if they are not part of the current layout:
```
```text
gef➤ context regs stack
```
### Examples ###
### Examples
* Display the code section first, then register, and stack, hiding everything else:
* Display the code section first, then register, and stack, hiding everything else:
```
```text
gef➤ gef config context.layout "code regs stack"
```
* Stop showing the context sections when breaking:
* Stop showing the context sections when breaking:
```
```text
gef➤ gef config context.enable 0
```
* Clear the screen before showing the context sections when breaking:
* Clear the screen before showing the context sections when breaking:
```
```text
gef➤ gef config context.clear_screen 1
```
* Don't dereference the registers in the `regs` section (more compact):
* Don't dereference the registers in the `regs` section (more compact):
```
```text
gef➤ gef config context.show_registers_raw 1
```
* Number of bytes of opcodes to display next to the disassembly.
* Number of bytes of opcodes to display next to the disassembly.
```
```text
gef➤ gef config context.show_opcodes_size 4
```
* Don't 'peek' into the start of functions that are called.
* Don't 'peek' into the start of functions that are called.
```
```text
gef➤ gef config context.peek_calls False
```
* Hide specific registers from the registers view.
* Hide specific registers from the registers view.
```
```text
gef➤ gef config context.ignore_registers "$cs $ds $gs"
```
* Hide the extra pc context info from the source code view.
* Hide the extra pc context info from the source code view.
```
```text
gef➤ gef config context.show_source_code_variable_values 0
```
* Show better definitions for call to libc functions.
* Show better definitions for call to libc functions.
```
```text
gef➤ gef config context.libc_args True
gef➤ gef config context.libc_args_path /path/to/gef-extras/libc_args
```
+5 -5
View File
@@ -10,7 +10,7 @@ It is a useful convienence function to spare to process of manually tracking val
dereference (by default, `$sp`), the number of consecutive addresses to dereference (by default,
`10`) and the base location for offset calculation (by default the same as the start address):
```
```text
gef➤ dereference
0x00007fffffffdec0│+0x0000: 0x00007ffff7ffe190 → 0x0000555555554000 → jg 0x555555554047 ← $rsp, $r13
0x00007fffffffdec8│+0x0008: 0x00007ffff7ffe730 → 0x00007ffff7fd3000 → 0x00010102464c457f
@@ -26,7 +26,7 @@ gef➤ dereference
Here is an example with arguments:
```
```text
gef➤ telescope $rbp+0x10 -l 8
0x00007fffffffdf40│+0x0000: 0x00007ffff7fa5760 → 0x00000000fbad2887
0x00007fffffffdf48│+0x0008: 0x00000001f7e65b63
@@ -44,7 +44,7 @@ default, `10`).
For example, if you want to dereference all the stack entries inside a function context (on a 64bit
architecture):
```
```text
gef➤ p ($rbp - $rsp)/8
$3 = 4
gef➤ dereference -l 5
@@ -57,7 +57,7 @@ gef➤ dereference -l 5
It is possible to change the offset calculation to use a different address than the start address:
```
```text
gef➤ dereference $sp -l 7 -r $rbp
0x00007ffe6ddaa3e0│-0x0030: 0x0000000000000000 ← $rsp
0x00007ffe6ddaa3e8│-0x0028: 0x0000000000400970 → <__libc_csu_init+0> push r15
@@ -71,7 +71,7 @@ gef➤ dereference $sp -l 7 -r $rbp
Just like with `x`, you can pass a negative number of addresses to dereference, to examine memory
backwards from the start address:
```
```text
gef➤ dereference $sp -l 3
0x00007fffffffcf90│+0x0010: 0x00007ffff7f5aaa0 → 0x0000000000000000
0x00007fffffffcf88│+0x0008: 0x00000000000204a0
+2 -2
View File
@@ -6,7 +6,7 @@ return a human-friendly display of the register flags.
One or many arguments can be provided, following the syntax below:
```
```text
gef➤ flags [(+|-|~)FLAGNAME ...]
```
@@ -16,7 +16,7 @@ whether to set, unset, or toggle the flag.
For instance, on x86 architecture, if we don't want to take a conditional jump (e.g. a `jz`
instruction), but we want to have the Carry flag set, simply go with:
```
```text
gef➤ flags -ZERO +CARRY
```
+2 -2
View File
@@ -2,7 +2,7 @@
`elf-info` (alias `elf`) provides some basic information on the currently loaded ELF binary:
```
```text
gef➤ elf
Magic : 7f 45 4c 46
Class : 0x2 - 64-bit
@@ -67,6 +67,6 @@ Entry point : 0x0000000000400750
Optionally a filepath to another ELF binary can be provided to view the basic information for that
binary instead.
```
```text
gef➤ elf-info --filename /path/to/elf/executable
```
+3 -3
View File
@@ -6,9 +6,9 @@ also be resolved, making further debugging easier.
It will perform the following actions:
1. Look up a `main` symbol. If found, set a temporary breakpoint and go.
2. Otherwise, it will look up for `__libc_start_main`. If found, set a temporary breakpoint and go.
3. Finally, if the previous two symbols are not found, it will get the entry point from the ELF
1. Look up a `main` symbol. If found, set a temporary breakpoint and go.
2. Otherwise, it will look up for `__libc_start_main`. If found, set a temporary breakpoint and go.
3. Finally, if the previous two symbols are not found, it will get the entry point from the ELF
header, set a breakpoint and run. This case should never fail if the ELF binary has a valid
structure.
+2 -2
View File
@@ -5,7 +5,7 @@ The `$` command attempts to mimic WinDBG `?` command.
When provided one argument, it will evaluate the expression, and try to display the result with
various formats:
```
```text
gef➤ $ $pc+1
93824992252977
0x555555559431
@@ -23,7 +23,7 @@ b'\x00\xf0\xff\xff\xff\xff\xff\xff'
With two arguments, it will simply compute the delta between them:
```
```text
gef➤ vmmap libc
Start End Offset Perm
0x00007ffff7812000 0x00007ffff79a7000 0x0000000000000000 r-x /lib/x86_64-linux-gnu/libc-2.24.so
+7 -7
View File
@@ -5,23 +5,23 @@ detecting potentially insecure format string when using the GlibC library.
It will use this new breakpoint against several targets, including:
* `printf()`
* `sprintf()`
* `fprintf()`
* `snprintf()`
* `vsnprintf()`
* `printf()`
* `sprintf()`
* `fprintf()`
* `snprintf()`
* `vsnprintf()`
Just call the command to enable this functionality.
`fmtstr-helper` is a shorter alias.
```
```text
gef➤ fmtstr-helper
```
Then start the binary execution.
```
```text
gef➤ r
```
+6 -6
View File
@@ -3,16 +3,16 @@
The `functions` command will list all of the [convenience
functions](https://sourceware.org/gdb/onlinedocs/gdb/Convenience-Funs.html) provided by GEF.
- `$_base([filepath])` -- Return the matching file's base address plus an optional offset.
- `$_base([filepath])` -- Return the matching file's base address plus an optional offset.
Defaults to the current file. Note that quotes need to be escaped.
- `$_bss([offset])` -- Return the current bss base address plus the given offset.
- `$_got([offset])` -- Return the current bss base address plus the given offset.
- `$_heap([offset])` -- Return the current heap base address plus an optional offset.
- `$_stack([offset])` -- Return the current stack base address plus an optional offset.
- `$_bss([offset])` -- Return the current bss base address plus the given offset.
- `$_got([offset])` -- Return the current bss base address plus the given offset.
- `$_heap([offset])` -- Return the current heap base address plus an optional offset.
- `$_stack([offset])` -- Return the current stack base address plus an optional offset.
These functions can be used as arguments to other commands to dynamically calculate values.
```
```text
gef➤ deref -l 4 $_heap()
0x0000000000602000│+0x00: 0x0000000000000000 ← $r8
0x0000000000602008│+0x08: 0x0000000000000021 ("!"?)
+8 -8
View File
@@ -11,9 +11,9 @@ process of debugging more cumbersome. GEF greatly improves that state with the `
`gef-remote` can function in 2 ways:
- `remote` which is meant to enrich use of GDB `target remote` command, when connecting to a "real"
- `remote` which is meant to enrich use of GDB `target remote` command, when connecting to a "real"
gdbserver instance
- `qemu-mode` when connecting to GDB stab of either `qemu-user` or `qemu-system`.
- `qemu-mode` when connecting to GDB stab of either `qemu-user` or `qemu-system`.
The reason for this difference being that Qemu provides *a lot* less information that GEF can
extract to enrich debugging. Whereas GDBServer allows to download remote file (therefore allowing to
@@ -30,7 +30,7 @@ to find the debug information.
For example, if we want to debug `uname`, we do on the server:
```
```text
$ gdbserver :1234 /tmp/default.out
Process /tmp/default.out created; pid = 258932
Listening on port 1234
@@ -41,7 +41,7 @@ Listening on port 1234
On the client, when the original `gdb` would use `target remote`, GEF's syntax is roughly similar
(shown running in debug mode for more verbose output, but you don't have to):
```
```text
$ gdb -ex 'gef config gef.debug 1'
GEF for linux ready, type `gef' to start, `gef config' to configure
90 commands loaded and 5 functions added for GDB 10.2 using Python engine 3.8
@@ -95,8 +95,8 @@ makes now even more sense 😉 And using it is very straight forward.
#### `qemu-user`
1. Run `qemu-x86_64 :1234 /bin/ls`
2. Use `--qemu-user` and `--qemu-binary /bin/ls` when starting `gef-remote`
1. Run `qemu-x86_64 :1234 /bin/ls`
2. Use `--qemu-user` and `--qemu-binary /bin/ls` when starting `gef-remote`
![qemu-user](https://user-images.githubusercontent.com/590234/175072835-e276ab6c-4f75-4313-9e66-9fe5a3fd220e.png)
@@ -105,7 +105,7 @@ makes now even more sense 😉 And using it is very straight forward.
To test locally, you can use the mini image linux x64 vm
[here](https://mega.nz/file/ldQCDQiR#yJWJ8RXAHTxREKVmR7Hnfr70tIAQDFeWSYj96SvPO1k).
1. Run `./run.sh`
2. Use `--qemu-user` and `--qemu-binary vmlinuz` when starting `gef-remote`
1. Run `./run.sh`
2. Use `--qemu-user` and `--qemu-binary vmlinuz` when starting `gef-remote`
![qemu-system](https://user-images.githubusercontent.com/590234/175071351-8e06aa27-dc61-4fd7-9215-c345dcebcd67.png)
+12 -12
View File
@@ -4,7 +4,7 @@
Displays a list of GEF commands and their descriptions.
```
```text
gef➤ gef
─────────────────────────────────── GEF - GDB Enhanced Features ───────────────────────────────────
$ -- SmartEval: Smart eval (vague approach to mimic WinDBG `?`).
@@ -24,7 +24,7 @@ GEF is fully battery-included. However in some rare cases, it is possible that n
loaded. If that's the case the command `gef missing` will detail which command failed to load, along
with a (likely) reason. Read the documentation for a solution, or reach out on the Discord.
```
```text
gef➤ gef missing
[*] Command `XXXX` is missing, reason → YYYYY.
```
@@ -36,7 +36,7 @@ persistent see the `gef save` entry.
Using `gef config` by itself just shows all of the available settings and their values.
```
```text
gef➤ gef config
──────────────────────────────────── GEF configuration settings ────────────────────────────────────
context.clear_screen (bool) = False
@@ -52,7 +52,7 @@ context.libc_args (bool) = False
To filter the config settings you can use `gef config [setting]`.
```
```text
gef➤ gef config theme
─────────────────────────── GEF configuration settings matching 'theme' ───────────────────────────
theme.context_title_line (str) = "gray"
@@ -67,7 +67,7 @@ theme.default_title_message (str) = "cyan"
You can use `gef config [setting] [value]` to set a setting for the current session (see example
below).
```
```text
gef➤ gef config theme.address_stack blue
```
@@ -76,7 +76,7 @@ gef➤ gef config theme.address_stack blue
The `gef save` command saves the current settings (set with `gef config`) to the user's `~/.gef.rc`
file (making the changes persistent).
```
```text
gef➤ gef save
[+] Configuration saved to '/home/michael/.gef.rc'
```
@@ -87,7 +87,7 @@ Using `gef restore` loads and applies settings from the `~/.gef.rc` file to the
This is useful if you are modifying your GEF configuration file and want to see the changes without
completely reloading GEF.
```
```text
gef➤ gef restore
[+] Configuration from '/home/michael/.gef.rc' restored
```
@@ -97,7 +97,7 @@ gef➤ gef restore
The GEF set command allows the user to use GEF context within GDB set commands. This is useful when
you want to make a convenient variable which can be set and referenced later.
```
```text
gef➤ gef set $a=1
```
@@ -106,7 +106,7 @@ gef➤ gef set $a=1
The GEF run command is a wrapper around GDB's run command, allowing the user to use GEF context
within the command.
```
```text
gef➤ gef run ./binary
```
@@ -115,14 +115,14 @@ gef➤ gef run ./binary
`gef install` allows to install one (or more) specific script(s) from `gef-extras`. The new scripts
will be downloaded and sourced to be used immediately after by GEF. The syntax is straight forward:
```
```text
gef➤ gef install SCRIPTNAME1 [SCRIPTNAME2...]
```
Where `SCRIPTNAME1` ... are the names of script from the [`gef-extras`
repository](https://github.com/hugsy/gef-extras/tree/main/scripts/).
```
```text
gef➤ gef install remote windbg stack
[+] Searching for 'remote.py' in `gef-extras@main`...
[+] Installed file '/tmp/gef/remote.py', new command(s) available: `rpyc-remote`
@@ -137,7 +137,7 @@ This makes it easier to deploy new functionalities in limited environment. By de
looks up for script names in the `main` branch of `gef-extras`. However you can change specify a
different branch through the `gef.default_branch` configuration setting:
```
```text
gef➤ gef config gef.default_branch my_other_branch
```
+3 -3
View File
@@ -5,7 +5,7 @@ Display the current state of GOT table of the running process.
The `got` command optionally takes function names and filters the output displaying only the
matching functions.
```
```text
gef➤ got
```
@@ -13,7 +13,7 @@ gef➤ got
The applied filter partially matches the name of the functions, so you can do something like this.
```
```text
gef➤ got str
gef➤ got print
gef➤ got read
@@ -23,7 +23,7 @@ gef➤ got read
Example of multiple partial filters:
```
```text
gef➤ got str get
```
+11 -11
View File
@@ -7,14 +7,14 @@ tracking and analyzing allocations and deallocations of chunks of memory.
Currently, the following issues can be tracked:
- NULL free
- Use-after-Free
- Double Free
- Heap overlap
- NULL free
- Use-after-Free
- Double Free
- Heap overlap
The helper can simply be activated by running the command `heap-analysis-helper`.
```
```text
gef➤ heap-analysis
[+] Tracking malloc()
[+] Tracking free()
@@ -30,13 +30,13 @@ enable/disable manually punctual checks via the `gef config` command.
The following settings are accepted:
- `check_null_free`: to break execution when a free(NULL) is encountered (disabled by default);
- `check_double_free`: to break execution when a double free is encountered;
- `check_null_free`: to break execution when a free(NULL) is encountered (disabled by default);
- `check_double_free`: to break execution when a double free is encountered;
![double-free](https://i.imgur.com/S7b4FJa.png)
- `check_weird_free`: to execution when `free()` is called against a non-tracked pointer;
- `check_uaf`: to break execution when a possible Use-after-Free condition is found.
- `check_weird_free`: to execution when `free()` is called against a non-tracked pointer;
- `check_uaf`: to break execution when a possible Use-after-Free condition is found.
![uaf](https://i.imgur.com/NfV5Cu9.png)
@@ -47,7 +47,7 @@ ascertained manually.
The `heap-analysis-helper` can also be used to simply track allocation and liberation of chunks of
memory. One can simply enable the tracking by setting all the configurations stated above to False:
```
```text
gef➤ gef config heap-analysis-helper.check_double_free False
gef➤ gef config heap-analysis-helper.check_free_null False
gef➤ gef config heap-analysis-helper.check_weird_free False
@@ -61,7 +61,7 @@ when a chunk is allocated/freed.
To get information regarding the currently tracked chunks, use the `show` subcommand:
```
```text
gef➤ heap-analysis-helper show
```
+27 -27
View File
@@ -5,36 +5,36 @@ only supports GlibC heap format (see [this
link](https://code.woboq.org/userspace/glibc/malloc/malloc.c.html#malloc_chunk) for `malloc`
structure information). Syntax to the subcommands is straight forward:
```
```text
gef➤ heap <sub_commands>
```
## `main_arena` symbol ###
## `main_arena` symbol
If the linked glibc of the target program does not have debugging symbols it might be tricky for GEF
to find the address of the `main_arena` which is needed for most of the `heap` subcommands. If you
know the offset of this symbol from the glibc base address you can use GEF's config to provide said
value:
```
```text
gef➤ gef config gef.main_arena_offset <offset>
```
If you do not know this offset and you want GEF to try and find it via bruteforce when executing a
`heap` command the next time, you can try this instead:
```
```text
gef➤ gef config gef.bruteforce_main_arena True
```
Note that this might take a few seconds to complete. If GEF does find the symbol you can then
calculate the offset to the libc base address and save it in the config.
### `heap chunks` command ###
### `heap chunks` command
Displays all the chunks from the `heap` section of the current arena.
```
```text
gef➤ heap chunks
```
@@ -43,7 +43,7 @@ gef➤ heap chunks
To select from which arena to display chunks either use the `heap set-arena` command or provide the
base address of the other arena like this:
```
```text
gef➤ heap chunks [arena_address]
```
@@ -51,7 +51,7 @@ gef➤ heap chunks [arena_address]
In order to display the chunks of all the available arenas at once use
```
```text
gef➤ heap chunks -a
```
@@ -62,12 +62,12 @@ re-aligns the chunks data start addresses to match Glibc's behavior. To be able
chunks as well, you can disable this with the `--allow-unaligned` flag. Note that this might result
in incorrect output.
### `heap chunk` command ###
### `heap chunk` command
This command gives visual information of a Glibc malloc-ed chunked. Simply provide the address to
the user memory pointer of the chunk to show the information related to a specific chunk:
```
```text
gef➤ heap chunk [address]
```
@@ -81,7 +81,7 @@ in incorrect output.
There is an optional `number` argument, to specify the number of chunks printed by this command. To
do so, simply provide the `--number` argument:
```
```text
gef➤ heap chunk --number 6 0x4e5400
Chunk(addr=0x4e5400, size=0xd0, flags=PREV_INUSE)
Chunk(addr=0x4e54d0, size=0x1a0, flags=PREV_INUSE)
@@ -92,7 +92,7 @@ Chunk(addr=0x4e6760, size=0x4c0, flags=PREV_INUSE)
```
### `heap arenas` command ###
### `heap arenas` command
Multi-threaded programs have different arenas, and the knowledge of the `main_arena` is not enough.
`gef` therefore provides the `arena` sub-commands to help you list all the arenas allocated in your
@@ -100,19 +100,19 @@ program **at the moment you call the command**.
![heap-arenas](https://i.imgur.com/RUTiADa.png)
### `heap set-arena` command ###
### `heap set-arena` command
In cases where the debug symbol are not present (e.g. statically stripped binary), it is possible to
instruct GEF to find the `main_arena` at a different location with the command:
```
```text
gef➤ heap set-arena [address]
```
If the arena address is correct, all `heap` commands will be functional, and use the specified
address for `main_arena`.
### `heap bins` command ###
### `heap bins` command
Glibc uses bins for keeping tracks of `free`d chunks. This is because making allocations through
`sbrk` (requiring a syscall) is costly. Glibc uses those bins to remember formerly allocated chunks.
@@ -120,14 +120,14 @@ Because bins are structured in single or doubly linked list, I found that quite
interrogate `gdb` to get a pointer address, dereference it, get the value chunk, etc... So I decided
to implement the `heap bins` sub-command, which allows to get info on:
- `fastbins`
- `bins`
- `unsorted`
- `small bins`
- `large bins`
- `tcachebins`
- `fastbins`
- `bins`
- `unsorted`
- `small bins`
- `large bins`
- `tcachebins`
#### `heap bins fast` command ####
#### `heap bins fast` command
When exploiting heap corruption vulnerabilities, it is sometimes convenient to know the state of the
`fastbinsY` array.
@@ -136,7 +136,7 @@ The `fast` sub-command helps by displaying the list of fast chunks in this array
argument, it will display the info of the `main_arena` arena. It accepts an optional argument, the
address of another arena (which you can easily find using `heap arenas`).
```
```text
gef➤ heap bins fast
──────────────────────── Fastbins for arena 0x7ffff7fb8b80 ────────────────────────
Fastbins[idx=0, size=0x20] ← Chunk(addr=0x555555559380, size=0x20, flags=PREV_INUSE)
@@ -148,19 +148,19 @@ Fastbins[idx=5, size=0x70] 0x00
Fastbins[idx=6, size=0x80] 0x00
```
#### Other `heap bins X` command ####
#### Other `heap bins X` command
All the other subcommands (with the exception of `tcache`) for the `heap bins` work the same way as
`fast`. If no argument is provided, `gef` will fall back to `main_arena`. Otherwise, it will use the
address pointed as the base of the `malloc_state` structure and print out information accordingly.
#### `heap bins tcache` command ####
#### `heap bins tcache` command
Modern versions of `glibc` use `tcache` bins to speed up multithreaded programs. Unlike other bins,
`tcache` bins are allocated on a per-thread basis, so there is one set of `tcache` bins for each
thread.
```
```text
gef➤ heap bins tcache [all] [thread_ids...]
```
@@ -169,6 +169,6 @@ bins tcache all` will show the `tcache`s for every thread, or you can specify an
ids to see the `tcache` for each of them. For example, use the following command to show the
`tcache` bins for threads 1 and 2.
```
```text
gef➤ heap bins tcache 1 2
```
+1 -1
View File
@@ -2,6 +2,6 @@
Displays the help menu for the loaded GEF commands.
```
```text
gef➤ gef help
```
+11 -11
View File
@@ -4,26 +4,26 @@ Imitation of the WinDBG command.
This command takes 4 optional arguments:
- The format for representing the data (by default, byte)
- A value/address/symbol used as the location to print the hexdump from (by default, $sp)
- The number of qword/dword/word/bytes to display (by default, 64 if the format is byte, 16
- The format for representing the data (by default, byte)
- A value/address/symbol used as the location to print the hexdump from (by default, $sp)
- The number of qword/dword/word/bytes to display (by default, 64 if the format is byte, 16
otherwise)
- The direction of output lines (by default, from low to high addresses)
- The direction of output lines (by default, from low to high addresses)
`hexdump byte` will also try to display the ASCII character values if the byte is printable
(similarly to the `hexdump -C` command on Linux).
The syntax is as following:
```
```text
hexdump (qword|dword|word|byte) [-h] [--reverse] [--size SIZE] [address]
```
Examples:
- Display 4 QWORDs from `$pc`:
- Display 4 QWORDs from `$pc`:
```
```text
gef➤ hexdump qword $pc --size 4
0x7ffff7a5c1c0+0000 │ 0x4855544155415641
0x7ffff7a5c1c0+0008 │ 0x0090ec814853cd89
@@ -31,17 +31,17 @@ gef➤ hexdump qword $pc --size 4
0x7ffff7a5c1c0+0018 │ 0x748918247c894800
```
- Display 32 bytes from a location in the stack:
- Display 32 bytes from a location in the stack:
```
```text
gef➤ hexdump byte 0x00007fffffffe5e5 --size 32
0x00007fffffffe5e5 2f 68 6f 6d 65 2f 68 75 67 73 79 2f 63 6f 64 65 /home/hugsy/code
0x00007fffffffe5f5 2f 67 65 66 2f 74 65 73 74 73 2f 77 69 6e 00 41 /gef/tests/win.A
```
- Display 8 WORDs from `$sp` in reverse order:
- Display 8 WORDs from `$sp` in reverse order:
```
```text
gef➤ hexdump word 8 --reverse
0x00007fffffffe0ee│+0x000e 0x0000
0x00007fffffffe0ec│+0x000c 0x7fff
+8 -8
View File
@@ -4,20 +4,20 @@ This command sets up custom highlighting for user set strings.
Syntax:
```
```text
highlight (add|remove|list|clear)
```
Alias:
- `hl`
- `hl`
## Adding matches
The following will add `41414141`/`'AAAA'` as yellow, and `42424242`/`'BBBB'`
as blue:
```
```text
gef➤ hl add 41414141 yellow
gef➤ hl add 42424242 blue
gef➤ hl add AAAA yellow
@@ -28,7 +28,7 @@ gef➤ hl add BBBB blue
To remove a match, target it by the original string used, ex.:
```
```text
gef➤ hl rm 41414141
```
@@ -36,7 +36,7 @@ gef➤ hl rm 41414141
To list all matches with their colors:
```
```text
gef➤ hl list
41414141 | yellow
42424242 | blue
@@ -48,7 +48,7 @@ BBBB | blue
To clear all matches currently setup:
```
```text
gef➤ hl clear
```
@@ -58,13 +58,13 @@ RegEx support is disabled by default, this is done for performance reasons.
To enable regular expressions on text matches:
```
```text
gef➤ gef config highlight.regex True
```
To check the current status:
```
```text
gef➤ gef config highlight.regex
highlight.regex (bool) = True
```
+3 -3
View File
@@ -5,13 +5,13 @@ file descriptor can point to a file, a pipe, a socket, a device etc.
To use it, simply run
```
```text
gef➤ hijack-fd FDNUM NEWFILE
```
For instance,
```
```text
gef➤ hijack-fd 1 /dev/null
```
@@ -21,7 +21,7 @@ Will modify the current process file descriptors to redirect STDOUT to
This command also supports connecting to an ip:port if it is provided as an
argument. For example
```
```text
gef➤ hijack-fd 0 localhost:8888
```
+2 -2
View File
@@ -4,13 +4,13 @@
The syntax is straight forward:
```
```text
ksymaddr <PATTERN>
```
For example,
```
```text
gef➤ ksymaddr commit_creds
[+] Found matching symbol for 'commit_creds' at 0xffffffff8f495740 (type=T)
[*] Found partial match for 'commit_creds' at 0xffffffff8f495740 (type=T): commit_creds
+10 -8
View File
@@ -15,7 +15,7 @@ Specify a location to watch and display with the context, along with their optio
Syntax:
```
```text
memory watch <ADDRESS> [SIZE] [(qword|dword|word|byte|pointers)]
```
@@ -28,16 +28,17 @@ functions
format](https://www.technovelty.org/linux/plt-and-got-the-key-to-code-sharing-and-dynamic-libraries.html)
allowing to easily track commonly used addresses:
For example, to watch the first 5 entries of the [GOT]() as pointers:
For example, to watch the first 5 entries of the [GOT](https://hugsy.github.io/gef/functions/got/)
as pointers:
```
```text
gef ➤ memory watch $_got()+0x18 5
[+] Adding memwatch to 0x555555773c50
```
Which, when the `context` is displayed, will show something like:
![](https://i.imgur.com/3YabwYv.png)
![gef-context-memory](https://i.imgur.com/3YabwYv.png)
### Removing a watch
@@ -45,7 +46,7 @@ Remove a watched address. To list all the addresses being watched, use `memory l
Syntax:
```
```text
memory unwatch <ADDRESS>
```
@@ -55,11 +56,12 @@ Enumerate all the addresses currently watched by the `memory` command.
Syntax:
```
```text
memory list
```
The command will output a list of all the addresses watched, along with the size and format to display them as.
The command will output a list of all the addresses watched, along with the size and format to
display them as.
### Resetting watches
@@ -67,6 +69,6 @@ Empties the list of addresses to watch.
Syntax:
```
```text
memory reset
```
+5 -5
View File
@@ -13,14 +13,14 @@ make it easier to keep an overview when using multiple breakpoints in a stripped
Examples:
- `nb first *0x400ec0`
- `nb "main func" main`
- `nb read_secret *main+149`
- `nb check_heap`
- `nb first *0x400ec0`
- `nb "main func" main`
- `nb read_secret *main+149`
- `nb check_heap`
Example output:
```
```text
─────────────────────────────────────────────────────────────────────────── code:x86:64 ────
0x400e04 add eax, 0xfffbe6e8
0x400e09 dec ecx
+8 -8
View File
@@ -2,7 +2,7 @@
The `nop` command allows you to easily patch instructions with nops.
```
```text
nop [LOCATION] [--i ITEMS] [--f] [--n] [--b]
```
@@ -19,42 +19,42 @@ instructions it overwrites
nop the current instruction ($pc):
```bash
```text
gef➤ nop
```
nop an instruction at $pc+3 address:
```bash
```text
gef➤ nop $pc+3
```
nop two instructions at address $pc+3:
```bash
```text
gef➤ nop --i 2 $pc+3
```
Replace 1 byte with nop at current instruction ($pc):
```bash
```text
gef➤ nop --b
```
Replace 1 byte with nop at address $pc+3:
```bash
```text
gef➤ nop --b $pc+3
```
Replace 2 bytes with nop(s) (breaking the last instruction) at address $pc+3:
```bash
```text
gef➤ nop --f --b --i 2 $pc+3
```
Patch 2 nops at address $pc+3:
```bash
```text
gef➤ nop --n --i 2 $pc+3
```
+1 -1
View File
@@ -9,7 +9,7 @@ gef➤ patch string $eip "cool!"
These commands copy the first 10 bytes of $rsp+8 to $rip:
```
```text
gef➤ print-format --lang bytearray -l 10 $rsp+8
Saved data b'\xcb\xe3\xff\xff\xff\x7f\x00\x00\x00\x00'... in '$_gef0'
gef➤ patch byte $rip $_gef0
+6 -6
View File
@@ -7,9 +7,9 @@ unique substrings of a chosen length.
It should be noted that for better compatibility, the algorithm implemented in `GEF` is the same as
the one in `pwntools`, and can therefore be used in conjunction.
### `pattern create` ###
### `pattern create`
```
```text
pattern create [-h] [-n N] [length]
```
@@ -17,7 +17,7 @@ The sub-command `create` allows one create a new De Bruijn sequence. The optiona
determines the length of unique subsequences. Its default value matches the currently loaded
architecture. The `length` argument sets the total length of the whole sequence.
```
```text
gef➤ pattern create -n 4 128
[+] Generating a pattern of 128 bytes (n=4)
aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaab
@@ -31,9 +31,9 @@ from pwn import *
p = cyclic(128, n=8)
```
### `pattern search` ###
### `pattern search`
```
```text
pattern search [-h] [-n N] [--max-length MAX_LENGTH] [pattern]
```
@@ -45,7 +45,7 @@ to search in can be adjusted.
Note that the `pattern` can be passed as a GDB symbol (such as a register name), a string or a
hexadecimal value
```
```text
gef➤ pattern search 0x6161616161616167
[+] Searching '0x6161616161616167'
[+] Found at offset 48 (little-endian search) likely
+15 -14
View File
@@ -13,7 +13,7 @@ extension`](https://github.com/hugsy/gef-extras/blob/main/scripts/windbg.py)
New structures can be stored in the location given by the configuration setting:
```
```text
gef➤ gef config pcustom.struct_path
```
@@ -22,13 +22,13 @@ structure can be created as a simple `ctypes` structure, in a file called `<stru
You can naturally set this path to a new location
```
```text
gef➤ gef config pcustom.struct_path /my/new/location
```
And save this change so you can re-use it directly next time you use `gdb`
```
```text
gef➤ gef save
[+] Configuration saved to '~/.gef.rc'
```
@@ -37,7 +37,7 @@ gef➤ gef save
You can list existing custom structures via
```
```text
gef➤ pcustom list
[+] Listing custom structures from '/tmp/structs'
→ /tmp/structs/A.py (A, B)
@@ -50,7 +50,7 @@ To create or edit a structure, use `pcustom edit <struct_name>` to spawn your ED
targeted structure. If the file does not exist, `gef` will nicely create the tree and file, and fill
it with a `ctypes` template that you can use straight away!
```
```text
gef➤ pcustom new mystruct_t
[+] Creating '/tmp/gef/structs/mystruct_t.py' from template
```
@@ -58,7 +58,7 @@ gef➤ pcustom new mystruct_t
If the structure already exists, GEF will open the text editor to edit the known structure. This is
equivalent to:
```
```text
gef➤ pcustom edit elf32_t
[+] Editing '/home/hugsy/code/gef-extras/structs/elf32_t.py'
```
@@ -100,7 +100,7 @@ class person_t(Structure):
`pcustom` requires at least one argument, which is the name of the structure. With only one
argument, `pcustom` will dump all the fields of this structure.
```
```text
gef➤ dt person_t
+0000 age c_int /* size=0x4 */
+0004 name c_char_Array_256 /* size=0x100 */
@@ -120,7 +120,8 @@ For a full demo, watch the following tutorial:
Additionally, if you have successfully configured your IDA settings, you can also directly import
the structure(s) that was(were) reverse-engineered in IDA directly in your GDB session:
![ida-structure-examples](https://i.imgur.com/Tnsf6nt.png) - (see `gef-extras/ida-rpyc`, which is the new improved version of `ida-interact`)
![ida-structure-examples](https://i.imgur.com/Tnsf6nt.png) - (see `gef-extras/ida-rpyc`, which is
the new improved version of `ida-interact`)
#### Dynamic `ctypes.Structure`-like classes
@@ -131,9 +132,9 @@ currently debugged binary, the architecture, the size of a pointer and more).
The syntax is relatively close to the way we use to create static classes (see above), but instead
we define a function that will generate the class. The requirements for this class factory are:
- take a single [`Gef`](https://github.com/hugsy/gef/blob/main/docs/api/gef.md#class-gef) positional
argument
- End the function name with `_t`
- Take a single [`Gef`](https://github.com/hugsy/gef/blob/main/docs/api/gef.md#class-gef)
positional argument
- End the function name with `_t`
To continue the `person_t` function we defined in the example above, we could modify the static
class as a dynamic one very easily:
@@ -190,13 +191,13 @@ A community contributed repository of structures can be found in
In bash:
```
```text
git clone https://github.com/hugsy/gef-extras
```
In GEF:
```
```text
gef➤ gef config pcustom.struct_path /path/to/gef-extras/structs
gef➤ gef save
```
@@ -204,7 +205,7 @@ gef➤ gef save
Then either close GDB or `gef reload`. You can confirm the structures were correctly loaded in GEF's
prompt:
```
```text
gef➤ pcustom list
```
+11 -11
View File
@@ -1,4 +1,4 @@
## Command `pie` ##
## Command `pie`
The `pie` command is handy when working with position-independent executables. At runtime, it can
automatically resolve addresses for breakpoints that are not static.
@@ -6,7 +6,7 @@ automatically resolve addresses for breakpoints that are not static.
Note that you need to use the **entire `pie` command series** to support PIE breakpoints, especially
the "`pie` run commands", like `pie attach`, `pie run`, etc.
### `pie breakpoint` command ###
### `pie breakpoint` command
This command sets a new PIE breakpoint. It can be used like the normal `breakpoint` command in gdb.
The argument for the command is the offset from the base address or a symbol. The breakpoints will
@@ -15,18 +15,18 @@ run` or `pie remote` to actually attach to a process, so it can resolve the righ
Usage:
```
```text
gef➤ pie breakpoint OFFSET
```
### `pie info` command ###
### `pie info` command
Since a PIE breakpoint is not a real breakpoint, this command provides a way to observe the state of
all PIE breakpoints.
This works just like `info breakpoint` in gdb.
```
```text
gef➤ pie info
VNum Num Addr
1 N/A 0xdeadbeef
@@ -39,29 +39,29 @@ You can omit the VNum argument to get info on all PIE breakpoints.
Usage:
```
```text
gef➤ pie info [VNum]
```
### `pie delete` command ###
### `pie delete` command
This command deletes a PIE breakpoint given its VNum.
Usage:
```
```text
gef➤ pie delete [VNum]
```
### `pie attach` command ###
### `pie attach` command
This command behaves like GDB's `attach` command. Always use this command instead of `attach` if you
have PIE breakpoints. This will convert the PIE breakpoints to real breakpoints at runtime.
The usage is just the same as `attach`.
### `pie remote` command ###
### `pie remote` command
This command behaves like GDB's `remote` command. Always use this command instead of `remote` if you
have PIE breakpoints. Behind the scenes this will connect to the remote target using `gef remote`
@@ -69,7 +69,7 @@ and then convert the PIE breakpoints to real breakpoints at runtime.
The usage is just the same as `remote`.
### `pie run` command ###
### `pie run` command
This command behaves like GDB's `run` command. Always use this command instead of `run` if you have
PIE breakpoints. This will convert the PIE breakpoints to real breakpoints at runtime.
+9 -9
View File
@@ -3,14 +3,14 @@
The command `print-format` (alias `pf`) will dump an arbitrary location as an array of bytes
following the format specified. Currently, the output formats supported are
- Python (`py` - default)
- C (`c`)
- Assembly (`asm`)
- Javascript (`js`)
- Hex string (`hex`)
- For patch byte command or GDB $_gef[N] byte access (`bytearray`)
- Python (`py` - default)
- C (`c`)
- Assembly (`asm`)
- Javascript (`js`)
- Hex string (`hex`)
- For patch byte command or GDB $_gef[N] byte access (`bytearray`)
```
```text
gef➤ print-format -h
[+] print-format [--lang LANG] [--bitlen SIZE] [(--length,-l) LENGTH] [--clip] LOCATION
--lang LANG specifies the output format for programming language (available: ['py', 'c', 'js', 'asm', 'hex'], default 'py').
@@ -22,7 +22,7 @@ gef➤ print-format -h
For example this command will dump 10 bytes from `$rsp` and copy the result to the clipboard.
```
```text
gef➤ print-format --lang py --bitlen 8 -l 10 --clip $rsp
[+] Copied to clipboard
buf = [0x87, 0xfa, 0xa3, 0xf7, 0xff, 0x7f, 0x0, 0x0, 0x30, 0xe6]
@@ -30,7 +30,7 @@ buf = [0x87, 0xfa, 0xa3, 0xf7, 0xff, 0x7f, 0x0, 0x0, 0x30, 0xe6]
These commands copy the first 10 bytes of $rsp+8 to $rip:
```
```text
gef➤ print-format --lang bytearray -l 10 $rsp+8
Saved data b'\xcb\xe3\xff\xff\xff\x7f\x00\x00\x00\x00'... in '$_gef0'
gef➤ display/x $_gef0[5]
+6 -6
View File
@@ -6,7 +6,7 @@ tcp/listening daemon that would fork upon `accept()`).
Without argument, it will return all processes reachable by user:
```
```text
gef➤ ps
1 root 0.0 0.4 ? /sbin/init
2 root 0.0 0.0 ? [kthreadd]
@@ -24,7 +24,7 @@ gef➤ ps
Or to filter with pattern:
```
```text
gef➤ ps bash
22590 vagrant 0.0 0.8 pts/0 -bash
```
@@ -33,20 +33,20 @@ Note: Use "\\" for escaping and "\\\\" for a literal backslash" in the pattern.
`ps` also accepts options:
* `--smart-scan` will filter out probably less relevant processes (belonging to different users,
* `--smart-scan` will filter out probably less relevant processes (belonging to different users,
pattern matched to arguments instead of the commands themselves, etc.)
* `--attach` will automatically attach to the first process found
* `--attach` will automatically attach to the first process found
So, for example, if your targeted process is called `/home/foobar/plop`, but the existing instance
is used through `socat`, like
```
```text
socat tcp-l:1234,fork,reuseaddr exec:/home/foobar/plop
```
Then every time a new connection is opened to tcp/1234, `plop` will be forked, and GEF can easily
attach to it with the command
```
```text
gef➤ ps --attach --smart-scan plop
```
+1 -1
View File
@@ -6,7 +6,7 @@
information provided by GDB `info proc` command, with all the information from the `procfs`
structure.
```
```text
gef➤ ps --smart-scan zsh
22879
gef➤ attach 22879
+3 -3
View File
@@ -4,7 +4,7 @@ The `registers` command will print all the registers and dereference any pointer
Example on a MIPS host:
```
```text
gef➤ reg
$zero : 0x00000000
$at : 0x00000001
@@ -48,12 +48,12 @@ $ra : 0x77e5e834 -> <__libc_start_main+260>: lw gp,16(sp)
$gp : 0x00418b20
```
### Filtering registers ###
### Filtering registers
If one or more register names are passed to the `registers` command as optional arguments, then only
those will be shown:
```
```text
gef➤ reg $rax $rip $rsp
$rax : 0x0000555555555169 → <main+0> endbr64
$rsp : 0x00007fffffffe3e8 → 0x00007ffff7df40b3 → <__libc_start_main+243> mov edi, eax
+3 -3
View File
@@ -5,7 +5,7 @@ lists all results.
Usage:
```
```text
gef➤ scan NEEDLE HAYSTACK
```
@@ -13,7 +13,7 @@ gef➤ scan NEEDLE HAYSTACK
is what will be searched for. The arguments are grepped against the process's memory mappings (just
like [vmmap](./vmmap.md)) to determine the memory ranges to search.
```
```text
gef➤ scan stack libc
[+] Searching for addresses in 'stack' that point to 'libc'
[stack]: 0x00007fffffffd6a8│+0x1f6a8: 0x00007ffff77cf482 → "__tunable_get_val"
@@ -24,7 +24,7 @@ gef➤ scan stack libc
[...]
```
### Advanced Needle/Haystack syntax ###
### Advanced Needle/Haystack syntax
To check mappings without a path associated, an address range (start-end) can be used. Note that
ranges don't include whitespaces.
+6 -6
View File
@@ -3,7 +3,7 @@
`gef` allows you to search for a specific pattern at runtime in all the segments of your process
memory layout. The command `search-pattern`, alias `grep`, aims to be straight-forward to use:
```
```text
gef➤ search-pattern MyPattern
```
@@ -15,7 +15,7 @@ section it/they was/were found, and the permission associated to that section.
`search-pattern` can also be used to search for addresses. To do so, simply ensure that your pattern
starts with `0x` and is a valid hex address. For example:
```
```text
gef➤ search-pattern 0x4005f6
```
@@ -25,23 +25,23 @@ The `search-pattern` command can also be used as a way to search for cross-refer
For this reason, the alias `xref` also points to the command `search-pattern`. Therefore the
command above is equivalent to `xref 0x4005f6` which makes it more intuitive to use.
### Searching in a specific range ###
### Searching in a specific range
Sometimes, you may need to search for a very common pattern. To limit the search space, you can also
specify an address range or the section to be checked.
```
```text
gef➤ search-pattern 0x4005f6 little libc
gef➤ search-pattern 0x4005f6 little 0x603100-0x603200
```
### Searching in a specific range using regex ###
### Searching in a specific range using regex
Sometimes, you may need an advanced search using regex. Just use --regex arg.
Example: how to find null-end-printable(from x20-x7e) C strings (min size >=2 bytes) with a regex:
```
```text
gef➤ search-pattern --regex 0x401000 0x401500 ([\\x20-\\x7E]{2,})(?=\\x00)
```
+1 -1
View File
@@ -4,7 +4,7 @@
search and download directly via `GEF` the shellcode you're looking for. Two primitive subcommands
are available, `search` and `get`
```
```text
gef➤ shellcode search arm
[+] Showing matching shellcodes
901 Linux/ARM Add map in /etc/hosts file - 79 bytes
+1 -1
View File
@@ -2,7 +2,7 @@
The `skipi` command allows you to easily skip instructions execution.
```
```text
skipi [LOCATION] [--n NUM_INSTRUCTIONS]
```
+4 -4
View File
@@ -2,7 +2,7 @@
The `stub` command allows you stub out functions, optionally specifying the return value.
```
```text
gef➤ stub [-h] [--retval RETVAL] [address]
```
@@ -17,14 +17,14 @@ fact drop us into the "child" process. It must be noted that this is a different
classic `set follow-fork-mode child` since here we do not spawn a new process, we only trick the
parent process into thinking it has become the child.
### Example ###
### Example
Patching `fork()` calls:
* Without stub:
* Without stub:
![fork execution](https://i.imgur.com/TjnTDot.png)
* With stub:
* With stub:
![stubbed fork](https://i.imgur.com/CllTnRH.png)
+12 -12
View File
@@ -2,7 +2,7 @@
Customize `GEF` by changing its color scheme.
```
```text
gef➤ theme
context_title_message : red bold
default_title_message : red bold
@@ -20,23 +20,23 @@ value.
Colors can be one of the following:
- red
- green
- blue
- yellow
- gray
- pink
- red
- green
- blue
- yellow
- gray
- pink
Color also accepts the following attributes:
- bold
- underline
- highlight
- blink
- bold
- underline
- highlight
- blink
Any other will value simply be ignored.
```
```text
gef➤ theme context_title_message blue bold foobar
gef➤ theme
context_title_message : blue bold
+5 -5
View File
@@ -3,18 +3,18 @@
In the purpose of always making debugging sessions easier while being more effective, `GEF`
integrates two commands:
* `tmux-setup`
* `screen-setup`
* `tmux-setup`
* `screen-setup`
Those commands will check whether GDB is being spawn from inside a `tmux` (resp. `screen`) session,
and if so, will split the pane vertically, and configure the context to be redirected to the new
pane, looking something like:
![](https://i.imgur.com/Khk3xGl.png)
![gef-tmux-setup](https://i.imgur.com/Khk3xGl.png)
To set it up, simply enter
```
```text
gef➤ tmux-setup
```
@@ -22,7 +22,7 @@ gef➤ tmux-setup
a very clean way to do this. Therefore, if possible, it would be recommended to use the `tmux-setup`
command instead.
### Possible color issues with tmux ###
### Possible color issues with tmux
On Linux tmux only supports 8 colors with some terminal capabilities (`$TERM` environment variable).
This can mess up your color themes when using GEF with tmux. To remedy this if your terminal
+1 -1
View File
@@ -7,7 +7,7 @@ the path taken by a specific execution. It should be used with the IDA script
It will trace and store all values taken by `$pc` during the execution flow, from its current value,
until the value provided as argument.
```
```text
gef> trace-run <address_of_last_instruction_to_trace>
```
+4 -4
View File
@@ -2,11 +2,11 @@
Print out version information about your current gdb environment.
### Usage Examples ###
### Usage Examples
When GEF is located in a directory tracked with git:
```
```text
gef➤ version
GEF: rev:48a9fd74dd39db524fb395e7db528f85cc49d081 (Git - clean)
SHA1(/gef/rules/gef.py): 848cdc87ba7c3e99e8129ad820c9fcc0973b1e99
@@ -16,7 +16,7 @@ GDB-Python: 3.8
Otherwise the command shows the `standalone` information:
```
```text
gef➤ version
GEF: (Standalone)
Blob Hash(/gef/rules/gef.py): f0aef0f481e8157006b26690bd121585d3befee0
@@ -27,7 +27,7 @@ GDB-Python: 3.8
The `Blob Hash` can be used to easily find the git commit(s) matching this file revision.
```
```text
git log --oneline --find-object <BLOB_HASH>
```
+17 -13
View File
@@ -4,25 +4,29 @@ This command is used to XOR a block of memory.
Its syntax is:
```
```text
xor-memory <display|patch> <address> <size_to_read> <xor_key>
```
The first argument (`display` or `patch`) is the action to perform:
1. `display` will only show an hexdump of the result of the XOR-ed memory block, without writing the
- `display` will only show an hexdump of the result of the XOR-ed memory block, without writing the
debuggee's memory.
gef➤ xor display $rsp 16 1337
[+] Displaying XOR-ing 0x7fff589b67f8-0x7fff589b6808 with '1337'
────────────────────────────────[ Original block ]────────────────────────────────────
0x00007fff589b67f8 46 4e 40 00 00 00 00 00 00 00 00 00 00 00 00 00 FN@.............
────────────────────────────────[ XOR-ed block ]──────────────────────────────────────
0x00007fff589b67f8 55 79 53 37 13 37 13 37 13 37 13 37 13 37 13 37 UyS7.7.7.7.7.7.7
```text
gef➤ xor display $rsp 16 1337
[+] Displaying XOR-ing 0x7fff589b67f8-0x7fff589b6808 with '1337'
────────────────────────────────[ Original block ]────────────────────────────────────
0x00007fff589b67f8 46 4e 40 00 00 00 00 00 00 00 00 00 00 00 00 00 FN@.............
────────────────────────────────[ XOR-ed block ]──────────────────────────────────────
0x00007fff589b67f8 55 79 53 37 13 37 13 37 13 37 13 37 13 37 13 37 UyS7.7.7.7.7.7.7
```
2. `patch` will overwrite the memory with the xor-ed content.
- `patch` will overwrite the memory with the xor-ed content.
gef➤ xor patch $rsp 16 1337
[+] Patching XOR-ing 0x7fff589b67f8-0x7fff589b6808 with '1337'
gef➤ hexdump byte $rsp 16
0x00007fff589b67f8 55 79 53 37 13 37 13 37 13 37 UyS7.7.7.7
```text
gef➤ xor patch $rsp 16 1337
[+] Patching XOR-ing 0x7fff589b67f8-0x7fff589b6808 with '1337'
gef➤ hexdump byte $rsp 16
0x00007fff589b67f8 55 79 53 37 13 37 13 37 13 37 UyS7.7.7.7
```
+3 -3
View File
@@ -1,12 +1,12 @@
# GEF Compatibility
## GEF Compatibility
This matrix indicates the version of Python and/or GDB
| GEF version | GDB Python compatibility* | Python compatibility* |
| GEF version | GDB Python compatibility* | Python compatibility** |
|:--:|:--:|:--:|
| [2018.02](https://github.com/hugsy/gef/releases/tag/2018.02) | 7.2 | Python 2.7, Python 3.4+ |
| [2020.03](https://github.com/hugsy/gef/releases/tag/2020.03) | 7.4 | Python 2.7, Python 3.4+ |
| [2022.01](https://github.com/hugsy/gef/releases/tag/2021.01) | 7.7 | Python 3.4+ |
| [Current](https://github.com/hugsy/gef/tree/main) | 8.0+ | Python 3.6+ |
* Up to - included
** Up to (included)
+2 -2
View File
@@ -23,14 +23,14 @@ will simply dump all known settings:
To update, follow the syntax
```
```text
gef➤ gef config <Module>.<ModuleSetting> <Value>
```
Any setting updated this way will be specific to the current GDB session. To
make permanent, use the following command
```
```text
gef➤ gef save
```
+1 -1
View File
@@ -1,4 +1,4 @@
# Deprecated commands
## Deprecated commands
GEF is in itself a large file, but to avoid it to be out of control some commands once part of GEF
were either moved to [GEF-Extras](https://github.com/hugsy/gef-extras) or even simply removed. This
+17 -17
View File
@@ -1,6 +1,6 @@
# Frequently Asked Questions #
## Frequently Asked Questions
## Why use GEF over PEDA? ##
## Why use GEF over PEDA?
[PEDA](https://github.com/longld/peda) is a fantastic tool that provides similar commands to make
the exploitation development process smoother.
@@ -13,7 +13,7 @@ new architectures very easily as well!
Also, PEDA development has been quite idle for a few years now, and many new interesting features a
debugger can provide simply do not exist.
## What if my GDB is < 8.0 ? ##
## What if my GDB is < 8.0 ?
GDB was introduced with its Python support early 2011 with the release of GDB 7. A (very) long way
has gone since and the Python API has been massively improved, and GEF is taking advantage of them
@@ -34,7 +34,7 @@ If you are running an obsolete version, GEF will show a error and message and ex
Some pre-compiled static binaries for both recent GDB and GDBServer can be downloaded from the
[`gdb-static`](https://github.com/hugsy/gdb-static) repository.
## I cannot get GEF setup ##
## I cannot get GEF setup
GEF will work on any GDB 8+ compiled with Python 3.6+ support. You can view that commands that
failed to load using `gef missing`, but this will not affect GEF generally.
@@ -49,12 +49,12 @@ All recent distributions ship packaged GDB that should be ready-to-go, with a GD
3.6+. Any version higher or equal will work just fine. So you might actually only need to run `apt
install gdb` to get the full-force of GEF.
## I get a SegFault when starting GDB with GEF ##
## I get a SegFault when starting GDB with GEF
A long standing bug in the `readline` library can make `gef` crash GDB when displaying certain
characters (SOH/ETX). As a result, this would SIGSEGV GDB as `gef` is loading, a bit like this:
```
```text
root@debian-aarch64:~# gdb -q ./test-bin-aarch64
GEF ready, type `gef' to start, `gef config' to configure
53 commands loaded, using Python engine 3.4
@@ -67,7 +67,7 @@ Segmentation fault (core dumped)
If so, this can be fixed easily by setting the `gef.readline_compat` variable to `True` in the
`~/.gef.rc` file. Something like this:
```
```text
root@debian-aarch64:~# nano ~/.gef.rc
[...]
[gef]
@@ -77,20 +77,20 @@ readline_compat = True
You can now use all features of `gef` even on versions of GDB compiled against old `readline`
library.
## Does GEF prevent the use of other GDB plugins? ##
## Does GEF prevent the use of other GDB plugins?
Definitely not! You can use any other GDB plugin on top of it for an even better debugging
experience.
Some interesting plugins highly recommended too:
- [!exploitable](https://github.com/jfoote/exploitable/)
- [Voltron](https://github.com/snare/voltron)
- [!exploitable](https://github.com/jfoote/exploitable/)
- [Voltron](https://github.com/snare/voltron)
![voltron](https://i.imgur.com/bfTIjNi.jpg)
Src: [@rick2600: terminator + gdb + gef + voltron cc: @snare @_hugsy_](https://twitter.com/rick2600/status/775926070566490113)
## I want to contribute, where should I head first? ##
## I want to contribute, where should I head first?
I would suggest thoroughly reading this documentation, just having a look to the
[CONTRIBUTE](https://github.com/hugsy/gef/blob/main/.github/CONTRIBUTING.md) file of the project to
@@ -99,7 +99,7 @@ give you pointers.
Also a good thing would be to join our [Discord channel](https://discord.gg/HCS8Hg7) to get in touch
with the people involved/using it.
## I think I've found a bug, how can I help fixing it? ##
## I think I've found a bug, how can I help fixing it?
`gef` is only getting better through people (like you!) using it, but most importantly reporting
unexpected behavior.
@@ -111,7 +111,7 @@ happens, you'll only get to see a message like this:
By switching to debug mode, `gef` will give much more information:
```
```text
gef➤ gef config gef.debug 1
```
@@ -124,7 +124,7 @@ what was your solution for it.
Otherwise, you can open an [issue](https://github.com/hugsy/gef/issues), give a thorough description
of your bug and copy/paste the content from above. This will greatly help for solving the issue.
## I get weird issues/characters using GDB + Python3, what's up? ##
## I get weird issues/characters using GDB + Python3, what's up?
Chances are you are not using UTF-8. Python3 is [highly relying on
UTF-8](https://www.diveintopython3.net/strings.html) to display correctly characters of any alphabet
@@ -135,11 +135,11 @@ compiled with Python3, GEF will assume that your current charset is UTF-8 (for i
In addition, some unexpected results were observed when your local is not set to English. If you
aren't sure, simply run `gdb` like this:
```
```text
LC_ALL=en_US.UTF-8 gdb /path/to/your/binary
```
## GDB crashes on ARM memory corruption with `gdb_exception_RETURN_MASK_ERROR` ##
## GDB crashes on ARM memory corruption with `gdb_exception_RETURN_MASK_ERROR`
This issue is **NOT** GEF related, but GDB's, or more precisely some versions of GDB packaged with
Debian/Kali for ARM
@@ -168,7 +168,7 @@ Debian/Kali for ARM
Therefore, there is nothing GEF's developers can do about that. The correct solution as mentioned
above is to recompile your GDB with a newer (better) version.
The whole topic was already internally discussed, so please refer to the
The whole topic was already internally discussed, so please refer to the
[issue 206](https://github.com/hugsy/gef/issues/206) for the whole story.
## I still don't have my answer... Where can I go?
+3 -3
View File
@@ -1,16 +1,16 @@
# Function `$_base()`
## Function `$_base()`
Return the matching file's base address plus an optional offset. Defaults to current file. Note that
quotes need to be escaped.
_Note_: a debugging session must be active
```
```text
$_base([filepath])
```
Example:
```
```text
gef➤ p $_base(\"/usr/lib/ld-2.33.so\")
```
+3 -3
View File
@@ -1,15 +1,15 @@
# Function `$_bss()`
## Function `$_bss()`
Return the current BSS base address plus the given offset.
_Note_: a debugging session must be active
```
```text
$_bss([offset])
```
Example:
```
```text
gef➤ p $_bss(0x20)
```
+3 -3
View File
@@ -1,15 +1,15 @@
# Function `$_got()`
## Function `$_got()`
Return the current GOT base address plus the given offset.
_Note_: a debugging session must be active
```
```text
$_got([offset])
```
Example:
```
```text
gef➤ p $_got(0x20)
```
+3 -3
View File
@@ -1,15 +1,15 @@
# Function `$_heap()`
## Function `$_heap()`
Return the current heap base address plus the given offset.
_Note_: a debugging session must be active
```
```text
$_heap([offset])
```
Example:
```
```text
gef➤ p $_heap(0x20)
```
+3 -3
View File
@@ -1,15 +1,15 @@
# Function `$_stack()`
## Function `$_stack()`
Return the current stack base address plus the given offset.
_Note_: a debugging session must be active
```
```text
$_stack([offset])
```
Example:
```
```text
gef➤ p $_stack(0x20)
```
+6 -5
View File
@@ -1,4 +1,4 @@
# GEF - GDB Enhanced Features #
# GEF - GDB Enhanced Features
[![Docs](https://img.shields.io/badge/Documentation-blue.svg)](https://hugsy.github.io/gef/) [![Coverage](https://img.shields.io/badge/Coverage-purple.svg)](https://hugsy.github.io/gef/coverage/) [![MIT](https://img.shields.io/packagist/l/doctrine/orm.svg?maxAge=2592000?style=plastic)](https://github.com/hugsy/gef/blob/main/LICENSE) [![Python 3](https://img.shields.io/badge/Python-3-green.svg)](https://github.com/hugsy/gef/) [![Discord](https://img.shields.io/badge/Discord-GDB--GEF-yellow)](https://discord.gg/HCS8Hg7)
@@ -29,7 +29,8 @@ It requires Python 3, but [`gef-legacy`](https://github.com/hugsy/gef-legacy) ca
* Built around an architecture abstraction layer, so all commands work in any GDB-supported
architecture such as x86-32/64, ARMv5/6/7, AARCH64, SPARC, MIPS, PowerPC, etc.
* Suited for real-life debugging, exploit development, just as much as for CTFs
* And a lot more commands contributed by the community available on [GEF-Extras](https://github.com/hugsy/gef-extras) !!
* And a lot more commands contributed by the community available on
[GEF-Extras](https://github.com/hugsy/gef-extras) !!
Check out the [showroom page](https://hugsy.github.io/gef/screenshots/) for more | or [try it online
yourself!](https://demo.gef.blah.cat) (user:`gef`/password:`gef-demo`)
@@ -71,7 +72,7 @@ local:~ $ gdb -q
gef➤ gef-remote -t your.ip.address:1234 -p 666
```
## Bugs & Feedbacks ##
## Bugs & Feedbacks
To discuss `gef`, `gdb`, exploitation or other topics, feel free to join our [Discord
channel](https://discord.gg/HCS8Hg7).
@@ -83,7 +84,7 @@ _Side Note_: `GEF` fully relies on the GDB API and other Linux-specific sources
as `/proc/<pid>`). As a consequence, some of the features might not work on custom or hardened
systems such as GrSec.
## Contribution ##
## Contribution
`gef` was created and maintained by myself, [`@_hugsy_`](https://twitter.com/_hugsy_), but kept
fresh thanks to [all the contributors](https://github.com/hugsy/gef/graphs/contributors).
@@ -93,7 +94,7 @@ fresh thanks to [all the contributors](https://github.com/hugsy/gef/graphs/contr
Or if you just like the tool, feel free to drop a simple _"thanks"_ on Discord, Twitter or other, it
is **always** very appreciated.
## Sponsors ##
## Sponsors
We would like to thank in particular the following people who've been sponsoring GEF allowing us to
dedicate more time and resources to the project:
+10 -8
View File
@@ -1,16 +1,17 @@
# Installing GEF
## Installing GEF
## Prerequisites
Specific GEF commands rely on commonly used Unix commands to extract additional information.
Therefore it requires the following binaries to be present:
* `file`
* `readelf`
* `ps`
* `python3`
* `file`
* `readelf`
* `ps`
* `python3`
Those tools are included by default in many modern distributions. If they're missing, you can use your OS package manager to install them.
Those tools are included by default in many modern distributions. If they're missing, you can use
your OS package manager to install them.
### GDB
@@ -44,9 +45,10 @@ There are **none**: `GEF` works out of the box!
GEF itself provides most (if not all 🤯) features required for typical sessions. However, GEF can be
easily extended via
* community-built scripts, functions and architectures in the repo
* community-built scripts, functions and architectures in the repo
`gef-extras` (see below)
* your own script which can leverage the GEF API for the heavy lifting
* your own script which can leverage the GEF API for the heavy lifting
## Standalone
+7 -7
View File
@@ -1,4 +1,4 @@
# Screenshots
## Screenshots
<!-- @import "[TOC]" {cmd="toc" depthFrom=1 depthTo=6 orderedList=false} -->
@@ -11,12 +11,12 @@ extensible architecture API.
Currently `GEF` supports the following architectures:
- Intel x86 (32b & 64b)
- ARM (v6/v7)
- AARCH64
- MIPS/MIPS64
- PowerPC
- SPARC/SPARCv9
- Intel x86 (32b & 64b)
- ARM (v6/v7)
- AARCH64
- MIPS/MIPS64
- PowerPC
- SPARC/SPARCv9
## Features
+1 -1
View File
@@ -114,7 +114,7 @@ pytest -k benchmark
which will return (after some time) an execution summary
```
```text
tests/perf/benchmark.py .. [100%]
-1
View File
@@ -33,4 +33,3 @@ class GefFuncDeprecatedApi(GefUnitTestGeneric):
self.assertNoException(res)
if not record:
pytest.fail(f"Expected a warning for '{item}'!")
-1
View File
@@ -76,4 +76,3 @@ class GefHeapApi(GefUnitTestGeneric):
addr3 = result_as_int("int(gef.heap.main_arena)")
self.assertEqual(addr1, addr2)
self.assertEqual(addr2, addr3)
+1 -1
View File
@@ -9,4 +9,4 @@ void f4(){ f5(); }
void f3(){ f4(); }
void f2(){ f3(); }
void f1(){ f2(); }
int main(){ f1(); return 0;}
int main(){ f1(); return 0;}
+1 -1
View File
@@ -1,3 +1,3 @@
#include "utils.h"
int f1(int i){ if(i==10) {DebugBreak(); return 0;} return f1(++i); }
int main(){ return f1(0); }
int main(){ return f1(0); }
-1
View File
@@ -16,4 +16,3 @@ class FunctionsCommand(GefUnitTestGeneric):
res = gdb_run_cmd(cmd)
self.assertNoException(res)
self.assertIn("$_heap", res)
-1
View File
@@ -120,4 +120,3 @@ class GefCommand(GefUnitTestGeneric):
self.assertNotEqual(-1, idx, f"Check {i}/{3} failed: missing '{pattern}' in\n{res}")
self.assertIn("new command(s) available", res)
res = res[idx:]
-1
View File
@@ -37,4 +37,3 @@ class GefRemoteCommand(GefUnitTestGeneric):
self.assertIn(
f"RemoteSession(target='{GDBSERVER_PREFERED_HOST}:{port}', local='/tmp/", res)
self.assertIn(", qemu_user=True)", res)
-1
View File
@@ -29,4 +29,3 @@ class GotCommand(GefUnitTestGeneric):
res = gdb_start_silent_cmd("got printf", target=target)
self.assertIn("printf", res)
self.assertNotIn("strcpy", res)
-1
View File
@@ -178,4 +178,3 @@ class HeapCommand(GefUnitTestGeneric):
self.assertIn("Found 1 chunks in unsorted bin", res)
self.assertIn("Chunk(addr=", res)
self.assertIn(f"size={self.expected_unsorted_bin_size:#x}", res)
-1
View File
@@ -24,4 +24,3 @@ class HeapAnalysisCommand(GefUnitTestGeneric):
addr = int(res.split("calloc(32)=")[1].split("\n")[0], 0)
self.assertRegex(res, r"realloc\(.+, 48")
self.assertIn(f"free({addr:#x}", res)
-3
View File
@@ -21,6 +21,3 @@ class HexdumpCommand(GefUnitTestGeneric):
self.assertNoException(res)
res = gdb_start_silent_cmd("hexdump byte $sp -s 32")
self.assertNoException(res)
-1
View File
@@ -21,4 +21,3 @@ class NameBreakCommand(GefUnitTestGeneric):
res = gdb_start_silent_cmd("nb foobar")
self.assertNoException(res)
-1
View File
@@ -77,4 +77,3 @@ class PatternCommand(GefUnitTestGeneric):
res = gdb_run_cmd(cmd, before=before, target=target)
self.assertNoException(res)
self.assertIn(f"not found", res)
-1
View File
@@ -52,4 +52,3 @@ class PieCommand(GefUnitTestGeneric):
# check the mask of the breakpoint address
address = int(res.split()[0], 16)
self.assertEqual(address & self.pie_offset, self.pie_offset)
-2
View File
@@ -18,5 +18,3 @@ class ProcessStatusCommand(GefUnitTestGeneric):
self.assertIn("Process Information", res)
self.assertIn("No child process", res)
self.assertIn("No open connections", res)
-1
View File
@@ -30,4 +30,3 @@ class RegistersCommand(GefUnitTestGeneric):
elif ARCH in ("i686", ):
self.assertIn("$eax", res)
self.assertIn("$eflags", res)
-2
View File
@@ -13,5 +13,3 @@ class ResetCacheCommand(GefUnitTestGeneric):
def test_cmd_reset_cache(self):
res = gdb_start_silent_cmd("reset-cache")
self.assertNoException(res)
-1
View File
@@ -21,4 +21,3 @@ class ScanCommand(GefUnitTestGeneric):
res = gdb_start_silent_cmd("scan binary libc")
self.assertNoException(res)
self.assertIn("__libc_start_main", res)
+2 -4
View File
@@ -17,14 +17,12 @@ class SearchPatternCommand(GefUnitTestGeneric):
self.assertIn("0x", res)
def test_cmd_search_pattern_regex(self):
res = gdb_start_silent_cmd_last_line("set {char[6]} $sp = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x00 }",
res = gdb_start_silent_cmd_last_line("set {char[6]} $sp = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x00 }",
after=[r"search-pattern --regex $sp $sp+7 ([\\x20-\\x7E]{2,})(?=\\x00)",])
self.assertNoException(res)
self.assertTrue(r"b'ABCDE'" in res)
# this should not match because binary string is not null ended:
res = gdb_start_silent_cmd_last_line("set {char[6]} $sp = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x03 }",
res = gdb_start_silent_cmd_last_line("set {char[6]} $sp = { 0x41, 0x42, 0x43, 0x44, 0x45, 0x03 }",
after=[r"search-pattern --regex $sp $sp+7 ([\\x20-\\x7E]{2,})(?=\\x00)",])
self.assertNoException(res)
self.assertTrue(r"b'ABCDE'" not in res)
-1
View File
@@ -60,4 +60,3 @@ class SkipiCommand(GefUnitTestGeneric):
)
self.assertNoException(res)
self.assertIn(r"\x90\x90", res) # 2 nops
+1 -1
View File
@@ -19,4 +19,4 @@ class StubCommand(GefUnitTestGeneric):
self.assertIn("Hello World!", res)
res = gdb_start_silent_cmd(cmds, after=["continue"])
self.assertNoException(res)
self.assertNotIn("Hello World!", res)
self.assertNotIn("Hello World!", res)
-1
View File
@@ -20,4 +20,3 @@ class TestGefConfigUnit(GefUnitTestGeneric):
# output format: 0xaddress opcode <symbol+offset> mnemo [operands, ...]
# example: 0x5555555546b2 897dec <main+8> mov DWORD PTR [rbp-0x14], edi
self.assertRegex(res, r"(0x([0-9a-f]{2})+)\s+(([0-9a-f]{2})+)\s+<[^>]+>\s+(.*)")
+1
View File
@@ -5,3 +5,4 @@ pytest-xdist
pytest-benchmark
pytest-forked
coverage
pre-commit