Skip to content

Commit

Permalink
Add config to override libc version. (#1027)
Browse files Browse the repository at this point in the history
This change add a config for force the libc version to a specific
version.

This is helpful when debugging certain core dumps that doesn't have good
memory map information, and could not find libc properly.

This shows up in our recent debugging, where we know the program is
using libc 2.31, but it could not be detected properly due to memory map
information missing.

This change allows us to force the libc version into a specific version,
which solves this problem.
  • Loading branch information
r12f committed Dec 22, 2023
1 parent 023b1a9 commit 663d4a2
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 1 deletion.
8 changes: 8 additions & 0 deletions docs/commands/heap.md
Expand Up @@ -30,6 +30,14 @@ 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.

Sometimes, the dump might not contain proper info to help GEF find the libc version, which results in
failure to parse the arena information. In this case, you can try to provide GEF a specific libc
version to use with the following command:

```text
gef➤ gef config gef.libc_version 2.31
```

### `heap chunks` command

Displays all the chunks from the `heap` section of the current arena.
Expand Down
7 changes: 7 additions & 0 deletions gef.py
Expand Up @@ -9602,6 +9602,7 @@ def __init__(self) -> None:
gef.config["gef.show_deprecation_warnings"] = GefSetting(True, bool, "Toggle the display of the `deprecated` warnings")
gef.config["gef.buffer"] = GefSetting(True, bool, "Internally buffer command output until completion")
gef.config["gef.bruteforce_main_arena"] = GefSetting(False, bool, "Allow bruteforcing main_arena symbol if everything else fails")
gef.config["gef.libc_version"] = GefSetting("", str, "Specify libc version when auto-detection fails")
gef.config["gef.main_arena_offset"] = GefSetting("", str, "Offset from libc base address to main_arena symbol (int or hex). Set to empty string to disable.")

self.commands : Dict[str, GenericCommand] = collections.OrderedDict()
Expand Down Expand Up @@ -11181,8 +11182,14 @@ def __str__(self) -> str:
def version(self) -> Optional[Tuple[int, int]]:
if not is_alive():
return None

if not self._version:
self._version = GefLibcManager.find_libc_version()

# Whenever auto-detection fails, we use the user-provided version.
if self._version == (0, 0) and gef.config["gef.libc_version"] != "":
return tuple([int(v) for v in gef.config["gef.libc_version"].split(".")])

return self._version

@staticmethod
Expand Down
22 changes: 21 additions & 1 deletion tests/config/__init__.py
Expand Up @@ -2,7 +2,7 @@
Test GEF configuration parameters.
"""

from tests.utils import gdb_run_cmd
from tests.utils import gdb_run_cmd, gdb_start_silent_cmd
from tests.utils import GefUnitTestGeneric


Expand Down Expand Up @@ -49,3 +49,23 @@ def test_config_type_validator(self):
res = gdb_run_cmd("gef config gef.debug 0")
self.assertNoException(res)
self.assertNotIn("[!]", res)

def test_config_libc_version(self):
"""Check setting libc version."""
res = gdb_run_cmd("gef config gef.libc_version")
self.assertNoException(res)
self.assertNotIn("[!]", res)

res = gdb_run_cmd("gef config gef.libc_version", before=["gef config gef.libc_version 2.31"])
self.assertNoException(res)
self.assertNotIn("[!]", res)
self.assertIn('gef.libc_version (str) = "2.31"', res)

res = gdb_run_cmd("gef config gef.libc_version", before=["gef config gef.libc_version 2.31", "gef config gef.libc_version ''"])
self.assertNoException(res)
self.assertNotIn("[!]", res)
self.assertIn('gef.libc_version (str) = ""', res)

res = gdb_start_silent_cmd("python print(gef.libc.version)", before=["gef config gef.libc_version 2.31"])
self.assertNoException(res)
self.assertNotIn("[!]", res)

0 comments on commit 663d4a2

Please sign in to comment.