mirror of https://github.com/pwndbg/pwndbg.git
parent
800e6d5f23
commit
a575fa7fab
@ -0,0 +1,35 @@
|
||||
import argparse
|
||||
|
||||
import pwndbg.color.message as M
|
||||
import pwndbg.commands
|
||||
import pwndbg.gdblib.kernel
|
||||
|
||||
parser = argparse.ArgumentParser(description="Outputs the kernel config (requires CONFIG_IKCONFIG)")
|
||||
|
||||
parser.add_argument("config_name", nargs="?", type=str, help="A config name to search for")
|
||||
|
||||
|
||||
@pwndbg.commands.ArgparsedCommand(parser)
|
||||
@pwndbg.commands.OnlyWhenQemuKernel
|
||||
def kconfig(config_name=None):
|
||||
kconfig_ = pwndbg.gdblib.kernel.kconfig()
|
||||
|
||||
if len(kconfig_) == 0:
|
||||
print(
|
||||
M.warn(
|
||||
"No kernel configuration found, make sure the kernel was built with CONFIG_IKCONFIG"
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
if config_name:
|
||||
key = kconfig_.get_key(config_name)
|
||||
if key:
|
||||
val = kconfig_[config_name]
|
||||
print(f"{key} = {val}")
|
||||
else:
|
||||
key = pwndbg.lib.kernel.kconfig.config_to_key(config_name)
|
||||
print(f"Config {key} not set")
|
||||
else:
|
||||
for name, val in kconfig_.items():
|
||||
print(f"{name} = {val}")
|
||||
@ -0,0 +1,23 @@
|
||||
import pwndbg.gdblib.memory
|
||||
import pwndbg.gdblib.symbol
|
||||
import pwndbg.lib.kernel.kconfig
|
||||
import pwndbg.lib.memoize
|
||||
|
||||
_kconfig = None
|
||||
|
||||
|
||||
def load_kconfig():
|
||||
config_start = pwndbg.gdblib.symbol.address("kernel_config_data")
|
||||
config_end = pwndbg.gdblib.symbol.address("kernel_config_data_end")
|
||||
config_size = config_end - config_start
|
||||
|
||||
compressed_config = pwndbg.gdblib.memory.read(config_start, config_size)
|
||||
return pwndbg.lib.kernel.kconfig.Kconfig(compressed_config)
|
||||
|
||||
|
||||
@pwndbg.lib.memoize.reset_on_start
|
||||
def kconfig():
|
||||
global _kconfig
|
||||
if _kconfig is None:
|
||||
_kconfig = load_kconfig()
|
||||
return _kconfig
|
||||
@ -0,0 +1,57 @@
|
||||
import zlib
|
||||
from collections import UserDict
|
||||
from typing import Dict
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def parse_config(config_text: str) -> Dict[str, str]:
|
||||
res = {}
|
||||
|
||||
for line in config_text.split(b"\n"):
|
||||
if b"=" in line:
|
||||
config_name, config_val = line.split(b"=", 1)
|
||||
res[config_name.decode("ascii")] = config_val.decode("ascii")
|
||||
|
||||
return res
|
||||
|
||||
|
||||
def parse_compresed_config(compressed_config: bytes) -> Dict[str, str]:
|
||||
config_text = zlib.decompress(compressed_config, 16)
|
||||
return parse_config(config_text)
|
||||
|
||||
|
||||
def config_to_key(name: str) -> str:
|
||||
return "CONFIG_" + name.upper()
|
||||
|
||||
|
||||
class Kconfig(UserDict):
|
||||
def __init__(self, compressed_config: bytes):
|
||||
super().__init__()
|
||||
self.data = parse_compresed_config(compressed_config)
|
||||
|
||||
def get_key(self, name: str) -> Optional[str]:
|
||||
# First attempt to lookup the value assuming the user passed in a name
|
||||
# like 'debug_info', then attempt to lookup the value assuming the user
|
||||
# passed in a value like `config_debug_info` or `CONFIG_DEBUG_INFO`
|
||||
key = config_to_key(name)
|
||||
if key in self.data:
|
||||
return key
|
||||
elif name.upper() in self.data:
|
||||
return name.upper()
|
||||
elif name in self.data:
|
||||
return name
|
||||
|
||||
return None
|
||||
|
||||
def __getitem__(self, name):
|
||||
key = self.get_key(name)
|
||||
if key:
|
||||
return self.data[key]
|
||||
|
||||
raise KeyError(f"Key {name} not found")
|
||||
|
||||
def __contains__(self, name: str):
|
||||
return self.get_key(name) is not None
|
||||
|
||||
def __getattr__(self, name: str):
|
||||
return self.get(name)
|
||||
Loading…
Reference in new issue