diff --git a/pwndbg/commands/kchecksec.py b/pwndbg/commands/kchecksec.py index 7a768e029f8..751df9ebed6 100644 --- a/pwndbg/commands/kchecksec.py +++ b/pwndbg/commands/kchecksec.py @@ -105,7 +105,6 @@ class Option(NamedTuple): @pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.KERNEL) @pwndbg.commands.OnlyWhenQemuKernel -@pwndbg.commands.OnlyWithKernelDebugSyms @pwndbg.commands.OnlyWhenPagingEnabled def kchecksec() -> None: kconfig = pwndbg.gdblib.kernel.kconfig() diff --git a/pwndbg/commands/kconfig.py b/pwndbg/commands/kconfig.py index 93fe41b0b75..6801b3fa3a4 100644 --- a/pwndbg/commands/kconfig.py +++ b/pwndbg/commands/kconfig.py @@ -16,7 +16,6 @@ @pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.KERNEL) @pwndbg.commands.OnlyWhenQemuKernel -@pwndbg.commands.OnlyWithKernelDebugSyms @pwndbg.commands.OnlyWhenPagingEnabled def kconfig(config_name=None) -> None: kconfig_ = pwndbg.gdblib.kernel.kconfig() diff --git a/pwndbg/commands/kversion.py b/pwndbg/commands/kversion.py index 76a25d1c8fd..e130b848288 100644 --- a/pwndbg/commands/kversion.py +++ b/pwndbg/commands/kversion.py @@ -11,7 +11,6 @@ @pwndbg.commands.ArgparsedCommand(parser, category=CommandCategory.KERNEL) @pwndbg.commands.OnlyWhenQemuKernel -@pwndbg.commands.OnlyWithKernelDebugSyms @pwndbg.commands.OnlyWhenPagingEnabled def kversion() -> None: print(pwndbg.gdblib.kernel.kversion()) diff --git a/pwndbg/gdblib/kernel/__init__.py b/pwndbg/gdblib/kernel/__init__.py index 11f240c9004..a4b1d1b9271 100644 --- a/pwndbg/gdblib/kernel/__init__.py +++ b/pwndbg/gdblib/kernel/__init__.py @@ -20,6 +20,7 @@ import pwndbg.lib.cache import pwndbg.lib.kernel.kconfig import pwndbg.lib.kernel.structs +import pwndbg.search _kconfig: pwndbg.lib.kernel.kconfig.Kconfig | None = None @@ -87,12 +88,39 @@ def nproc() -> int: return int(gdb.lookup_global_symbol("nr_cpu_ids").value()) -@requires_debug_syms(default={}) +def get_first_kernel_ro(): + """Returns the first kernel mapping which contains the linux_banner""" + base = kbase() + + for mapping in pwndbg.gdblib.vmmap.get(): + if mapping.vaddr < base: + continue + + results = list(pwndbg.search.search(b"Linux version", mappings=[mapping])) + + if len(results) > 0: + return mapping + + return None + + def load_kconfig() -> pwndbg.lib.kernel.kconfig.Kconfig | None: - config_start = pwndbg.gdblib.symbol.address("kernel_config_data") - config_end = pwndbg.gdblib.symbol.address("kernel_config_data_end") + if has_debug_syms(): + config_start = pwndbg.gdblib.symbol.address("kernel_config_data") + config_end = pwndbg.gdblib.symbol.address("kernel_config_data_end") + else: + mapping = get_first_kernel_ro() + results = list(pwndbg.search.search(b"IKCFG_ST", mappings=[mapping])) + + if len(results) == 0: + return None + + config_start = results[0] + len("IKCFG_ST") + config_end = list(pwndbg.search.search(b"IKCFG_ED", start=config_start))[0] + if config_start is None or config_end is None: return None + config_size = config_end - config_start compressed_config = pwndbg.gdblib.memory.read(config_start, config_size) @@ -116,10 +144,14 @@ def kcmdline() -> str: return pwndbg.gdblib.memory.string(cmdline_addr).decode("ascii") -@requires_debug_syms(default="") @pwndbg.lib.cache.cache_until("start") def kversion() -> str: - version_addr = pwndbg.gdblib.symbol.address("linux_banner") + if has_debug_syms(): + version_addr = pwndbg.gdblib.symbol.address("linux_banner") + else: + mapping = get_first_kernel_ro() + version_addr = list(pwndbg.search.search(b"Linux version", mappings=[mapping]))[0] + return pwndbg.gdblib.memory.string(version_addr).decode("ascii").strip() diff --git a/tests/qemu-tests/tests/system/test_commands_kernel.py b/tests/qemu-tests/tests/system/test_commands_kernel.py index 2b666083aa5..f63c8089e2c 100644 --- a/tests/qemu-tests/tests/system/test_commands_kernel.py +++ b/tests/qemu-tests/tests/system/test_commands_kernel.py @@ -18,11 +18,6 @@ def test_command_kcmdline(): def test_command_kconfig(): - if not pwndbg.gdblib.kernel.has_debug_syms(): - res = gdb.execute("kconfig", to_string=True) - assert "may only be run when debugging a Linux kernel with debug" in res - return - res = gdb.execute("kconfig", to_string=True) assert "CONFIG_IKCONFIG = y" in res @@ -31,11 +26,6 @@ def test_command_kconfig(): def test_command_kversion(): - if not pwndbg.gdblib.kernel.has_debug_syms(): - res = gdb.execute("kversion", to_string=True) - assert "may only be run when debugging a Linux kernel with debug" in res - return - res = gdb.execute("kversion", to_string=True) assert "Linux version" in res