From 663d4a251748c294f342974027ca9bd6ad7f8eb6 Mon Sep 17 00:00:00 2001 From: Riff Date: Fri, 22 Dec 2023 07:14:03 -0800 Subject: [PATCH] Add config to override libc version. (#1027) 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. --- docs/commands/heap.md | 8 ++++++++ gef.py | 7 +++++++ tests/config/__init__.py | 22 +++++++++++++++++++++- 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/docs/commands/heap.md b/docs/commands/heap.md index aa43b7581..a9c164dc3 100644 --- a/docs/commands/heap.md +++ b/docs/commands/heap.md @@ -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. diff --git a/gef.py b/gef.py index f0a950e16..218dcc266 100644 --- a/gef.py +++ b/gef.py @@ -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() @@ -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 diff --git a/tests/config/__init__.py b/tests/config/__init__.py index 1d35df3ec..d2f59d67f 100644 --- a/tests/config/__init__.py +++ b/tests/config/__init__.py @@ -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 @@ -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)