mirror of
https://github.com/volatilityfoundation/volatility3.git
synced 2026-08-30 03:39:51 +02:00
Merge pull request #1567 from Abyss-W4tcher/split_linuxutilities_modules
Add deprecation decorator and split Linux modules utilities
This commit is contained in:
@@ -573,6 +573,8 @@ class CommandLine:
|
||||
fulltrace = traceback.TracebackException.from_exception(excp).format(chain=True)
|
||||
vollog.debug("".join(fulltrace))
|
||||
|
||||
file_a_bug_msg = f"Please re-run with -vvv and file a bug with the output at {constants.BUG_URL}"
|
||||
|
||||
if isinstance(excp, exceptions.InvalidAddressException):
|
||||
general = "Volatility was unable to read a requested page:"
|
||||
if isinstance(excp, exceptions.SwappedInvalidAddressException):
|
||||
@@ -617,9 +619,7 @@ class CommandLine:
|
||||
elif isinstance(excp, exceptions.LayerException):
|
||||
general = f"Volatility experienced a layer-related issue: {excp.layer_name}"
|
||||
detail = f"{excp}"
|
||||
caused_by = [
|
||||
"A faulty layer implementation (re-run with -vvv and file a bug)"
|
||||
]
|
||||
caused_by = [f"A faulty layer implementation. {file_a_bug_msg}"]
|
||||
elif isinstance(excp, exceptions.MissingModuleException):
|
||||
general = f"Volatility could not import a necessary module: {excp.module}"
|
||||
detail = f"{excp}"
|
||||
@@ -630,13 +630,17 @@ class CommandLine:
|
||||
general = "Volatility experienced an issue when rendering the output:"
|
||||
detail = f"{excp}"
|
||||
caused_by = ["An invalid renderer option, such as no visible columns"]
|
||||
elif isinstance(excp, exceptions.VersionMismatchException):
|
||||
general = "A version mismatch was detected between two components:"
|
||||
detail = f"{excp}"
|
||||
caused_by = [
|
||||
excp.failure_reason or "An outdated API caller, such as a method.",
|
||||
file_a_bug_msg,
|
||||
]
|
||||
else:
|
||||
general = "Volatility encountered an unexpected situation."
|
||||
detail = ""
|
||||
caused_by = [
|
||||
"Please re-run using with -vvv and file a bug with the output",
|
||||
f"at {constants.BUG_URL}",
|
||||
]
|
||||
caused_by = [file_a_bug_msg]
|
||||
|
||||
# Code that actually renders the exception
|
||||
output = sys.stderr
|
||||
|
||||
@@ -11,9 +11,12 @@ import inspect
|
||||
import logging
|
||||
import os
|
||||
import traceback
|
||||
from typing import Any, Dict, Generator, List, Optional, Tuple, Type, TypeVar
|
||||
import functools
|
||||
import warnings
|
||||
from typing import Any, Callable, Dict, Generator, List, Optional, Tuple, Type, TypeVar
|
||||
|
||||
from volatility3.framework import constants, interfaces
|
||||
from volatility3.framework import constants, exceptions, interfaces
|
||||
from volatility3.framework.configuration import requirements
|
||||
|
||||
if (
|
||||
sys.version_info.major != constants.REQUIRED_PYTHON_VERSION[0]
|
||||
@@ -63,6 +66,61 @@ def require_interface_version(*args) -> None:
|
||||
)
|
||||
|
||||
|
||||
class Deprecation:
|
||||
"""Deprecation related methods."""
|
||||
|
||||
@staticmethod
|
||||
def deprecated_method(
|
||||
replacement: Callable,
|
||||
replacement_version: Tuple[int, int, int] = None,
|
||||
additional_information: str = "",
|
||||
):
|
||||
"""A decorator for marking functions as deprecated.
|
||||
|
||||
Args:
|
||||
replacement: The replacement function overriding the deprecated API, in the form of a Callable (typically a method)
|
||||
replacement_version: The "replacement" base class version that the deprecated method expects before proxying to it. This implies that "replacement" is a method from a class that inherits from VersionableInterface.
|
||||
additional_information: Information appended at the end of the deprecation message
|
||||
"""
|
||||
|
||||
def decorator(deprecated_func):
|
||||
@functools.wraps(deprecated_func)
|
||||
def wrapper(*args, **kwargs):
|
||||
nonlocal replacement, replacement_version, additional_information
|
||||
# Prevent version mismatches between deprecated (proxy) methods and the ones they proxy
|
||||
if (
|
||||
replacement_version is not None
|
||||
and callable(replacement)
|
||||
and hasattr(replacement, "__self__")
|
||||
):
|
||||
replacement_base_class = replacement.__self__
|
||||
|
||||
# Verify that the base class inherits from VersionableInterface
|
||||
if inspect.isclass(replacement_base_class) and issubclass(
|
||||
replacement_base_class,
|
||||
interfaces.configuration.VersionableInterface,
|
||||
):
|
||||
# SemVer check
|
||||
if not requirements.VersionRequirement.matches_required(
|
||||
replacement_version, replacement_base_class.version
|
||||
):
|
||||
raise exceptions.VersionMismatchException(
|
||||
deprecated_func,
|
||||
replacement_base_class,
|
||||
replacement_version,
|
||||
"This is a bug, the deprecated call needs to be removed and the caller needs to update their code to use the new method.",
|
||||
)
|
||||
|
||||
deprecation_msg = f"Method \"{deprecated_func.__module__ + '.' + deprecated_func.__qualname__}\" is deprecated, use \"{replacement.__module__ + '.' + replacement.__qualname__}\" instead. {additional_information}"
|
||||
warnings.warn(deprecation_msg, FutureWarning)
|
||||
# Return the wrapped function with its original arguments
|
||||
return deprecated_func(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
class NonInheritable:
|
||||
def __init__(self, value: Any, cls: Type) -> None:
|
||||
self.default_value = value
|
||||
|
||||
@@ -8,9 +8,10 @@ space or symbol tables, and by layers when an address is invalid. The
|
||||
:class:`PagedInvalidAddressException` contains information about the
|
||||
size of the invalid page.
|
||||
"""
|
||||
from typing import Dict, Optional
|
||||
from typing import Callable, Dict, Optional, Tuple
|
||||
|
||||
from volatility3.framework import interfaces
|
||||
from volatility3.framework.interfaces.configuration import VersionableInterface
|
||||
|
||||
|
||||
class VolatilityException(Exception):
|
||||
@@ -134,3 +135,31 @@ class RenderException(VolatilityException):
|
||||
|
||||
class LinuxPageCacheException(VolatilityException):
|
||||
"""Thrown if there is an error during Linux Page Cache processing"""
|
||||
|
||||
|
||||
class VersionMismatchException(VolatilityException):
|
||||
"""Thrown if a version mismatch has been encountered between two components."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
source_component: Callable,
|
||||
target_component: VersionableInterface,
|
||||
target_version: Tuple[int, int, int],
|
||||
failure_reason: str = None,
|
||||
*args,
|
||||
):
|
||||
"""
|
||||
Args:
|
||||
source_component: The component that required the target component
|
||||
target_component: The component that is required. Must inherit from VersionableInterface
|
||||
target_version: The version of the target component that was required, and ultimately was not satisfied
|
||||
failure_reason: A detailed failure reason to enhance debugging and bug tracking
|
||||
"""
|
||||
super().__init__(*args)
|
||||
self.source_component = source_component
|
||||
self.target_component = target_component
|
||||
self.target_version = target_version
|
||||
self.failure_reason = failure_reason
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.source_component.__module__+ '.' + self.source_component.__qualname__}: Version {self.target_version} dependency on {self.target_component.__module__+ '.' + self.target_component.__name__} {self.target_component.version} unmet."
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import logging
|
||||
from typing import List
|
||||
|
||||
import volatility3.framework.symbols.linux.utilities.modules as linux_utilities_modules
|
||||
from volatility3.framework import interfaces, renderers, symbols
|
||||
from volatility3.framework.configuration import requirements
|
||||
from volatility3.framework.renderers import format_hints
|
||||
@@ -27,6 +28,11 @@ class Check_idt(interfaces.plugins.PluginInterface):
|
||||
description="Linux kernel",
|
||||
architectures=["Intel32", "Intel64"],
|
||||
),
|
||||
requirements.VersionRequirement(
|
||||
name="linux_utilities_modules",
|
||||
component=linux_utilities_modules.Modules,
|
||||
version=(1, 0, 0),
|
||||
),
|
||||
requirements.VersionRequirement(
|
||||
name="linuxutils", component=linux.LinuxUtilities, version=(2, 0, 0)
|
||||
),
|
||||
@@ -99,8 +105,10 @@ class Check_idt(interfaces.plugins.PluginInterface):
|
||||
|
||||
idt_addr = idt_addr & address_mask
|
||||
|
||||
module_name, symbol_name = linux.LinuxUtilities.lookup_module_address(
|
||||
vmlinux, handlers, idt_addr
|
||||
module_name, symbol_name = (
|
||||
linux_utilities_modules.Modules.lookup_module_address(
|
||||
self.context, vmlinux.name, handlers, idt_addr
|
||||
)
|
||||
)
|
||||
|
||||
yield (
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
import logging
|
||||
|
||||
import volatility3.framework.symbols.linux.utilities.modules as linux_utilities_modules
|
||||
from volatility3.framework import interfaces, renderers, exceptions
|
||||
from volatility3.framework.configuration import requirements
|
||||
from volatility3.framework.renderers import format_hints
|
||||
@@ -26,6 +27,11 @@ class Keyboard_notifiers(interfaces.plugins.PluginInterface):
|
||||
description="Linux kernel",
|
||||
architectures=["Intel32", "Intel64"],
|
||||
),
|
||||
requirements.VersionRequirement(
|
||||
name="linux_utilities_modules",
|
||||
component=linux_utilities_modules.Modules,
|
||||
version=(1, 0, 0),
|
||||
),
|
||||
requirements.PluginRequirement(
|
||||
name="lsmod", plugin=lsmod.Lsmod, version=(2, 0, 0)
|
||||
),
|
||||
@@ -66,8 +72,10 @@ class Keyboard_notifiers(interfaces.plugins.PluginInterface):
|
||||
):
|
||||
call_addr = call_back.notifier_call
|
||||
|
||||
module_name, symbol_name = linux.LinuxUtilities.lookup_module_address(
|
||||
vmlinux, handlers, call_addr
|
||||
module_name, symbol_name = (
|
||||
linux_utilities_modules.Modules.lookup_module_address(
|
||||
self.context, vmlinux.name, handlers, call_addr
|
||||
)
|
||||
)
|
||||
|
||||
yield (0, [format_hints.Hex(call_addr), module_name, symbol_name])
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import logging
|
||||
from typing import List
|
||||
|
||||
import volatility3.framework.symbols.linux.utilities.modules as linux_utilities_modules
|
||||
from volatility3.framework import constants, exceptions, interfaces, renderers
|
||||
from volatility3.framework.configuration import requirements
|
||||
from volatility3.framework.interfaces import plugins
|
||||
@@ -20,7 +21,7 @@ class Kthreads(plugins.PluginInterface):
|
||||
"""Enumerates kthread functions"""
|
||||
|
||||
_required_framework_version = (2, 11, 0)
|
||||
_version = (1, 0, 2)
|
||||
_version = (1, 0, 3)
|
||||
|
||||
@classmethod
|
||||
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
|
||||
@@ -30,6 +31,11 @@ class Kthreads(plugins.PluginInterface):
|
||||
description="Linux kernel",
|
||||
architectures=architectures.LINUX_ARCHS,
|
||||
),
|
||||
requirements.VersionRequirement(
|
||||
name="linux_utilities_modules",
|
||||
component=linux_utilities_modules.Modules,
|
||||
version=(1, 0, 0),
|
||||
),
|
||||
requirements.VersionRequirement(
|
||||
name="linuxutils", component=linux.LinuxUtilities, version=(2, 1, 0)
|
||||
),
|
||||
@@ -88,8 +94,10 @@ class Kthreads(plugins.PluginInterface):
|
||||
if kthread.has_member("full_name")
|
||||
else task_name
|
||||
)
|
||||
module_name, symbol_name = linux.LinuxUtilities.lookup_module_address(
|
||||
vmlinux, handlers, threadfn
|
||||
module_name, symbol_name = (
|
||||
linux_utilities_modules.Modules.lookup_module_address(
|
||||
self.context, vmlinux.name, handlers, threadfn
|
||||
)
|
||||
)
|
||||
|
||||
fields = [
|
||||
|
||||
@@ -5,6 +5,7 @@ from dataclasses import dataclass, field
|
||||
from abc import ABC, abstractmethod
|
||||
import logging
|
||||
|
||||
import volatility3.framework.symbols.linux.utilities.modules as linux_utilities_modules
|
||||
from typing import Iterator, List, Tuple
|
||||
from volatility3 import framework
|
||||
from volatility3.framework import (
|
||||
@@ -98,6 +99,20 @@ class AbstractNetfilter(ABC):
|
||||
f"linux.LinuxUtilities version not suitable: required {linuxutils_required_version} found {linuxutils_current_version}"
|
||||
)
|
||||
|
||||
linux_utilities_modules_required_version = (
|
||||
Netfilter._required_linux_utilities_modules_version
|
||||
)
|
||||
linux_utilities_modules_current_version = (
|
||||
linux_utilities_modules.Modules._version
|
||||
)
|
||||
if not requirements.VersionRequirement.matches_required(
|
||||
linux_utilities_modules_required_version,
|
||||
linux_utilities_modules_current_version,
|
||||
):
|
||||
raise exceptions.PluginRequirementException(
|
||||
f"linux_utilities_modules.Modules version not suitable: required {linux_utilities_modules_required_version} found {linux_utilities_modules_current_version}"
|
||||
)
|
||||
|
||||
modules = lsmod.Lsmod.list_modules(context, kernel_module_name)
|
||||
self.handlers = linux.LinuxUtilities.generate_kernel_handler_info(
|
||||
context, kernel_module_name, modules
|
||||
@@ -263,8 +278,10 @@ class AbstractNetfilter(ABC):
|
||||
"""Helper to obtain the module and symbol name in the format needed for the
|
||||
output of this plugin.
|
||||
"""
|
||||
module_name, symbol_name = linux.LinuxUtilities.lookup_module_address(
|
||||
self.vmlinux, self.handlers, addr
|
||||
module_name, symbol_name = (
|
||||
linux_utilities_modules.Modules.lookup_module_address(
|
||||
self._context, self.vmlinux.name, self.handlers, addr
|
||||
)
|
||||
)
|
||||
|
||||
if module_name == "UNKNOWN":
|
||||
@@ -677,6 +694,7 @@ class Netfilter(interfaces.plugins.PluginInterface):
|
||||
|
||||
_version = (1, 1, 0)
|
||||
|
||||
_required_linux_utilities_modules_version = (1, 0, 0)
|
||||
_required_linuxutils_version = (2, 1, 0)
|
||||
_required_lsmod_version = (2, 0, 0)
|
||||
|
||||
@@ -688,6 +706,11 @@ class Netfilter(interfaces.plugins.PluginInterface):
|
||||
description="Linux kernel",
|
||||
architectures=["Intel32", "Intel64"],
|
||||
),
|
||||
requirements.VersionRequirement(
|
||||
name="linux_utilities_modules",
|
||||
component=linux_utilities_modules.Modules,
|
||||
version=cls._required_linux_utilities_modules_version,
|
||||
),
|
||||
requirements.PluginRequirement(
|
||||
name="lsmod", plugin=lsmod.Lsmod, version=cls._required_lsmod_version
|
||||
),
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
import logging
|
||||
from typing import List
|
||||
|
||||
import volatility3.framework.symbols.linux.utilities.modules as linux_utilities_modules
|
||||
from volatility3.framework import interfaces, renderers, exceptions, constants
|
||||
from volatility3.framework.configuration import requirements
|
||||
from volatility3.framework.interfaces import plugins
|
||||
@@ -29,6 +30,11 @@ class tty_check(plugins.PluginInterface):
|
||||
description="Linux kernel",
|
||||
architectures=["Intel32", "Intel64"],
|
||||
),
|
||||
requirements.VersionRequirement(
|
||||
name="linux_utilities_modules",
|
||||
component=linux_utilities_modules.Modules,
|
||||
version=(1, 0, 0),
|
||||
),
|
||||
requirements.PluginRequirement(
|
||||
name="lsmod", plugin=lsmod.Lsmod, version=(2, 0, 0)
|
||||
),
|
||||
@@ -79,8 +85,10 @@ class tty_check(plugins.PluginInterface):
|
||||
|
||||
recv_buf = tty_dev.ldisc.ops.receive_buf
|
||||
|
||||
module_name, symbol_name = linux.LinuxUtilities.lookup_module_address(
|
||||
vmlinux, handlers, recv_buf
|
||||
module_name, symbol_name = (
|
||||
linux_utilities_modules.Modules.lookup_module_address(
|
||||
self.context, vmlinux.name, handlers, recv_buf
|
||||
)
|
||||
)
|
||||
|
||||
yield (0, (name, format_hints.Hex(recv_buf), module_name, symbol_name))
|
||||
|
||||
@@ -8,8 +8,15 @@ import logging
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Iterator, List, Tuple, Optional, Union
|
||||
|
||||
import volatility3.framework.symbols.linux.utilities.modules as linux_utilities_modules
|
||||
from volatility3 import framework
|
||||
from volatility3.framework import constants, exceptions, interfaces, objects
|
||||
from volatility3.framework import (
|
||||
constants,
|
||||
exceptions,
|
||||
interfaces,
|
||||
objects,
|
||||
Deprecation,
|
||||
)
|
||||
from volatility3.framework.objects import utility
|
||||
from volatility3.framework.symbols import intermed
|
||||
from volatility3.framework.symbols.linux import extensions
|
||||
@@ -81,7 +88,7 @@ class LinuxKernelIntermedSymbols(intermed.IntermediateSymbolTable):
|
||||
class LinuxUtilities(interfaces.configuration.VersionableInterface):
|
||||
"""Class with multiple useful linux functions."""
|
||||
|
||||
_version = (2, 2, 0)
|
||||
_version = (2, 2, 1)
|
||||
_required_framework_version = (2, 0, 0)
|
||||
|
||||
framework.require_interface_version(*_required_framework_version)
|
||||
@@ -339,6 +346,10 @@ class LinuxUtilities(interfaces.configuration.VersionableInterface):
|
||||
yield fd_num, filp, full_path
|
||||
|
||||
@classmethod
|
||||
@Deprecation.deprecated_method(
|
||||
replacement=linux_utilities_modules.Modules.mask_mods_list,
|
||||
replacement_version=(1, 0, 0),
|
||||
)
|
||||
def mask_mods_list(
|
||||
cls,
|
||||
context: interfaces.context.ContextInterface,
|
||||
@@ -346,18 +357,11 @@ class LinuxUtilities(interfaces.configuration.VersionableInterface):
|
||||
mods: Iterator[interfaces.objects.ObjectInterface],
|
||||
) -> List[Tuple[str, int, int]]:
|
||||
"""
|
||||
DEPRECATED: use "volatility3.framework.symbols.linux.utilities.modules.Modules.mask_mods_list" instead.
|
||||
|
||||
A helper function to mask the starting and end address of kernel modules
|
||||
"""
|
||||
mask = context.layers[layer_name].address_mask
|
||||
|
||||
return [
|
||||
(
|
||||
utility.array_to_string(mod.name),
|
||||
mod.get_module_base() & mask,
|
||||
(mod.get_module_base() & mask) + mod.get_core_size(),
|
||||
)
|
||||
for mod in mods
|
||||
]
|
||||
return linux_utilities_modules.Modules.mask_mods_list(context, layer_name, mods)
|
||||
|
||||
@classmethod
|
||||
def generate_kernel_handler_info(
|
||||
@@ -382,41 +386,30 @@ class LinuxUtilities(interfaces.configuration.VersionableInterface):
|
||||
|
||||
return [
|
||||
(constants.linux.KERNEL_NAME, start_addr, end_addr)
|
||||
] + LinuxUtilities.mask_mods_list(context, kernel.layer_name, mods_list)
|
||||
] + linux_utilities_modules.Modules.mask_mods_list(
|
||||
context, kernel.layer_name, mods_list
|
||||
)
|
||||
|
||||
@classmethod
|
||||
@Deprecation.deprecated_method(
|
||||
replacement=linux_utilities_modules.Modules.lookup_module_address,
|
||||
replacement_version=(1, 0, 0),
|
||||
)
|
||||
def lookup_module_address(
|
||||
cls,
|
||||
kernel_module: interfaces.context.ModuleInterface,
|
||||
handlers: List[Tuple[str, int, int]],
|
||||
target_address: int,
|
||||
):
|
||||
) -> Tuple[str, str]:
|
||||
"""
|
||||
DEPRECATED: use "volatility3.framework.symbols.linux.utilities.modules.Modules.lookup_module_address" instead.
|
||||
|
||||
Searches between the start and end address of the kernel module using target_address.
|
||||
Returns the module and symbol name of the address provided.
|
||||
"""
|
||||
|
||||
mod_name = "UNKNOWN"
|
||||
symbol_name = "N/A"
|
||||
|
||||
for name, start, end in handlers:
|
||||
if start <= target_address <= end:
|
||||
mod_name = name
|
||||
if name == constants.linux.KERNEL_NAME:
|
||||
symbols = list(
|
||||
kernel_module.get_symbols_by_absolute_location(target_address)
|
||||
)
|
||||
|
||||
if len(symbols):
|
||||
symbol_name = (
|
||||
symbols[0].split(constants.BANG)[1]
|
||||
if constants.BANG in symbols[0]
|
||||
else symbols[0]
|
||||
)
|
||||
|
||||
break
|
||||
|
||||
return mod_name, symbol_name
|
||||
return linux_utilities_modules.Modules.lookup_module_address(
|
||||
kernel_module.context, kernel_module.name, handlers, target_address
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def walk_internal_list(cls, vmlinux, struct_name, list_member, list_start):
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
from typing import Iterator, List, Tuple
|
||||
|
||||
from volatility3 import framework
|
||||
from volatility3.framework import constants, interfaces
|
||||
from volatility3.framework.objects import utility
|
||||
|
||||
|
||||
class Modules(interfaces.configuration.VersionableInterface):
|
||||
"""Kernel modules related utilities."""
|
||||
|
||||
_version = (1, 0, 0)
|
||||
_required_framework_version = (2, 0, 0)
|
||||
|
||||
framework.require_interface_version(*_required_framework_version)
|
||||
|
||||
@classmethod
|
||||
def mask_mods_list(
|
||||
cls,
|
||||
context: interfaces.context.ContextInterface,
|
||||
layer_name: str,
|
||||
mods: Iterator[interfaces.objects.ObjectInterface],
|
||||
) -> List[Tuple[str, int, int]]:
|
||||
"""
|
||||
A helper function to mask the starting and end address of kernel modules
|
||||
"""
|
||||
mask = context.layers[layer_name].address_mask
|
||||
|
||||
return [
|
||||
(
|
||||
utility.array_to_string(mod.name),
|
||||
mod.get_module_base() & mask,
|
||||
(mod.get_module_base() & mask) + mod.get_core_size(),
|
||||
)
|
||||
for mod in mods
|
||||
]
|
||||
|
||||
@classmethod
|
||||
def lookup_module_address(
|
||||
cls,
|
||||
context: interfaces.context.ContextInterface,
|
||||
kernel_module_name: str,
|
||||
handlers: List[Tuple[str, int, int]],
|
||||
target_address: int,
|
||||
) -> Tuple[str, str]:
|
||||
"""
|
||||
Searches between the start and end address of the kernel module using target_address.
|
||||
Returns the module and symbol name of the address provided.
|
||||
"""
|
||||
kernel_module = context.modules[kernel_module_name]
|
||||
mod_name = "UNKNOWN"
|
||||
symbol_name = "N/A"
|
||||
|
||||
for name, start, end in handlers:
|
||||
if start <= target_address <= end:
|
||||
mod_name = name
|
||||
if name == constants.linux.KERNEL_NAME:
|
||||
symbols = list(
|
||||
kernel_module.get_symbols_by_absolute_location(target_address)
|
||||
)
|
||||
|
||||
if len(symbols):
|
||||
symbol_name = (
|
||||
symbols[0].split(constants.BANG)[1]
|
||||
if constants.BANG in symbols[0]
|
||||
else symbols[0]
|
||||
)
|
||||
|
||||
break
|
||||
|
||||
return mod_name, symbol_name
|
||||
Reference in New Issue
Block a user